MessageStoreInterceptor 拦截器的使用
本文将详细介绍 MessageStoreInterceptor, 包括 MessageStoreInterceptor 的作用, operationMode 参数的取值, 应用举例和源码分析.
MessageStoreInterceptor 拦截器能保证 actionMessage 在 redirect 后不会丢失. struts.xml 文件的部分配置如下:
<interceptors> <interceptor-stack name="storeMessage"> <interceptor-ref name="defaultStack" /> <interceptor-ref name="store"> <param name="operationMode">AUTOMATIC</param> </interceptor-ref> </interceptor-stack> </interceptors> <default-interceptor-ref name="storeMessage" />
<interceptor name="store" />

<a href="emp!list.action" mce_href="emp!list.action">List Emps</a><br><br> <a href="emp.action" mce_href="emp.action">Add Emp</a>
import java.util.List; import com.opensymphony.xwork2.ActionSupport; import com.opensymphony.xwork2.ModelDriven; import com.opensymphony.xwork2.Preparable; public class EmpAction extends ActionSupport implements ModelDriven<Emp>, Preparable{ private static final long serialVersionUID = 1L; private EmpDao empDao = new EmpDao(); private List<Emp> emps = null; private Emp emp; @SuppressWarnings("static-access") public String list() throws Exception { System.out.println("list..."); emps = empDao.getAll(); return "list"; } @SuppressWarnings("static-access") public String add(){ empDao.addEmp(emp); addActionMessage("Save User Success!"); return "reload"; } @Override public Emp getModel() { return emp; } @Override public void prepare() throws Exception { } public void prepareAdd() throws Exception { emp = new Emp(); } public List<Emp> getEmps() { return emps; } public void setEmps(List<Emp> emps) { this.emps = emps; } public Emp getEmp() { return emp; } public void setEmp(Emp emp) { this.emp = emp; } } <package name="simpleit" namespace="/" extends="struts-default"> <interceptors> <interceptor-stack name="storeMessage"> <interceptor-ref name="defaultStack" /> <interceptor-ref name="store"> <param name="operationMode">AUTOMATIC</param> </interceptor-ref> </interceptor-stack> </interceptors> <default-interceptor-ref name="storeMessage" /> <action name="emp" type="redirect">/emp!list.action</result> </action> </package>
<s:actionmessage/> <table> <tr> <th>Name</th> <th>Email</th> </tr> <s:iterator value="emps" var="emp"> <tr> <td>${emp.name }</td> <td>${emp.email }</td> </tr> </s:iterator> </table> <s:form action="emp!add.action"> <s:textfield name="name" label="Name"></s:textfield> <s:textfield name="email" label="Email"></s:textfield> <s:submit value="Submit"></s:submit> </s:form>
public class Emp { private String name; private String email; public Emp() {} public Emp(String name, String email) { this.name = name; this.email = email; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } } public class EmpDao { private final static List<Emp> emps = new ArrayList<Emp>(); static{ emps.add(new Emp("Tom", "Tom@sina.com")); emps.add(new Emp("Jerry", "Jerry@sina.com")); } public static List<Emp> getAll(){ return emps; } public static void addEmp(Emp emp){ emps.add(emp); } } public String intercept(ActionInvocation invocation) throws Exception { before(invocation); String result = invocation.invoke(); after(invocation, result); return result; } protected void after(ActionInvocation invocation, String result) throws Exception { //获取 operationMode 参数 String reqOperationMode = getRequestOperationMode(invocation); //获取响应类型是否为重定向 boolean isRedirect = invocation.getResult() instanceof ServletRedirectResult; if (STORE_MODE.equalsIgnoreCase(reqOperationMode) || STORE_MODE.equalsIgnoreCase(operationMode) || (AUTOMATIC_MODE.equalsIgnoreCase(operationMode) && isRedirect)) { //获取 Action 实例 Object action = invocation.getAction(); if (action instanceof ValidationAware) { // store error / messages into session Map session = (Map) invocation.getInvocationContext().get(ActionContext.SESSION); ValidationAware validationAwareAction = (ValidationAware) action; //把 Action 实例中的 "消息" 放入 session 域中 session.put(actionErrorsSessionKey, validationAwareAction.getActionErrors()); session.put(actionMessagesSessionKey, validationAwareAction.getActionMessages()); session.put(fieldErrorsSessionKey, validationAwareAction.getFieldErrors()); } else { LOG.debug("Action ["+action+"] is not ValidationAware, no message / error that are storeable"); } } } protected void before(ActionInvocation invocation) throws Exception { String reqOperationMode = getRequestOperationMode(invocation); if (RETRIEVE_MODE.equalsIgnoreCase(reqOperationMode) || RETRIEVE_MODE.equalsIgnoreCase(operationMode) || AUTOMATIC_MODE.equalsIgnoreCase(operationMode)) { Object action = invocation.getAction(); if (action instanceof ValidationAware) { // retrieve error / message from session Map session = (Map) invocation.getInvocationContext().get(ActionContext.SESSION); ValidationAware validationAwareAction = (ValidationAware) action; LOG.debug("retrieve error / message from session to populate into action ["+action+"]"); //从 session 中获取 "消息" Collection actionErrors = (Collection) session.get(actionErrorsSessionKey); Collection actionMessages = (Collection) session.get(actionMessagesSessionKey); Map fieldErrors = (Map) session.get(fieldErrorsSessionKey); //把 "消息" 放入 Action 中 if (actionErrors != null && actionErrors.size() > 0) { Collection mergedActionErrors = mergeCollection(validationAwareAction.getActionErrors(), actionErrors); validationAwareAction.setActionErrors(mergedActionErrors); } if (actionMessages != null && actionMessages.size() > 0) { Collection mergedActionMessages = mergeCollection(validationAwareAction.getActionMessages(), actionMessages); validationAwareAction.setActionMessages(mergedActionMessages); } if (fieldErrors != null && fieldErrors.size() > 0) { Map mergedFieldErrors = mergeMap(validationAwareAction.getFieldErrors(), fieldErrors); validationAwareAction.setFieldErrors(mergedFieldErrors); } session.remove(actionErrorsSessionKey); session.remove(actionMessagesSessionKey); session.remove(fieldErrorsSessionKey); } } }