Struts2中的paramsPrepareParamsStack

<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);
		}
	}
	

	@Override
	public void prepare() throws Exception {
		
	}

	@Override
	public Employee getModel() {
		// TODO Auto-generated method stub
		return model;
	}

}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值