如何使用Struts 2中的超链接传递操作名称?

我有一个名为"Click for new User"的超链接。 一旦我点击链接,我得到NullPointerException而不是打开RegisterPage.jsp页面。

我在这里发布我的代码,我找不到我的错误

index.jsp

      <a href="https://stackoverflow.com/questions/18268758/how-to-pass-a-action-name-using-hyperlink-in-struts-2/">Click for New User 

struts.xml

    loginsuccess.jsp error.jsp index.jsp   RegisterPage.jsp    

Login.java (Action Class):

 package java4s; import com.opensymphony.xwork2.ActionSupport; public class Login extends ActionSupport { private static final long serialVersionUID = 1L; private String username,password; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String register(){ System.out.println("register ()"); return SUCCESS; } public String execute(){ if (getUsername().equals("java4s")&&getPassword().equals("java4s")) { return SUCCESS; } else { this.addActionError(getText("upwrong")); return ERROR; } } @Override public void validate() { if (getUsername().equals("")||getUsername().length()==0) this.addFieldError("username",getText("error.uname")); if(getPassword().equals("")||getPassword().length()==0) this.addFieldError("password", getText("error.pass")); } } 

例外:

  javax.servlet.ServletException: java.lang.NullPointerException org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:515) org.apache.struts2.dispatcher.FilterDispatcher.doFilter(FilterDispatcher.java:4‌​19) java.lang.NullPointerException java4s.Login.validate(Login.java:38) com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor.doIntercept(DefaultWorkflowInterceptor.java:200) com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:86) com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224) com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223) com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455) com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221) com.opensymphony.xwork2.validator.ValidationInterceptor.doIntercept(ValidationInterceptor.java:150) org.apache.struts2.interceptor.validation.AnnotationValidationInterceptor.doIntercept(AnnotationValidationInterceptor.java:48) com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:86) com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224) com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223) com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455) com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221) com.opensymphony.xwork2.interceptor.ConversionErrorInterceptor.intercept(ConversionErrorInterceptor.java:123) com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224) com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223) com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455) com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221) com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:167) com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:86) com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224) com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223) com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455) com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221) com.opensymphony.xwork2.interceptor.StaticParametersInterceptor.intercept(StaticParametersInterceptor.java:105) com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224) com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223) com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455) com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221) org.apache.struts2.interceptor.CheckboxInterceptor.intercept(CheckboxInterceptor.java:83) com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224) com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223) com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455) com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221) org.apache.struts2.interceptor.FileUploadInterceptor.intercept(FileUploadInterceptor.java:207) com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224) com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223) com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455) com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221) com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor.intercept(ModelDrivenInterceptor.java:74) com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224) com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223) com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455) com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221) com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor.intercept(ScopedModelDrivenInterceptor.java:127) com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224) com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223) com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455) com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221) org.apache.struts2.interceptor.ProfilingActivationInterceptor.intercept(ProfilingActivationInterceptor.java:107) com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224) com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223) com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455) com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221) org.apache.struts2.interceptor.debugging.DebuggingInterceptor.intercept(DebuggingInterceptor.java:206) com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224) com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223) com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455) com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221) com.opensymphony.xwork2.interceptor.ChainingInterceptor.intercept(ChainingInterceptor.java:115) com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224) com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223) com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455) com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221) com.opensymphony.xwork2.interceptor.I18nInterceptor.intercept(I18nInterceptor.java:143) com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224) com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223) com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455) com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221) com.opensymphony.xwork2.interceptor.PrepareInterceptor.doIntercept(PrepareInterceptor.java:121) com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:86) com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224) com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223) com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455) com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221) org.apache.struts2.interceptor.ServletConfigInterceptor.intercept(ServletConfigInterceptor.java:170) com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224) com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223) com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455) com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221) com.opensymphony.xwork2.interceptor.AliasInterceptor.intercept(AliasInterceptor.java:123) com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224) com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223) com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455) com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221) com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor.intercept(ExceptionMappingInterceptor.java:176) com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:224) com.opensymphony.xwork2.DefaultActionInvocation$2.doProfiling(DefaultActionInvocation.java:223) com.opensymphony.xwork2.util.profiling.UtilTimerStack.profile(UtilTimerStack.java:455) com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:221) org.apache.struts2.impl.StrutsActionProxy.execute(StrutsActionProxy.java:50) org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:504) org.apache.struts2.dispatcher.FilterDispatcher.doFilter(FilterDispatcher.java:419) 

当您单击超链接时,您不会提供带有参数usernamepassword的请求URL(参数不是由params拦截器设置的),因此此属性的null但在操作之前调用validate()方法执行是因为您的操作扩展了ActionSupport ,它实现了ValidateableValidationAware ,它允许validation拦截器(这是defaultStack的一部分)执行validate()方法,您可以在其中执行手动检查并提供ActionErrorsFieldErrorsActionMessages 。 但如果您不提供属性的值,则没有理由这样做。 您应该提交表单或在URL中设置参数

 Click for New User  

但问题是参数值(用户名和密码)是敏感信息,不应传入URL。 您应该使用Ajax post或使用POST请求提交表单,如本例所示。

使用手动validation时,使用Apache commonsvalidation器非常有用

 if (GenericValidator.isBlankOrNull(value)) addFieldError("FieldLabel", MessageFormat.format(getText("ErrorKey"), getText("FieldLabel"), new Object {})); 

可以为ActionErrors和/或ActionMessages执行类似的代码。 commons-validator包中提供了其他validation器,或者您可以使用不属于此问题的Struts2validation器。