【问题标题】:execAndWait interceptor not working with validationexecAndWait 拦截器不适用于验证
【发布时间】:2015-04-26 11:22:15
【问题描述】:

当使用execAndWait 拦截器和validate() 方法时,我得到NullPointerException。在index.jsp 中,我有一个textfield 用于firstName。当我提交时,它首先在 Action 类中使用 validate 方法 validate 那个字符串。然后转到execute 方法。在输出中,我得到NullPointerExceptionfirstName 字段在validate 方法中找不到。我在某处了解到,execAndWait 在单独的线程中运行,这就是出现此问题的原因。我想知道如何解决这个问题。下面的文件明智代码:

index.jsp:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<%@ taglib uri="/struts-tags" prefix="s"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
    <s:actionerror />
    <s:actionmessage />
    <s:form action="go" method="post">
        <s:textfield name="fname" label="First-Name" />
        <s:submit value="enter"></s:submit>
    </s:form>
</body>
</html>

struts.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
    "http://struts.apache.org/dtds/struts-2.3.dtd">

<struts>
    <package name="abc" extends="struts-default">

        <interceptors>
            <interceptor-stack name="myStack">
                <interceptor-ref name="defaultStack"></interceptor-ref>
                <interceptor-ref name="execAndWait"></interceptor-ref>
            </interceptor-stack>
        </interceptors>

        <action name="go" class="pack.GoAction">
            <interceptor-ref name="myStack" />
            <result name="success">/success.jsp</result>
            <result name="failure">/failure.jsp</result>
            <result name="input">/index.jsp</result>
            <result name="wait">/wait.jsp</result>
        </action>
    </package>
</struts>   

GoAction.java:

package pack;
import java.sql.*;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
public class GoAction extends ActionSupport implements ModelDriven<User> {
    private static final long serialVersionUID = 1L;
    private User user;
    public User getUser() {
        return user;
    }
    public void setUser(User user) {
        this.user = user;
    }
    @Override
    public User getModel() {
        System.out.println("****inside getModel()****");
        user=new User();
        return user;
    }

    public void validate(){
        System.out.println("****inside validate****");
        if(user.getFname().length()<4){
            this.addFieldError("fname", "first name can not be less than 5");
            System.out.println("console: first name can not be less than 5 "+user.getFname());
        }
        if(user.getFname().length()==0){
            this.addFieldError("fname", "first name found empty");
        }
    }

    public String execute(){
        System.out.println("****inside execute****");
        String returnValue="";
        int i=0;
        Connection con=null;
        ResultSet rs=null;
        PreparedStatement ps=null;
        if(user.getFname().equals("zebra")){
            System.out.println("First-Name : zebra : not allowed.");
            this.addActionMessage("First-Name : zebra : not allowed");
            return "failure";
        }
        try{
            Class.forName("oracle.jdbc.driver.OracleDriver");
            con=DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "hibernate", "hibernate");
            ps=con.prepareStatement("insert into table1 values(?)");
            ps.setString(1, user.getFname());
            i=ps.executeUpdate();
            if(i!=0){
                returnValue="success";
                this.addActionMessage("data successfully inserted");
                System.out.println("ok");
            }
            else{
                returnValue="failure";
                System.out.println("not ok");
            }
        }catch(Exception ex){
            System.out.println("E x c e p t i o n    o c c u r r e d  !!!!");
            ex.printStackTrace();
        }
        return returnValue;
    }
}

wait.jsp:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<%@ taglib uri="/struts-tags" prefix="s"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Wait...</title>
<meta http-equiv="refresh" content="1;">
</head>
<body>
    <img src="images/animation_processing.gif" />
</body>
</html>

success.jsp:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<%@ taglib uri="/struts-tags" prefix="s"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
    Success !!
    <br>
    <s:actionmessage />
</body>
</html>

输出屏幕(逐步)

然而值被插入到数据库中:

控制台输出

