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


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

    public String create(){
            creditCardTypeList = this.creditCardTypeService.getList();
           
            
    return SUCCESS;
    }

    Struts的配置文件:

    <action name="create" method="create" class="example.CreditCardAction">     <result name="success">input.jsp</result>
    </action>

    input.jsp

    ...
    <
    s:select name="creditCard.creditCardTypeId" list="creditCardTypeList" listKey="creditCardTypeId" 
                    listValue
    ="ccType" />
    ....

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

    <interceptor-ref name="prepare"/>
    <interceptor-ref name="defaultStack"/>

    就可以了
    prepare方法:

    public void prepare(){
        creditCardTypeList = this.creditCardTypeService.getList(); 
    }


    Add Acton:

    <action name="add" method="add" class="example.CreditCardAction">
        
    <interceptor-ref name="prepare"/>
        
    <interceptor-ref name="defaultStack"/>
        
    <result name="input">input.jsp</result>            
        
    <result name="success" type="redirect-action">
                
    <param name="namespace">/credit</param>
            
    <param name="actionName">list</param>
        
    </result>
    </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方法。

    <package name="project-default" abstract="true" extends="struts-default">
             
    <interceptors>
             
    <interceptor-stack name="defaultStack">
                    
    <interceptor-ref name="exception"/>
                    
    <interceptor-ref name="alias"/>
                    
    <interceptor-ref name="servletConfig"/>
                    
    <!--                           
                    <interceptor-ref name="prepare"/>
                     
    -->                              
                    
    <interceptor-ref name="i18n"/>
                    
    <interceptor-ref name="chain"/>
                    
    <interceptor-ref name="debugging"/>
                    
    <interceptor-ref name="profiling"/>
                    
    <interceptor-ref name="scopedModelDriven"/>
                    
    <interceptor-ref name="modelDriven"/>
                    
    <interceptor-ref name="fileUpload"/>
                    
    <!-- 
                    <interceptor-ref name="checkbox">  
                           <param name="uncheckedValue">no</param>  
                    </interceptor-ref>
                    
    -->
                    
    <interceptor-ref name="staticParams"/>
                    
    <interceptor-ref name="params">
                      
    <param name="excludeParams">dojo..*</param>
                    
    </interceptor-ref>
                    
    <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>
           
    </interceptors>
        
    </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();
        }

  • 相关阅读:
    PTA 乙级 1032 挖掘机技术哪家强 (20分) C++
    Jmeter接口测试之MD5函数使用
    charles基础理论一
    Jmeter接口测试之函数和cookies
    appium+robotframework之权限设置
    appium+robotframework之context问题解决
    jmeter接口测试之断言持续时间
    Appium+robotframework 自动化之软键盘的调起(文本框无法输入值)
    Jmeter接口测试之测试计划和线程组的关系
    Jmeter接口测试之用户定义变量
  • 原文地址:https://www.cnblogs.com/gexiaoshan/p/3297800.html
Copyright © 2020-2023  润新知