我的struts2使用的是2.3.16.3版本的,web配置struts2的监听如下
struts2
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
config
struts-default.xml,struts-plugin.xml,config/struts-config/struts-config.xml
actionPackages
com.founder.rk
struts2
*.action
Struts2中package配置如下
/sm/frame/system/login/login.jsp
/sm/frame/system/errorReport/error500.jsp
/sm/frame/system/errorReport/errorNologin.jsp
/sm/frame/system/errorReport/error404.jsp
action类继承和实现了如下接口
public class SjbflAction extends ActionSupport implements Preparable,ModelDriven{
ModelDriven接口是使用模型封装请求参数,Preparable接口是为了在模型封装之前构造model对象,代码如下
@Override
public SjbflVO getModel() {
// TODO Auto-generated method stub
return sjbfl;
}
@Override
public void prepare() throws Exception {
// TODO Auto-generated method stub
System.out.println(request.getParameter("id"));
//判断是否传递参数id,如果有id,则根据id去数据库获取实例,没有则创建一个新的
if (isNullOrEmptyString(id)) {
sjbfl = new SjbflVO();
} else {
sjbfl = sjbflService.getById(id);
}
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
就这样,请求action的方法时我传递了id参数,但是发现action中prepare的方法中获取属性id为空,我断点调试了一下发现在执行action的prepare方法前没有调用setId方法,没有给id设置值,我检查了好多地方都没有发现问题所在,最后把实现Preparable接口给去掉后,set方法就自动调用了。
后来我又查了一下Struts2的拦截器相关资料,结果代码测试,发现其实是拦截器的问题,Struts2默认的拦截器栈
“defaultStack”如果action实现了preparable接口,action的执行顺序是先执行prepare方法,再执行set方法,所以再prepare方法中属性id是没有被赋值的为null,此时把默认的拦截器栈换成paramsPrepareParamsStack就解决了我遇到的上面的问题,代码如下
/sm/frame/system/login/login.jsp
/sm/frame/system/errorReport/error500.jsp
/sm/frame/system/errorReport/errorNologin.jsp
/sm/frame/system/errorReport/error404.jsp
paramsPrepareParamsStack包含的拦截器如下:
input,back,cancel,browse
input,back,cancel,browse
paramsPrepareParamsStack拦截器栈中的使用顺序:
params->prepare->model-driven->params
Struts2的设计上要求modelDriven在params之前调用,而业务中prepare要负责准备model,准备model又需要参数,这就需要在prepare之前调用params拦截器设置相关参数,这个也就是创建paramsPrepareParamsStack的原因。
流程:
1.params拦截器首先给action的相关参数赋值
2.prepare拦截器执行prepare方法,prepare方法会根据参数,如id,去调用业务逻辑,设置model对象
3.model-diven拦截器将model对象压入值栈,这里的model对象就是在prepare中创建
4.params拦截器将参数值赋给model对象
5.action的逻辑执行