Struts2 validate()在初始进入jsp时调用了两次

时间:2016-01-21 21:04:05

标签: validation struts2

我开始写一个登录页面,我的初步测试显示,当我第一次输入login.jsp时,验证方法被调用两次,但是当我提交登录表单时却没有。我想了解为什么lca被调用两次以及如何阻止它。

首先,这是我的struts.xml:

validate()

这是我的<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" "http://struts.apache.org/dtds/struts-2.1.dtd"> <struts> <constant name="struts.devMode" value="true"/> <constant name="struts.i18n.reload" value="true" /> <constant name="struts.ui.theme" value="simple"/> <constant name="struts.custom.i18n.resources" value="resources.i18n.portalLogin, resources.i18n.errors"/> <constant name="struts.action.extension" value="action"/> <constant name="struts.ognl.allowStaticMethodAccess" value="true" /> <!-- Configuration for the default package. --> <package name="default" extends="json-default"> <interceptors> <interceptor name="security" class="login.interceptor.SecurityInterceptor"/> <interceptor-stack name="appDefaultStack"> <interceptor-ref name="jsonValidationWorkflowStack"/> <interceptor-ref name="defaultStack"> <param name="exception.logEnabled">true</param> <param name="exception.logLevel">ERROR</param> <!-- Exclude the jQuery no-cache parameter and the jQuery Displaytag parameters from processing by the ParametersInterceptor --> <param name="params.excludeParams">_,d-\d+-[sop]</param> </interceptor-ref> <interceptor-ref name="security"></interceptor-ref> </interceptor-stack> </interceptors> <default-interceptor-ref name="appDefaultStack" /> <global-results> <result name="error">/jsp/error/systemError.jsp</result> <result name="security">/jsp/error/accessDenied.jsp</result> </global-results> <global-exception-mappings> <exception-mapping result="error" exception="java.lang.Exception"/> </global-exception-mappings> <action name="Login" class="login.action.Login"> <result name="input">/jsp/login.jsp</result> <result name="success" type="redirect"> <param name="ActionName">LoginRedirect</param> </result> </action> </package> </struts>

index.jsp

这是我的<!DOCTYPE HTML> <% String path = request.getContextPath(); String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path; // prevent caching these pages at clients. response.setHeader("Cache-Control", "no-cache"); // HTTP 1.1 response.setHeader("Pragma", "no-cache"); // HTTP 1.0 response.setDateHeader("Expires", 0); // prevents caching at proxy %> <html> <head> <base href="<%=basePath%>"> <title>Login</title> </head> <script> location.href = '<%= basePath %>/Login.action'; </script> <body> Please go to the <a href="<%= basePath %>/Login.action">Login</a> page.<br> </body> </html>

login.jsp

这是我的Login.java动作:

<%@ taglib prefix='s' uri='/struts-tags' %>
<%@ taglib prefix='tiles' uri='/tiles' %>

<tiles:insertDefinition name='fullLayout'>
  <tiles:putAttribute name='title' cascade='true'>
    <s:text name='layout.title'/>
  </tiles:putAttribute>
  <tiles:putAttribute name='content' cascade='true'>
    <s:text name='instructions.text'/>
    <s:form name='Login' action='Login' method='POST' validate='true' focusElement="userId"
            autocomplete='off'>
      <div class='userIdInput'>
        <label class='formLabel required' for='userId'>
          <s:text name='text.userID' />
        </label>
        <s:textfield cssClass='inputText' name='userId' id='userId' value="%{userId}" />
      </div>
      <div class='passwordInput'>
        <label class='formLabel required' for='password'>
          <s:text name='text.password' />
        </label>
        <s:textfield cssClass='inputText' name='password' id='password' type='password' />
      </div>
      <input id='Login' type='submit' title='<s:text name="login.submit" />'
             value='<s:text name="login.submit" />'>
    </s:form>
  </tiles:putAttribute>
</tiles:insertDefinition>