****inside getModel()****
****inside validate****
****inside execute****
Apr 26, 2015 4:30:48 PM org.apache.struts2.util.TokenHelper warn
WARNING: Could not find token mapped to token name token
ok
****inside getModel()****
****inside validate****
Apr 26, 2015 4:30:50 PM org.apache.struts2.dispatcher.Dispatcher error
SEVERE: Exception occurred during processing request: null
java.lang.NullPointerException
    at pack.GoAction.validate(GoAction.java:35)
    at com.opensymphony.xwork2.validator.ValidationInterceptor.doBeforeInvocation(ValidationInterceptor.java:251)
    at com.opensymphony.xwork2.validator.ValidationInterceptor.doIntercept(ValidationInterceptor.java:263)
    at org.apache.struts2.interceptor.validation.AnnotationValidationInterceptor.doIntercept(AnnotationValidationInterceptor.java:68)
    at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
    at com.opensymphony.xwork2.interceptor.ConversionErrorInterceptor.intercept(ConversionErrorInterceptor.java:138)
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
    at com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:239)
    at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
    at com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:239)
    at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
    at com.opensymphony.xwork2.interceptor.StaticParametersInterceptor.intercept(StaticParametersInterceptor.java:191)
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
    at org.apache.struts2.interceptor.MultiselectInterceptor.intercept(MultiselectInterceptor.java:73)
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
    at org.apache.struts2.interceptor.CheckboxInterceptor.intercept(CheckboxInterceptor.java:91)
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
    at org.apache.struts2.interceptor.FileUploadInterceptor.intercept(FileUploadInterceptor.java:252)
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
    at com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor.intercept(ModelDrivenInterceptor.java:100)
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
    at com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor.intercept(ScopedModelDrivenInterceptor.java:141)
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
    at com.opensymphony.xwork2.interceptor.ChainingInterceptor.intercept(ChainingInterceptor.java:145)
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
    at com.opensymphony.xwork2.interceptor.PrepareInterceptor.doIntercept(PrepareInterceptor.java:171)
    at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
    at com.opensymphony.xwork2.interceptor.I18nInterceptor.intercept(I18nInterceptor.java:161)
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
    at org.apache.struts2.interceptor.ServletConfigInterceptor.intercept(ServletConfigInterceptor.java:164)
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
    at com.opensymphony.xwork2.interceptor.AliasInterceptor.intercept(AliasInterceptor.java:193)
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
    at com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor.intercept(ExceptionMappingInterceptor.java:189)
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
    at org.apache.struts2.impl.StrutsActionProxy.execute(StrutsActionProxy.java:54)
    at org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:563)
    at org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:77)
    at org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:99)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:936)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1004)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)

经过一番浏览,我知道execAndWait 在单独的线程中运行,无法获取user.getFname() 的值。谁能帮我解决这个问题。

