使用NullPointerException
拦截器和execAndWait
方法时,我得到validate()
。在index.jsp
中,textfield
有一个firstName
。当我提交时,它首先validate
使用validate方法在Action
类中的字符串execute
。然后转到NullPointerException
方法。在输出中,我在firstName
方法中找不到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)
OUTPUT-Screens(逐步)
但是在数据库中插入了值:
控制台OUTPUT
execAndWait
经过一段时间的浏览,我发现user.getFname()
在一个单独的线程中运行,并且无法获得$(function() {
// your code here
});
的值。任何人都可以帮我解决这个问题。
答案 0 :(得分: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());
}
}
答案 1 :(得分:0)
解决方案在于internalNode
拦截器的工作方式以及struts2框架调用方法(private class internalNode implements Node<T> {
// ^remove `<T>` from here
,然后是execAndWait
然后getModel()
)的方式。另请注意,validate()
在不同的主题中运行。您不能使用ActionContext,因为它是ThreadLocal。这意味着如果您需要访问例如会话数据,则需要实现SessionAware而不是调用ActionContext.getSession()。
---- execAndWait如何工作------
由@Roman C和API Docs
讲述
execute
在超时后返回等待结果,一次又一次地调用您的操作,直到执行操作为止。如果它没有参数,则不会将其设置为操作,验证始终会失败。
由于execAndWait
拦截器在每1秒间隔后重复调用execAndWait
(以及NullPointerException
)这一事实,上述程序正在抛出execAndWait
(参见wait.jsp getModel()
)。
因此,当它再次调用validate()
时,它会设置原始<meta http-equiv="refresh" content="1;"/>
对象,即没有任何参数getModel()
。因此,在new User();
之后,它再次进入fname
。这次它发现getModel()
为validate()
。因此,要解决上述问题,只需使用以下代码替换fname
类:
<强> GoAction 强>
null
在这段代码中,我正在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;
}
}
对象存储的会话映射。如果未找到:user
。如果找到:返回它。