Struts2中的paramsPrepareParamsStack

来源:互联网 发布:剑网三淘宝买金哪家 编辑:程序博客网 时间:2024/06/05 11:10
<span style="white-space:pre"></span><!-- 定义新的拦截器栈, 配置 prepare 拦截器栈的 alwaysInvokePrepare 参数值为 false --><interceptors><interceptor-stack name="sshStack"><interceptor-ref name="paramsPrepareParamsStack"><param name="prepare.alwaysInvokePrepare">false</param></interceptor-ref></interceptor-stack></interceptors><!-- 使用新的拦截器栈 --><default-interceptor-ref name="sshStack"></default-interceptor-ref>

常常我们在Struts2中,都需要配置一个这个东西,是什么东西呢?

先说下正常业务中的情况:

Action接受用户提交的表单数据,并封装到bean里面,例如action中有个user对象,如果想要用params拦截器将数据

直接封装到user对象中,那么就要在jsp中这么写 <input type="text" name="user.name" />

而如果我们想在jsp页面直接写<input type="text" name="name" />并将这个name封装到user对象的name属性上,

就需要依赖我们 的ModelDriven<T>拦截器i:实际上他就是把我们的model对象压到栈顶,这样使用OGNL时就先从栈顶找name一样的set方法。

ModelDrivenInterceptor.java:

 @Override    public String intercept(ActionInvocation invocation) throws Exception {        Object action = invocation.getAction();        if (action instanceof ModelDriven) {            ModelDriven modelDriven = (ModelDriven) action;            ValueStack stack = invocation.getStack();            Object model = modelDriven.getModel();            if (model !=  null) {            stack.push(model);            }            if (refreshModelBeforeResult) {                invocation.addPreResultListener(new RefreshModelBeforeResult(modelDriven, model));            }        }        return invocation.invoke();    }

那么Preparable接口又是干什么的,我们知道form提交的action会请求到一个java类的方法上,有时候我们需要在方法调用前准备点什么,

那么实现Preparable接口就可以了,因为PrepareInterceptor为我们代理了一下action的调用:

PrepareInterceptor.java

  @Override    public String doIntercept(ActionInvocation invocation) throws Exception {        Object action = invocation.getAction();        if (action instanceof Preparable) {            try {                String[] prefixes;                if (firstCallPrepareDo) {                    prefixes = new String[] {ALT_PREPARE_PREFIX, PREPARE_PREFIX};                } else {                    prefixes = new String[] {PREPARE_PREFIX, ALT_PREPARE_PREFIX};                }                PrefixMethodInvocationUtil.invokePrefixMethod(invocation, prefixes);            }            catch (InvocationTargetException e) {                Throwable cause = e.getCause();                if (cause instanceof Exception) {                    throw (Exception) cause;                } else if(cause instanceof Error) {                    throw (Error) cause;                } else {                    throw e;                }            }            if (alwaysInvokePrepare) {                ((Preparable) action).prepare();            }        }        return invocation.invoke();    }}

我们看到:默认是在action方法调用前执行prepare方法,但是,实际中我们的一个action可能要处理增删改查等多个逻辑。

如果我们都放到一个prepare方法中,会显得混乱,并且方法的复用性也很低。

那我们就可以看到一个alwaysInvokePrepare参数可以控制不使用prepare方法了,而是

PrefixMethodInvocationUtil.invokePrefixMethod(invocation, prefixes),就是比如我的action方法是input(),那么它会自动找inputprepare()方法

如果找到,就会在input()之前执行,是不是很方便呢!

另外:在prepare方法中,我们有时候需要一些表单传递过来的参数,例如id等,而我们知道params拦截器是处理请求参数,默认的DefalultInterceptorStack里面

虽然也有prepare拦截器,但是prepare却无法接收到用户请求的数据,因为只有params拦截器才能传递,这就要

paramsPrepareParamsStack:

<span style="white-space:pre"></span><interceptor-stack name="paramsPrepareParamsStack">                <interceptor-ref name="exception"/>                <interceptor-ref name="alias"/>                <interceptor-ref name="i18n"/>                <interceptor-ref name="checkbox"/>                <interceptor-ref name="datetime"/>                <interceptor-ref name="multiselect"/>                <interceptor-ref name="params"/>                <interceptor-ref name="servletConfig"/>                <interceptor-ref name="prepare"/>                <interceptor-ref name="chain"/>                <interceptor-ref name="modelDriven"/>                <interceptor-ref name="fileUpload"/>                <interceptor-ref name="staticParams"/>                <interceptor-ref name="actionMappingParams"/>                <interceptor-ref name="params"/>                <interceptor-ref name="conversionError"/>                <interceptor-ref name="validation">                    <param name="excludeMethods">input,back,cancel,browse</param>                </interceptor-ref>                <interceptor-ref name="workflow">                    <param name="excludeMethods">input,back,cancel,browse</param>                </interceptor-ref>            </interceptor-stack>
而defaultStack:

 <span style="white-space:pre"></span><interceptor-stack name="defaultStack">                <interceptor-ref name="exception"/>                <interceptor-ref name="alias"/>                <interceptor-ref name="servletConfig"/>                <interceptor-ref name="i18n"/>                <interceptor-ref name="prepare"/>                <interceptor-ref name="chain"/>                <interceptor-ref name="scopedModelDriven"/>                <interceptor-ref name="modelDriven"/>                <interceptor-ref name="fileUpload"/>                <interceptor-ref name="checkbox"/>                <interceptor-ref name="datetime"/>                <interceptor-ref name="multiselect"/>                <interceptor-ref name="staticParams"/>                <interceptor-ref name="actionMappingParams"/>                <interceptor-ref name="params"/>                <interceptor-ref name="conversionError"/>                <interceptor-ref name="validation">                    <param name="excludeMethods">input,back,cancel,browse</param>                </interceptor-ref>                <interceptor-ref name="workflow">                    <param name="excludeMethods">input,back,cancel,browse</param>                </interceptor-ref>                <interceptor-ref name="debugging"/>                <interceptor-ref name="deprecation"/>            </interceptor-stack>
显然在prepare前面少了params拦截器。

下面给出action中使用这2个技术的demo:

Xxxaction.java

package ray.actions;import java.io.ByteArrayInputStream;import java.io.InputStream;import java.io.UnsupportedEncodingException;import java.util.Date;import com.opensymphony.xwork2.ModelDriven;import com.opensymphony.xwork2.Preparable;import ray.po.Employee;import ray.services.DepartmentService;import ray.services.EmployeeService;public class EmployeeAction extends BaseAction<Employee> implements ModelDriven<Employee>, Preparable{/** *  */private static final long serialVersionUID = 1L;private DepartmentService departmentService;public void setDepartmentService(DepartmentService departmentService) {this.departmentService = departmentService;}public String list() {requestMap.put("employees", employeeService.getAll());return "list";}private Integer id;public void setId(Integer id) {this.id = id;}private Employee model;public String input(){requestMap.put("departments", departmentService.getAll());return INPUT;}public void prepareInput(){if(id != null){model = employeeService.get(id);}}public String save(){if(id == null){(model).setCreateDate(new Date());}employeeService.saveOrUpdate(model);return SUCCESS;}public void prepareSave(){if(id == null){model = new Employee();}else{model = employeeService.get(id);}}@Overridepublic void prepare() throws Exception {}@Overridepublic Employee getModel() {// TODO Auto-generated method stubreturn model;}}



0 0
原创粉丝点击