【问题讨论】:

    标签: java validation jsp struts2


    【解决方案1】:

    更改验证方法的逻辑

    public void validate(){
        System.out.println("****inside validate****");
        if(user.getFname() == null || user.getFname().length()==0){
            this.addFieldError("fname", "first name found empty");
        } else
        if(user.getFname().length()<4){
            this.addFieldError("fname", "first name can not be less than 5");
            System.out.println("console: first name can not be less than 5 "+user.getFname());
        }
    }
    

    【讨论】:

    • 它的意思是“发现名字为空”。即使它将值插入到 db.另外,如果我从struts.xml 文件中删除execAndWait 拦截器条目,则验证方法的旧代码没有问题。
    • 是在将值插入到数据库之前还是之后?
    • 首先很抱歉反应太晚了。这是我得到的控制台输出: ****在 getModel()**** **** 在 validate**** **** 在执行**** 2015 年 4 月 26 日 10:33: 00 PM org.apache.struts2.util.TokenHelper 警告警告:找不到映射到令牌名称令牌的令牌 ok ****inside getModel()**** ****inside validate****
    • 你能告诉我...为什么又进入getModel()validate()方法?如果我从 struts.xml 中删除 execAndWait 拦截器条目,则输出显示:****inside getModel()**** ****inside validate**** ****inside execute****
    • 你应该阅读execAndWait拦截器是如何工作的,它会在一段时间后返回一个wait结果来一次又一次地调用你的动作,直到动作被执行。如果它没有参数,它们将不会被设置为动作并且验证总是失败。如果您从堆栈中删除validation 拦截器,或者干脆不要将execAndWait 拦截器用于发布请求。
    【解决方案2】:

    解决方案在于execAndWait 拦截器的工作方式以及struts2 框架调用方法的方式(getModel(),然后是validate(),然后是execute)。另请注意,execAndWait 在不同的线程中运行。您不能使用 ActionContext,因为它是 ThreadLocal。这意味着如果您需要访问例如会话数据,您需要实现 SessionAware 而不是调用 ActionContext.getSession()。

    ----execAndWait 是如何工作的-----

    正如@Roman C 和 API Docs 所说的

    • execAndWait 在超时后返回等待结果,以一次又一次地调用您的操作,直到执行该操作。如果它没有参数,它们将不会被设置为动作并且验证总是失败。

    上面的程序抛出NullPointerException,因为execAndWait拦截器在每1秒间隔后重复调用getModel()(以及validate())(参见wait.jsp &lt;meta http-equiv="refresh" content="1;"/&gt;)。

    所以当它再次调用getModel() 时,它会设置原始new User();object,即没有任何参数fname。因此,在getModel() 之后,它再次进入validate()。而这一次它发现fnamenull。因此,要解决上述问题,只需将 GoAction 类替换为以下代码:

    开始行动

    package pack;
    import java.sql.*;
    import java.util.Map;
    import org.apache.struts2.dispatcher.SessionMap;
    import org.apache.struts2.interceptor.SessionAware;
    import com.opensymphony.xwork2.ActionSupport;
    import com.opensymphony.xwork2.ModelDriven;
    public class GoAction extends ActionSupport implements ModelDriven<User>,SessionAware {
        private SessionMap<String, Object> sm;
        private static final long serialVersionUID = 1L;
        private User user;
        public User getUser() {
            return user;
        }
        public void setUser(User user) {
            this.user = user;
        }
        @Override
        public User getModel() {
            System.out.println("****inside getModel()****");
            User u=(User) sm.get("user");
            if(u==null){
                user=new User();
            }
            else{
                user=u;
            }
            return user;
        }
    
        public void validate(){
            sm.put("user", user);
            User u=(User) sm.get("user");
            System.out.println("^^^"+u.getFname());
            System.out.println("****inside validate****");
            if(u.getFname().length()<4){
                this.addFieldError("fname", "first name can not be less than 5");
                System.out.println("console: first name can not be less than 5 "+user.getFname());
            }
        }
    
        public String execute() throws InterruptedException{
            System.out.println("****inside execute****");
            String returnValue="";
            int i=0;
            Connection con=null;
            ResultSet rs=null;
            PreparedStatement ps=null;
            if(user.getFname().equals("zebra")){
                System.out.println("First-Name : zebra : not allowed.");
                this.addActionMessage("First-Name : zebra : not allowed");
                return "failure";
            }
            try{
                Class.forName("oracle.jdbc.driver.OracleDriver");
                con=DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "hibernate", "hibernate");
                ps=con.prepareStatement("insert into table1 values(?)");
                ps.setString(1, user.getFname());
                i=ps.executeUpdate();
                if(i!=0){
                    returnValue="success";
                    this.addActionMessage("data successfully inserted");
                    System.out.println("ok");
                }
                else{
                    returnValue="failure";
                    System.out.println("not ok");
                }
            }catch(Exception ex){
                System.out.println("E x c e p t i o n    o c c u r r e d  !!!!");
                ex.printStackTrace();
            }
            return returnValue;
        }
        @Override
        public void setSession(Map<String, Object> sm) {
            this.sm=(SessionMap<String, Object>) sm;
        }
    }
    

    在这段代码中,我在getModel() 方法中检查user 对象存储的会话映射。如果未找到:new User()。如果找到:返回它。

    【讨论】:

      猜你喜欢
      • 2013-11-07
      • 1970-01-01
      • 2021-10-20
      • 2015-02-23
      • 1970-01-01
      • 2015-10-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多