比如,当我要添加一个信用卡的时候,我需要信用卡的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();
    }

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

  1. vue踩坑:vue+ element ui 表单验证有值但验证失败。

    一.如图:有值但是验证失败 二. <el-form :model="form" :rules="rules"> <el-form-item l ...

  2. Struts(二十四):短路验证&重写实现转换验证失败时短路&非字段验证

    短路验证: 若对一个字段使用多个验证器,默认情况下会执行所有的验证.若希望前面的验证器没有通过,后面的验证器就不再执行,可以使用短路验证. 1.如下拦截器,如果输入字符串,提交表单后,默认是会出现三个 ...

  3. 对InvokeAction简略分析了解验证失败为什么Action还会继续执行

    一.前言 有些同学使用AuthorizationFilter来进行用户是否登录验证,如果未登录就跳到登录页. 很简单的一个场景,但是有些同学会发现虽然验证失败了,但是整个Action还会执行一遍. 于 ...

  4. Struts学习之手动验证

    * 首先要从页面中获取对应的标签name属性的值,在动作类action中声明同名的属性,提供get和set方法    * 要继承ActionSupport类或者实现Validateable接口     ...

  5. django 1.10 CSRF验证失败的解决过程

    最近工作闲,没事自学django,感觉这个最烦的就是各版本提供的api函数经常有变化,不是取消了就是参数没有了,网上搜到的帖子也没说明用的是什么版本的django,所以经常出现搬运过来的代码解决不了问 ...

  6. 关于 submit 按钮的 onclick 验证事件,第一次验证失败,第二次 submit 按钮失效的原因解析

    今天在做一个生成订单的简单验证页面 主要功能:实现点击提交按钮后,先在页面上用JavaScript验证信息是否输入完全,不完全不允许提交,待输入完全后,才可以提交 页面:如下页面,可以看到,当文本框有 ...

  7. 微信公众号token验证失败的一些总结

    这几天准备弄一个微信公众号,在进行服务器配置的时候出现总是出现token验证失败的报错. 实际上,这个问题很好解决.既然微信平台没有给我们很明确的报错提示,那么我们就可以通过跟踪获取到的请求参数进行分 ...

  8. SAE微信公众号PHP SDK, token一直验证失败

    用的是SAE,创建的是微信公众号PHP SDK框架,里面example文件夹下有server.php用来验证token的.但是问题来了,无论我怎么输入URL和token,一直告诉我token验证失败. ...

  9. java微信公众号开发token验证失败的问题及解决办法

    本文引自http://m.blog.csdn.net/qq_32331997/article/details/72885424 微信公众平台服务器配置时,需要引入token,但是提交的时候总是提示to ...

随机推荐

  1. CSS3属性选择通配符

    CSS3增加了更多的CSS选择器,可以实现更简单但是更强大的功能,比如:nth-child()等. Attribute selectors:在属性中可以加入通配符,包括^,$,* [att^=val] ...

  2. CentOS-6.5安装zabbix2.4.4

    使用epel源  (检查网络连接是否正常)   //这里使用epel源 [root@localhost /]# wget -O /etc/yum.repos.d/CentOS-Base.repo ht ...

  3. iOS开发——UI进阶篇(十二)事件处理,触摸事件,UITouch,UIEvent,响应者链条,手势识别

    触摸事件 在用户使用app过程中,会产生各种各样的事件 一.iOS中的事件可以分为3大类型 触摸事件加速计事件远程控制事件 响应者对象在iOS中不是任何对象都能处理事件,只有继承了UIResponde ...

  4. POJ2104 —— K-th number

    1.题目大意:区间第k小,什么修改没有... 2.分析:这个是可持久化线段树,也是主席树,解释一下,n个线段树是怎么存下的,就是每一颗线段树和前一个有logn个点不一样 然后我们只需要一个线段树开lo ...

  5. NSLock/NSRecursiveLock/NSConditionLock/@synchronized

    NSLock/NSRecursiveLock/NSConditionLock/@synchronized http://blog.sina.com.cn/s/blog_8c87ba3b0101ok8y ...

  6. [codevs1029]遍历问题

    [codevs1029]遍历问题 试题描述 我们都很熟悉二叉树的前序.中序.后序遍历,在数据结构中常提出这样的问题:已知一棵二叉树的前序和中序遍历,求它的后序遍历,相应的,已知一棵二叉树的后序遍历和中 ...

  7. 跟着百度学PHP[4]OOP面对对象编程-5-内部引用$this

    $this就是对象内部代表这个对象的引用 可以调用被封装的方法或者属性! <?php class Person{ private $name; "; var $sex; functio ...

  8. r-cnn学习(一)

    http://closure11.com/rcnn-fast-rcnn-faster-rcnn%E7%9A%84%E4%B8%80%E4%BA%9B%E4%BA%8B/ 首先看fast r-cnn这篇 ...

  9. mysql互换表中两列数据方法

    1.创建表及记录用于测试 ) unsigned ) ,) unsigned ,) unsigned NOT NULL COMMENT '现价', PRIMARY KEY (`id`) ) ENGINE ...

  10. String和StringBuffer的转换

    从String到StringBuffer: StringBuffer sb = New StringBuffer("abcd");从StringBuffer到String: Str ...