Reputation: 2327
I'm currently trying to learn Struts2.
I've created a form, an action to process it, an XML to validate it, and actions in the struts.xml.
Every time the form displays, even the first time, Struts2 tries to validate, so errors are displayed before the user had a chance to complete it.
Here is the relevant code:
<!-- /WebContent/views/user/login.jsp -->
<?xml version="1.0" encoding="ISO-8859-1" ?>
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!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>Login Page</title>
<s:head />
</head>
<body>
<h1>Login Page</h1>
<s:form action="executeUser">
<s:textfield key="userBean.userName" />
<s:password key="userBean.password" />
<s:submit align="center" />
</s:form>
</body>
</html>
<!-- /src/struts.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<constant name="struts.devMode" value="true" />
<package name="overviewofstruts" extends="struts-default">
<action name="loginUser" class="hu.flux.user.LoginUserAction" method="execute">
<result name="input">/views/user/login.jsp</result>
</action>
<action name="executeUser" class="hu.flux.user.LoginUserAction" method="execute">
<result name="input">/views/user/login.jsp</result>
<result name="success">/views/user/login_thankyou.jsp</result>
</action>
</package>
</struts>
// /src/hu/flux/user/LoginUserAction.java
package hu.flux.user;
import java.util.Map;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
public class LoginUserAction extends ActionSupport {
private User userBean;
public void setUserBean(User userBean) { this.userBean = userBean; }
public User getUserBean() { return userBean; }
public String login() throws Exception { return this.execute(); }
public String execute() throws Exception { return SUCCESS; }
public String input() throws Exception { return INPUT; }
}
<!-- // /src/hu/flux/user/LoginUserAction-validation.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE validators PUBLIC
"-//OpenSymphony Group//XWork Validator 1.0.2//EN"
"http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
<validators>
<validator type="requiredstring">
<param name="fieldname">userBean.userName</param>
<message>Username is required.</message>
</validator>
<validator type="requiredstring">
<param name="fieldname">userBean.password</param>
<message>Password is required.</message>
</validator>
What do I need to do or change to get struts to show the form the first time without complaining about all the blank fields?
Upvotes: 11
Views: 11446
Reputation: 23614
Yee, I know this issue. Usually I'm using following work-around.
Mark execute
with org.apache.struts2.interceptor.validation.SkipValidation
@SkipValidation
public String execute() throws Exception { return SUCCESS; }
So first pass will ignore validation method. But input will be validated.
Upvotes: 13
Reputation: 1291
The @SkipValidation workaround will do it, but Struts validation already has built-in rules about when it will run (or not) -- it's better to learn the rules so you don't need the extra configuration. It's also worth learning so you aren't confused when validation doesn't run when you need it...
So, short answer: if you change this
<action name="loginUser" class="hu.flux.user.LoginUserAction" method="execute">
to this
<action name="loginUser" class="hu.flux.user.LoginUserAction" method="input">
(notice the method parameter) -- that'll fix the problem (implement the method in your action class as well).
Long answer: Open struts-default.xml, at the root of the struts-core JAR file and browse around. Validation is handled by the "validation" interceptor. Then there's another interceptor called "workflow" that handles automatically showing the "input" result if validation fails, so look at these together.
Find and you'll see this:
<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>
The excludeMethods refers to the action method parameter, and is for exactly what you're trying to do.
You can also set up your own interceptor stack (modeled on the default, or one of the other examples) and define other excluded methods. Wildcards are supported in the names.
Upvotes: 13