比如,当我要添加一个信用卡的时候,我需要信用卡的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. Android中实现圆角矩形及半透明效果。

    注:本文由Colin撰写,版权所有!转载请注明原文地址,谢谢合作! 在做Android开发时,我们为了美观,有时候需要使用圆角矩形,或半透明之类的效果,在网页设计中很容易实现.但在Android开发中 ...

  2. mac jdk环境变量

    /System/Library/Java/JavaVirtualMachines/1.6.0.jdk /Library/Java/JavaVirtualMachines/jdk1.7.0_71.jdk ...

  3. 今天微信群需要人家通过吗?是微信bug吗

    今天遇到微信群拉人的问题,所以来和大家取经,刚开始拉人一下就拉进去了,后来拉的需要人家通过,今天朋友些也帮我拉人也是这样的,所以想问下微信群扩容的问题.晚上有位朋友跟我说一次拉十个人,不能拉多,这样就 ...

  4. asp.net读写配置文件方法

    方法1: System.Collections.Specialized.NameValueCollection nvc = (System.Collections.Specialized.NameVa ...

  5. .NET Core Preview

    .NET Core Preview 这是很容易上手使用.NET Core在您选择的平台上. 你只需要一个命令行,一个文本编辑器和10分钟的时间. 原文链接:https://www.microsoft. ...

  6. gcc 和g++区别

    gcc和g++都是GNU的一个编译器;这两者的区别:1.从源文件上看,对于文件后缀(扩展名)为.c的test.c文件,gcc会把它看成是C程序,而g++则会把它看成是C++程序;而对于文件后缀(扩展名 ...

  7. Android--UI之AutoCompleteTextView

    前言 之前讲过EditText,有兴趣的朋友可以看一下.这篇博客主要说明的是自动完成文本框,它实际上也是一个文本编辑框,可以理解为对EditText功能的扩展,它对输入的内容可以进行提示并且自动完成. ...

  8. linux 下 修改mysql账号密码

    1.root用户登录到mysql数据库代码示例:/usr/local/mysql/bin/mysql -u root -p (输入密码进入mysql)2.进入mysql,输入:代码示例:use mys ...

  9. Effective Java 读书笔记之十 序列化

    一.谨慎地实现Serializable接口 1.一旦一个类被发布,就大大地降低了“改变这个类的实现”的灵活性. 2.仔细设计类的序列化形式而不是接受类的默认虚拟化形式. 3.反序列化机制是一个“隐藏的 ...

  10. class training

    实验3-1 分别使用while循环.do while循环.for循环求 (即求1+2+3+ --+100). 参考: 源码 方法一#include<stdio.h> int main(){ ...