这是我的package login.action; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectOutputStream; import java.lang.reflect.Array; import java.lang.reflect.Method; import java.util.Arrays; import java.util.Enumeration; import java.util.Iterator; import java.util.Map; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import org.apache.struts2.interceptor.ServletRequestAware; import com.opensymphony.xwork2.ActionSupport; import logging.Logger; import common.util.StringUtils; /** * The main Action class for this application */ public class Login extends ActionSupport implements ServletRequestAware { private static final long serialVersionUID = 1L; private HttpServletRequest httpRequest; private String userId; private String password; /* (non-Javadoc) * @see com.opensymphony.xwork2.Action#execute() */ @Override public String execute() { Logger.debug(this, "execute(" + hashCode() + "): Begin"); boolean debug = Logger.canLogDebug(this); HttpSession session = httpRequest.getSession(); if ((userId == null || userId.isEmpty()) && (password == null || password.isEmpty())) { if (debug) { Logger.debug(this, " No userID and no Password."); Logger.debug(this, "execute End"); } return INPUT; } if (debug) { Logger.debug(this, "userId = " + userId); Logger.debug(this, " password is " + ((password == null || password.isEmpty()) ? "not " : "") + "set"); } Logger.debug(this, "execute End"); return SUCCESS; } /** * @return String */ public String getUserId() { return userId; } /** * @param String userId */ public void setUserId(String userId) { Logger.debug(this, "in setUserId(" + userId + ")"); this.userId = userId; } /** * @param String password */ public void setPassword(String password) { Logger.debug(this, "in setPassword(" + password + ")"); this.password = password; } /* (non-Javadoc) * @see com.opensymphony.xwork2.ActionSupport#validate() */ @Override public void validate() { Logger.debug(this, "validate(" + hashCode() + "): Begin"); if ((userId == null || userId.isEmpty()) && (password == null || password.isEmpty())) { if (Logger.canLogDebug(this)) { Logger.debug(this, " No userID and no Password."); Logger.debug(this, "validateLogin: End"); } return; } if ((userId == null || userId.isEmpty())) { Logger.debug(this, " No userID."); addActionError(getText("missing.required", new String[] {getText("text.userID")})); } if ((password == null || password.isEmpty())) { Logger.debug(this, " No Password."); addActionError(getText("missing.required", new String[] {getText("text.password")})); } Logger.debug(this, "validate: End"); } /* (non-Javadoc) * @see ServletRequestAware#setServletRequest(HttpServletRequest) */ @Override public void setServletRequest(HttpServletRequest httpRequest) { this.httpRequest = httpRequest; } }

SecurityInterceptor.java

最后,这是我记录的信息:

初始JSP条目

package login.interceptor;

import javax.servlet.http.HttpServletRequest;

import org.apache.struts2.interceptor.ServletRequestAware;

import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
import logging.Logger;

public class SecurityInterceptor extends AbstractInterceptor
                                 implements ServletRequestAware {
    private static final long serialVersionUID = 1L;
    HttpServletRequest servletRequest = null;

    @Override
    public String intercept(ActionInvocation invocation) throws Exception {
        boolean debug = Logger.canLogDebug(this);
        if (debug) {
            Logger.debug(this, "intercept: Begin");
            Logger.debug(this, "invocation = " + 
                               invocation.getAction().getClass().getName());
        }

        //TODO: Siteminder integration

        Logger.debug(this, "intercept: End");
        return invocation.invoke();
    }

    /* (non-Javadoc)
     * @see ServletRequestAware#setServletRequest(HttpServletRequest)
     */
    @Override
    public void setServletRequest(HttpServletRequest servletRequest) {
        this.servletRequest = servletRequest;
    }
}

表格提交后

2016/01/21 15:17:50.470| DEBUG|                      login.action.Login| validate(12565027): Begin
2016/01/21 15:17:50.473| DEBUG|                      login.action.Login|     No userID and no Password.
2016/01/21 15:17:50.475| DEBUG|                      login.action.Login| validateLogin: End
2016/01/21 15:17:50.480| DEBUG|                      login.action.Login| validate(12565027): Begin
2016/01/21 15:17:50.480| DEBUG|                      login.action.Login|     No userID and no Password.
2016/01/21 15:17:50.480| DEBUG|                      login.action.Login| validateLogin: End
2016/01/21 15:17:50.480| DEBUG|   login.interceptor.SecurityInterceptor| intercept: Begin
2016/01/21 15:17:50.480| DEBUG|   login.interceptor.SecurityInterceptor| invocation = login.action.Login
2016/01/21 15:17:50.480| DEBUG|   login.interceptor.SecurityInterceptor| intercept: End
2016/01/21 15:17:50.480| DEBUG|                      login.action.Login| execute(12565027): Begin
2016/01/21 15:17:50.480| DEBUG|                      login.action.Login|     No userID and no Password.
2016/01/21 15:17:50.480| DEBUG|                      login.action.Login| execute End

1 个答案:

答案 0 :(得分:2)

因为您在默认使用的拦截器堆栈中引用了两次。两个堆栈都包含validation拦截器,它调用validate

<interceptor-ref name="jsonValidationWorkflowStack"/>
<interceptor-ref name="defaultStack">

只需删除第二个,第一个堆栈包括basicStack,这是您的应用程序应该使用的最小值。您可以在自定义堆栈或操作中添加其他拦截器。