比如,当我要添加一个信用卡的时候,我需要信用卡的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. 正确理解JavaScript中的this关键字

    JavaScript有this关键字,this跟JavaScript的执行上下文密切相关,很多前端开发工程师至今对this关键字还是模棱两可,本文将结合代码讲解下JavaScript的this关键字. ...

  2. int long 等基础类型在不同平台的大小

    转自http://www.cnblogs.com/yishuiliunian/archive/2011/03/18/1988244.html 上次腾讯面试,问我int和long分别几个字节,结果被鄙视 ...

  3. C语言中free函数是如何确定要释放多少内存空间的

    本文链接:http://www.cnblogs.com/xxNote/p/4009359.html 今天看书的时候看到free函数释放动态申请的内存时只需要把内存块的首地址传过去就行了,显然仅仅依靠首 ...

  4. Gunicorn 和 Nginx

    Web Application Deployment Using Nginx Nginx is a very high performant web server / (reverse)-proxy. ...

  5. 解压版MySQL安装说明

    一.复制my.ini到MySQL解压的目录 例如:E:\MySQL 二.修改my.ini第39~40行 basedir = "E:\\MySQL" datadir = " ...

  6. 一颗躁动的心---下决心从SLAM开始,不钻研嵌入式底层了

    在写这个随笔时,北京的外面正在下2016的第一场雪.夜深人尽之时总会考虑一下自己的未来在何方. 长这么大了,我发现我这人始终不能坚定不移的朝着一个方向努力,总是朝三暮四,对学习更是朝令夕改,这造成了我 ...

  7. PHP输出控制(Output Control)函数

    ob_start 此函数将打开输出缓冲.当输出缓冲激活后,脚本将不会输出内容(除http标头外),相反需要输出的内容被存储在内部缓冲区中. 内部缓冲区的内容可以用 ob_get_contents() ...

  8. Python自动化之线程进阶篇

    拓展知识 什么是CPU-bound(计算密集型) 和I/O bound(I/O密集型) ? I/O bound 指的是系统的CPU效能相对硬盘/内存的效能要好很多,此时,系统运作,大部分的状况是 CP ...

  9. Webclent基本操作

    /** * @Title: webclientTest.java * @Package webclient * @Description: TODO(用一句话描述该文件做什么) * @author A ...

  10. 在Coding.net创建项目开发

    先在Coding上创建个项目 只要建个项目推送代码余额就会增加,积累码币可以在商城里兑换相应的商品.为了码币,我也应该建个项目搞搞啊-  记录下过程. 先在Coding上创建个项目   现在是这样,我 ...