Struts 2, 值在验证失败回到原来页面的时候会丢失的解决方案

时间:2022-05-22 13:25:37

比如,当我要添加一个信用卡的时候,我需要信用卡的CardType, 这些数据是存在数据库中的,我要先通过action 的一个 create方法,取到信用卡的类型:

Struts 2, 值在验证失败回到原来页面的时候会丢失的解决方案public String create(){
Struts 2, 值在验证失败回到原来页面的时候会丢失的解决方案        creditCardTypeList = this.creditCardTypeService.getList();
Struts 2, 值在验证失败回到原来页面的时候会丢失的解决方案       
Struts 2, 值在验证失败回到原来页面的时候会丢失的解决方案        return SUCCESS;
Struts 2, 值在验证失败回到原来页面的时候会丢失的解决方案}

Struts的配置文件:

Struts 2, 值在验证失败回到原来页面的时候会丢失的解决方案<action name="create" method="create" class="example.CreditCardAction">Struts 2, 值在验证失败回到原来页面的时候会丢失的解决方案     <result name="success">input.jsp</result>
Struts 2, 值在验证失败回到原来页面的时候会丢失的解决方案</action>

input.jsp

...Struts 2, 值在验证失败回到原来页面的时候会丢失的解决方案
<s:select name="creditCard.creditCardTypeId" list="creditCardTypeList" listKey="creditCardTypeId" 
Struts 2, 值在验证失败回到原来页面的时候会丢失的解决方案                listValue="ccType" />
....

当提交input.jsp 的时候,Validate 检查没有通过,这时我需要回到input.jsp,此时应该下拉列表框的CreditType应该被保留,只需要在example.CreditCardAction 实现 Preparable接口,并实现prepare 方法,然后在add的 action中加上

Struts 2, 值在验证失败回到原来页面的时候会丢失的解决方案<interceptor-ref name="prepare"/>
Struts 2, 值在验证失败回到原来页面的时候会丢失的解决方案<interceptor-ref name="defaultStack"/>

就可以了
prepare方法:

Struts 2, 值在验证失败回到原来页面的时候会丢失的解决方案public void prepare(){
Struts 2, 值在验证失败回到原来页面的时候会丢失的解决方案    creditCardTypeList = this.creditCardTypeService.getList(); 
Struts 2, 值在验证失败回到原来页面的时候会丢失的解决方案}

Add Acton:

Struts 2, 值在验证失败回到原来页面的时候会丢失的解决方案<action name="add" method="add" class="example.CreditCardAction">
Struts 2, 值在验证失败回到原来页面的时候会丢失的解决方案    <interceptor-ref name="prepare"/>
Struts 2, 值在验证失败回到原来页面的时候会丢失的解决方案    <interceptor-ref name="defaultStack"/>
Struts 2, 值在验证失败回到原来页面的时候会丢失的解决方案    <result name="input">input.jsp</result>            
Struts 2, 值在验证失败回到原来页面的时候会丢失的解决方案    <result name="success" type="redirect-action">
Struts 2, 值在验证失败回到原来页面的时候会丢失的解决方案            <param name="namespace">/credit</param>
Struts 2, 值在验证失败回到原来页面的时候会丢失的解决方案        <param name="actionName">list</param>
Struts 2, 值在验证失败回到原来页面的时候会丢失的解决方案    </result>
Struts 2, 值在验证失败回到原来页面的时候会丢失的解决方案</action>

这样,在验证前将首先调用 prepare方法,即使失败了回到input.jsp页面creditCardType选择框的值仍然存在。

<interceptor-ref name="defaultStack"/> 中的 defaultStack 是我们在struts.xml 中配置的,其中我们注释掉了 <interceptor-ref name="prepare"/> 这样在example.CreditCardAction中的其他Action就不会首先执行prepare方法,只有加上了 <interceptor-ref name="prepare"/> 的才会去首先执行 prepare方法。

