本文将详细介绍 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" />
问题:
- 1. MessageStoreIntercetor 的作用是什么?
- 2. operationMode 可以取哪些值? 每个值都有什么作用?
- 3. MessageStoreIntercetor 的主要应用场景是什么?
- 4. MessageStoreIntercetor 工作的原理怎样?
1. MessageStoreInterceptor 的配置在 struts-default.xml 文件中可以找到:
<interceptor
name="store"
class="org.apache.struts2.interceptor.MessageStoreInterceptor" />
由 MessageStoreInterceptor 的 API 可以知道: 若 Action 类实现了 ValidationAware 接口, MessageStoreInterceptor 拦截器可以把和该 Action 相关的 messages, errors 和 field errors(下称 "消息") 保存到 session 中(默认放在 Action 中, 而 Action 在 request 中). 以使可以跨请求访问 messages, errors 和 field errors.
2. 从文档上知道 operationMode 的合法取值有: NONE, STORE, RETRIEVE 和 AUTOMATIC. 其中 NONE 为默认值.
①. STORE: MessageStoreInterceptor 拦截器会把 "消息" 放入 session 域中.
②. RETRIEVE: MessageStoreInterceptor 拦截器会把 "消息" 从 session 中取出来, 放入 Action 中.
③. AUTOMATIC: MessageStoreInterceptor 拦截器会把 "消息" 从 session 中取出来, 放入 Action 中. 而且若响应结果的类型的 redirect, Action 中的 "消息" 会被放入 session 中.
④. NONE: 什么都不做.
3. 使用场景: 添加新的员工后, 重定向到员工显示页面, 并显示 "员工添加成功" 的消息.
现举例说明:
1). 项目目录结构:
2). 代码:
index.jsp:
<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>
显示所有的员工信息: 点击: List Emps 到 EmpAction 的 list 方法.
EmpAction.java
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;
}
}
然后转到 /WEB-INF/content/emp-list.jsp
struts.xml:
<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" class="org.simpleit.eg.EmpAction">
<result name="success">/WEB-INF/content/emp-add.jsp</result>
<result name="list">/WEB-INF/content/emp-list.jsp</result>
<result name="reload" type="redirect">/emp!list.action</result>
</action>
</package>
emp-list.jsp:
<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>
添加新员工: 点击 index.jsp 页面的 Add Emp 连接, 将把页面转到 /WEB-INF/content/emp-add.jsp
emp-add.jsp:
<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>
点击 "Submit" 按钮, 将执行 EmpAction 的 add() 方法, 然后 重定向 到 emp!list.action, 再转发到 emp-list.jsp, 在 emp-list.jsp 页面上可以通过 <s:actionmessage/> 标签显示消息.
其它代码:
Emp.java
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;
}
}
EmpDao.java
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);
}
}
4. 源码分析:
先总结下 "添加员工" 的操作流程: 提交表单, 执行 EmpAction 的 add() 方法, 在 add() 方法中通过 addActionMessage("Save User Success!"); 存放消息, 然后重定向到 list() 方法, 再在页面上通过标签显示消息. 重定向到 list() 方法后依然能够得到在 add() 方法中得到的消息, 就是 MessageStoreInterceptor 拦截器的功劳!
打开 MessageStoreInterceptor 的源代码:
public String intercept(ActionInvocation invocation) throws Exception {
before(invocation);
String result = invocation.invoke();
after(invocation, result);
return result;
}
在执行 invoke 方法之前会调用 before() 方法, 执行 invoke() 方法之后调用 after() 方法.
提交表单后, 执行 add() 方法, 然后 MessageStoreInterceptor 拦截器的 after() 方法会被调用:
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");
}
}
}
在执行 list() 方法之前 before() 方法会被调用:
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);
}
}
}

