Struts2框架 action实现Preparable接口后不再调用set方法进行属性赋值

我的struts2使用的是2.3.16.3版本的,web配置struts2的监听如下

<filter>
    <filter-name>struts2</filter-name>
    <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
    <init-param>
      <param-name>config</param-name>
      <param-value>struts-default.xml,struts-plugin.xml,config/struts-config/struts-config.xml</param-value>
    </init-param>
    <init-param>
      <param-name>actionPackages</param-name>
      <param-value>com.founder.rk</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>struts2</filter-name>
    <url-pattern>*.action</url-pattern>
  </filter-mapping>

Struts2中package配置如下

<package name="global" extends="struts-default,json-default">
		<interceptors>			
			<interceptor-stack name="SMInterceptorStack">
				
				<interceptor-ref name="defaultStack"></interceptor-ref>
				
			</interceptor-stack>
		</interceptors>
		<default-interceptor-ref name="SMInterceptorStack"></default-interceptor-ref>
		<global-results>
			<result name="login" type="redirect">/sm/frame/system/login/login.jsp</result>
			<result name="error">/sm/frame/system/errorReport/error500.jsp</result>
			<result name="error_nologin">/sm/frame/system/errorReport/errorNologin.jsp</result>
			<result name="error_nopage">/sm/frame/system/errorReport/error404.jsp</result>
		</global-results>		
</package>

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就解决了我遇到的上面的问题,代码如下

<package name="global" extends="struts-default,json-default">
		<interceptors>
			<interceptor-stack name="SMInterceptorStack">
				<!-- 该拦截器栈,先调用action的set方法,再调用prepare方法,最后再调用一次set方法 -->
				<interceptor-ref name="paramsPrepareParamsStack" />
			</interceptor-stack>
		</interceptors>
		<default-interceptor-ref name="SMInterceptorStack"></default-interceptor-ref>
		<global-results>
			<result name="login" type="redirect">/sm/frame/system/login/login.jsp</result>
			<result name="error">/sm/frame/system/errorReport/error500.jsp</result>
			<result name="error_nologin">/sm/frame/system/errorReport/errorNologin.jsp</result>
			<result name="error_nopage">/sm/frame/system/errorReport/error404.jsp</result>
		</global-results>		
</package>

paramsPrepareParamsStack包含的拦截器如下:

   <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>

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的逻辑执行

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值