Struts 2, 值在验证失败回到原来页面的时候会丢失的解决方案<package name="project-default" abstract="true" extends="struts-default">
Struts 2, 值在验证失败回到原来页面的时候会丢失的解决方案         <interceptors>
Struts 2, 值在验证失败回到原来页面的时候会丢失的解决方案         <interceptor-stack name="defaultStack">
Struts 2, 值在验证失败回到原来页面的时候会丢失的解决方案                <interceptor-ref name="exception"/>
Struts 2, 值在验证失败回到原来页面的时候会丢失的解决方案                <interceptor-ref name="alias"/>
Struts 2, 值在验证失败回到原来页面的时候会丢失的解决方案                <interceptor-ref name="servletConfig"/>
Struts 2, 值在验证失败回到原来页面的时候会丢失的解决方案                <!--                           
Struts 2, 值在验证失败回到原来页面的时候会丢失的解决方案                <interceptor-ref name="prepare"/>
Struts 2, 值在验证失败回到原来页面的时候会丢失的解决方案                 -->                              
Struts 2, 值在验证失败回到原来页面的时候会丢失的解决方案                <interceptor-ref name="i18n"/>
Struts 2, 值在验证失败回到原来页面的时候会丢失的解决方案                <interceptor-ref name="chain"/>
Struts 2, 值在验证失败回到原来页面的时候会丢失的解决方案                <interceptor-ref name="debugging"/>
Struts 2, 值在验证失败回到原来页面的时候会丢失的解决方案                <interceptor-ref name="profiling"/>
Struts 2, 值在验证失败回到原来页面的时候会丢失的解决方案                <interceptor-ref name="scopedModelDriven"/>
Struts 2, 值在验证失败回到原来页面的时候会丢失的解决方案                <interceptor-ref name="modelDriven"/>
Struts 2, 值在验证失败回到原来页面的时候会丢失的解决方案                <interceptor-ref name="fileUpload"/>
Struts 2, 值在验证失败回到原来页面的时候会丢失的解决方案                <!-- 
Struts 2, 值在验证失败回到原来页面的时候会丢失的解决方案                <interceptor-ref name="checkbox">  
Struts 2, 值在验证失败回到原来页面的时候会丢失的解决方案                       <param name="uncheckedValue">no</param>  
Struts 2, 值在验证失败回到原来页面的时候会丢失的解决方案                </interceptor-ref>
Struts 2, 值在验证失败回到原来页面的时候会丢失的解决方案                -->
Struts 2, 值在验证失败回到原来页面的时候会丢失的解决方案                <interceptor-ref name="staticParams"/>
Struts 2, 值在验证失败回到原来页面的时候会丢失的解决方案                <interceptor-ref name="params">
Struts 2, 值在验证失败回到原来页面的时候会丢失的解决方案                  <param name="excludeParams">dojo..*</param>
Struts 2, 值在验证失败回到原来页面的时候会丢失的解决方案                </interceptor-ref>
Struts 2, 值在验证失败回到原来页面的时候会丢失的解决方案                <interceptor-ref name="conversionError"/>
Struts 2, 值在验证失败回到原来页面的时候会丢失的解决方案                <interceptor-ref name="validation">
Struts 2, 值在验证失败回到原来页面的时候会丢失的解决方案                    <param name="excludeMethods">input,back,cancel,browse</param>
Struts 2, 值在验证失败回到原来页面的时候会丢失的解决方案                </interceptor-ref>
Struts 2, 值在验证失败回到原来页面的时候会丢失的解决方案                <interceptor-ref name="workflow">
Struts 2, 值在验证失败回到原来页面的时候会丢失的解决方案                    <param name="excludeMethods">input,back,cancel,browse</param>
Struts 2, 值在验证失败回到原来页面的时候会丢失的解决方案                </interceptor-ref>
Struts 2, 值在验证失败回到原来页面的时候会丢失的解决方案            </interceptor-stack>
Struts 2, 值在验证失败回到原来页面的时候会丢失的解决方案       </interceptors>
Struts 2, 值在验证失败回到原来页面的时候会丢失的解决方案    </package> 

现在看下PrepareInterceptor拦截器的源代码:

public String doIntercept(ActionInvocation invocation) throws Exception {
        Object action = invocation.getAction();

if (action instanceof Preparable) {  //判断这个action是否是Preparable类的一个实例,也就是判断这个action有没有implement实现这个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) {
                /*
                 * The invoked method threw an exception and reflection wrapped it
                 * in an InvocationTargetException.
                 * If possible re-throw the original exception so that normal
                 * exception handling will take place.
                 */
                Throwable cause = e.getCause();
                if (cause instanceof Exception) {
                    throw (Exception) cause;
                } else if(cause instanceof Error) {
                    throw (Error) cause;
                } else {
                    /*
                     * The cause is not an Exception or Error (must be Throwable) so
                     * just re-throw the wrapped exception.
                     */
                    throw e;
                }
            }

if (alwaysInvokePrepare) {
                ((Preparable) action).prepare();
            }
        }

return invocation.invoke();
    }