- 大小: 8.2 KB
分享到:
相关推荐
- XML配置:在`struts.xml`文件中,使用`<interceptor>`元素定义拦截器,`<interceptor-stack>`元素组合多个拦截器,`<package>`元素下的`interceptors`属性指定拦截器栈。 ```xml <!-- 可以添加其他内置或...
拦截器的使用为开发人员提供了灵活的请求处理方式,可以方便地在请求到达控制器之前和之后加入自定义的逻辑。掌握拦截器的使用,对于开发安全、高效、易于维护的Web应用是非常有帮助的。在实际开发中,合理设计拦截...
### Struts2拦截器的使用方法 #### 一、Struts2拦截器概述 Struts2框架中的拦截器(Interceptor)是一种重要的机制,用于在Action执行前后进行一系列处理,比如参数验证、数据预处理等。它能够帮助开发者更加灵活...
请求拦截器和响应拦截器 请求拦截器和响应拦截器是 Axios 库中提供的一种机制,用于在发送请求之前和响应数据...使用请求拦截器和响应拦截器可以统一处理所有请求和响应数据,简化代码,提高代码的可维护性和可读性。
3. **配置拦截器栈**:在`struts-config.xml`中,可以使用`<interceptor-stack>`标签定义拦截器栈,栈中的拦截器会按照定义的顺序执行。 4. **插件使用**:Struts1.2提供了一些预定义的拦截器插件,例如`...
微信小程序请求拦截器 ,响应拦截器,结合微信小程序二次封装request 一起使用
这篇博客文章“struts2 拦截器的使用(继承抽象拦截器)”探讨了如何通过继承Struts2的抽象拦截器来创建自定义拦截器。 首先,让我们理解拦截器的基本概念。在Struts2中,拦截器是基于Java的动态代理机制实现的,...
在IT行业中,Web服务是应用程序之间进行通信的一种标准方法,而WebService之自定义拦截器的实现,无论是...通过理解并熟练掌握CXF框架下的拦截器使用,开发者可以更好地驾驭Web服务,实现更高效、更安全的应用程序。
本篇文章将深入探讨如何使用CXF的`EndpointImpl`类来发布一个WebService,并加入拦截器。 首先,我们要理解`EndpointImpl`是CXF框架用于构建和配置Web服务端点的核心类。通过实例化这个类,我们可以自定义服务的...
通过`addInterceptors(InterceptorRegistry registry)`方法添加自定义的拦截器,然后使用`registry.addInterceptor(interceptor)`方法将拦截器实例注册到注册表中。配置完成后,拦截器会按照添加的顺序依次执行。 5...
6. **调试和测试拦截器**:为了确保拦截器按预期工作,你需要了解如何在CXF中启用日志输出,这通常通过设置日志级别和使用如`java.util.logging`或`log4j`这样的日志框架来实现。 7. **异常处理**:自定义拦截器...
本文将详细介绍如何使用MyBatis拦截器来实现通用权限字段添加,达到灵活、可靠、可维护的数据库操作。 MyBatis拦截器是什么 MyBatis拦截器是一个接口,用于拦截MyBatis的Executor对象,以便在执行SQL语句之前或...
在Java Web开发中,拦截器(Interceptor)是一个重要的概念,特别是在使用MVC框架如Struts2时。拦截器可以理解为一种预处理和后处理机制,它在请求到达控制器之前和离开控制器之后进行操作,例如日志记录、权限检查...
通过使用分页拦截器,我们可以将分页逻辑封装起来,使得在编写Mapper接口和Mapper XML文件时,无需关心具体的分页细节。 MyBatis中的拦截器(Interceptor)是基于Java的动态代理机制实现的,它可以拦截执行SQL的...
在uni-app中,我们可以使用`uni.$http`提供的拦截器功能,它包含两个部分:请求拦截器(request interceptor)和响应拦截器(response interceptor)。请求拦截器主要在请求发送前执行,而响应拦截器则在接收到...
`OpeInfoInterceptor`类就是这样一个拦截器,它使用了`@Intercepts`注解来指定拦截的目标。`@Signature`注解用来精确定义拦截的方法,这里是`Executor`类的`update`方法,接收`MappedStatement`和`Object`两个参数。...
"拦截器解决中文乱码问题"这个主题,主要关注的是如何通过使用拦截器(Interceptor)这一技术手段来预防或解决乱码现象。拦截器是Spring MVC框架中的一个重要组件,它可以对HTTP请求进行预处理和后处理,从而在数据...
【理解拦截器】 拦截器是面向切面编程(AOP)的一个重要概念,它允许在方法或字段被访问之前或之后插入额外的操作。这提供了一种灵活的方式,可以在不修改原有代码的情况下,增强或控制程序的行为。在Web开发框架如...