I m new to Struts2. I want to use Validation Framework for a simple 'register' form. Here is my JSP page form elements;
<s:form action="register">
<s:textfield name="name" label="Name" />
<s:textfield name="age" label="Age" />
<s:textfield name="email" label="email"/>
<s:submit value="Register" />
</s:form>
validation error ? = <s:actionerror /><br/>
---Action Message--- <s:actionmessage/>
Here is struts2.xml file;
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<package name="default" extends="struts-default">
<action name="register"
class="com.action.RegisterAction">
<result name="success">home.jsp</result>
<result name="input">index.jsp</result>
</action>
</package>
</struts>
RegisterAction class has
String name;
int age;
String email; variables with getters and setters. And its execute() just returns SUCCESS
For these fields validations the following validation xml file is used, for now only one field name is checked. Name of the validation file is RegisterAction-validation.xml
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<!-- Author: Aash -->
<validators>
<field name="name">
<field-validator type="requiredstring">
<param name="trim">true</param>
<message>name is required.. :) </message>
</field-validator>
</field>
</validators>
Here is the project structure
Please any one let me know how can I come up with this. Thanks in advance.
New Add : According to the struts.xml, if there is an error,(the validation says something is wrong), the page should be redirected to index.jsp ,but when nothing is given for the field 'name', still it goes to home.jsp .
A Solution Found
I added to validation.xml
!DOCTYPE validators PUBLIC
"-//OpenSymphony Group//XWork Validator 1.0.2//EN"
"http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
But it is displayed on the top of Form, I don't know why not printed as actionError. How I get it Printed where I want it to view(example : bottom of the form)?
Since it is a field Error, as you have put elements in the JSP page, the message comes close to the field 'name' . If you wanna get printed it,where u want it to be, <s:fielderror fieldName="name" />
I think the problem is the xml file name. It should be RegisterAction-validation.xml
As this says, the DOCTYPE should be there in the validation.xml.
<!DOCTYPE validators PUBLIC "-//OpenSymphony Group//XWork Validator 1.0.2//EN" "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
-->
Put parameter validate value make 'true; in in <s:form action="register" validate="true">
Related
I use struts in my Java EE project:
In my loading.jsp if I use the below src, I will get 404 error:
<IFRAME src="${pageContext.request.contextPath}/WEB-INF/page/menu/alermDevice.jsp" name="dev" id="dev" frameBorder="0" width="500" scrolling="auto" height="400">
</IFRAME>
But if I use below src:
<IFRAME src="elecMenuAction_alermDevice.do" name="dev" id="dev" frameBorder="0" width="500" scrolling="auto" height="400">
</IFRAME>
I will get the correct information.
This is my 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>
<constant name="struts.devMode" value="true"></constant>
<constant name="struts.ui.theme" value="simple"></constant>
<constant name="struts.action.extension" value="do"></constant>
<package name="system" namespace="/system" extends="struts-default">
<action name="elecTextAction_*" class="elecTextAction" method="{1}">
<result name="save">/system/textAdd.jsp</result>
</action>
<action name="elecMenuAction_*" class="elecMenuAction" method="{1}">
<result name="menuHome">/WEB-INF/page/menu/home.jsp</result>
<result name="title">/WEB-INF/page/menu/title.jsp</result>
<result name="left">/WEB-INF/page/menu/left.jsp</result>
<result name="change">/WEB-INF/page/menu/change.jsp</result>
<result name="loading">/WEB-INF/page/menu/loading.jsp</result>
<result name="logout" type="redirect">index.jsp</result>
<result name="alermStation">/WEB-INF/page/menu/alermStation.jsp</result>
<result name="alermDevice">/WEB-INF/page/menu/alermDevice.jsp</result>
</action>
</package>
</struts>
Why I use the path can not access the JSP? only use the action I can get it yet?
The web server cannot get resources from and below WEB-INF folder. When action is invoked it returns a response as an execution of the result. It's used a result type dispatcher which is used by default to forward request to the specified URL (the requested JSP page).
Dispatcher Result
Includes or forwards to a view (usually a jsp). Behind the scenes
Struts will use a RequestDispatcher, where the target servlet/JSP
receives the same request/response objects as the original
servlet/JSP. Therefore, you can pass data between them using
request.setAttribute() - the Struts action is available.
There are three possible ways the result can be executed:
If we are in the scope of a JSP (a PageContext is available), PageContext's PageContext#include(String) method is
called.
If there is no PageContext and we're not in any sort of include (there is no "javax.servlet.include.servlet_path" in the request
attributes), then a call to
RequestDispatcher#forward(javax.servlet.ServletRequest,
javax.servlet.ServletResponse) is made.
Otherwise, RequestDispatcher#include(javax.servlet.ServletRequest,
javax.servlet.ServletResponse) is called.
When servlet dispatcher is invoked it has not such restriction and can return resource with the same response that was originally requested.
I am getting following exception, please help to solve this issue.
Jul 16, 2013 11:18:40 AM org.apache.struts2.components.Form evaluateExtraParamsServletRequest
WARNING: No configuration found for the specified action: `'HelloWorld1'` in namespace: `''`. Form action defaulting to 'action' attribute's literal value.
index.jsp:
<s:form action="HelloWorld1" namespace="/" method="post" >
<s:textfield name="userName" label="User Name" />
<s:submit />
</s:form>
struts.xml:
<package name="default" namespace="/" extends="struts-default" >
<action name="HelloWorld1" class="java.vaannila.HelloWorld">
<result name="SUCCESS">/success.jsp</result>
</action>
</package>
HelloWorld .java:
public class HelloWorld extends ActionSupport{
//execute method
}
The error suggests that Struts 2 couldn't load your XML configuration. Make sure your struts.xml is inside WEB-INF/classes directory. (The rest of the configuration looks fine.)
If you are sure that the configurations are being loaded properly, try removing the namespace attribute or setting namespace="" instead of namespace="/".
This warning appears only when you use devMode. Turn it off and it should disappear, add the following to the struts.xml
<constant name="struts.devMode" value="false"/>
This question already has an answer here:
Multiple submit buttons in Struts 2 form tag
(1 answer)
Closed 2 years ago.
I have a form in a jsp. There are two submit buttons: "Search" and "Add New" button.
<s:form name="searchForm" action="employeeAction" method="post">
<s:textfield name="id" label="Employee ID"/>
<s:textfield name="name" label="Employee Name"/>
<s:submit value="Search"/>
<s:submit value="Add New"/>
</s:form>
In 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>
<constant name="struts.enable.DynamicMethodInvocation" value="false" />
<constant name="struts.devMode" value="true" />
<package name="default" namespace="/" extends="struts-default">
<default-action-ref name="index" />
<global-results>
<result name="error">/error.jsp</result>
</global-results>
<global-exception-mappings>
<exception-mapping exception="java.lang.Exception" result="error"/>
</global-exception-mappings>
</package>
<package name="example" namespace="/example" extends="default">
<action name="employeeAction" class="example.EmployeeAction">
<result name="search">/example/search.jsp</result>
<result name="add" type="redirect">/example/add.jsp</result>
</action>
</package>
</struts>
In Struts Action class, we know that there is only one method that processing http request, that is execute() method.
In my expected case, when I clicked Search button, it will perform searching data and render data to /example/search.jsp, when I clicked Add New button, it will perform redirecting page to /example/add.jsp. However, both buttons when clicked will go into execute() method. So I need to know how to detect which button clicked in the execute() method.
The scenario looks like this
public class EmployeeAction extends ActionSupport {
public String execute() throws Exception {
//PSEUDOCODE
//IF (submitButton is searchButton)
// return doSearch();
//ELSE IF (submitButton is addNewButton)
// return doAddNew();
return SUCCESS;
}
public String doSearch() throws Exception {
//perform search logic here
return "search";
}
public String doAddNew() throws Exception {
return "add";
}
}
You can define two actions in struts.xml file and use action attribute of <s:submit> tag in order to submit to different actions http://struts.apache.org/docs/submit.html.
In JSP:
<s:submit value="Search" action="searchEmployeeAction"/>
<s:submit value="Add New" action="addEmployeeAction"/>
In struts.xml:
<action name="addEmployeeAction" method="add" class="example.EmployeeAction">
<result>/example/add.jsp</result>
</action>
<action name="searchEmployeeAction" method="search" class="example.EmployeeAction">
<result>/example/search.jsp</result>
</action>
And in your action create two public String methods add and search.
Read about Multiple Submit Buttons http://struts.apache.org/docs/multiple-submit-buttons.html.
Update
Starting from Struts2 version 2.3.15.3 you need to set struts.mapper.action.prefix.enabled constant to true in order to enable support for action: prefix.
Put that in your struts.xml file:
<constant name="struts.mapper.action.prefix.enabled" value="true" />
In your model layer, define a String property named 'button'. Now, for both your submit buttons, specify name or property attribute as 'button'. So, in your execute() method, in property 'button', you will get the corresponding value.
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?
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.
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.
My issue is that when I don't see a client side validation error message when I don't enter any values for that field even when it is configured as required. The page is reloaded and goes to the result page and client validation fails. I am not sure what I am doing wrong.
I have a simple form where I have a pull down menu called selection criterion. A value must be selected. If a value is not selected, then the page should reload with configured error message. My input form action_item_search.jsp is given below:
<%# taglib prefix="s" uri="/struts-tags" %>
<%# page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<title>Action Item Search</title>
</head>
<body>
<s:actionerror/>
<s:fielderror />
<s:form action="action_item_search" validate="true">
<s:select label="Search Criterion" name="searchCriterion"
list="#{'': 'Select One', 'creatorName':'creator name',
assignedTo':'assigned to'}" required="true" />
<s:submit name="search" value="Search"></s:submit>
</s:form>
</body>
I have add validators.xml in my WEB-INF/classes directory of exploded war file as given below:
<!DOCTYPE validators PUBLIC
"-//OpenSymphony Group//XWork Validator Config 1.0//EN"
"http://www.opensymphony.com/xwork/xwork-validator-config-1.0.dtd">
<validators>
<validator name="required"
class="com.opensymphony.xwork2.validator.validators.RequiredFieldValidator"/>
<validator name="requiredstring"
class="com.opensymphony.xwork2.validator.validators.RequiredStringValidator"/>
<validator name="int"
class="com.opensymphony.xwork2.validator.validators.IntRangeFieldValidator"/>
<validator name="long"
class="com.opensymphony.xwork2.validator.validators.LongRangeFieldValidator"/>
<validator name="short"
class="com.opensymphony.xwork2.validator.validators.ShortRangeFieldValidator"/>
<validator name="double"
class="com.opensymphony.xwork2.validator.validators.DoubleRangeFieldValidator"/>
<validator name="date"
class="com.opensymphony.xwork2.validator.validators.DateRangeFieldValidator"/>
<validator name="expression"
class="com.opensymphony.xwork2.validator.validators.ExpressionValidator"/>
<validator name="fieldexpression"
class="com.opensymphony.xwork2.validator.validators.FieldExpressionValidator"/>
<validator name="email"
class="com.opensymphony.xwork2.validator.validators.EmailValidator"/>
<validator name="url"
class="com.opensymphony.xwork2.validator.validators.URLValidator"/>
<validator name="visitor"
class="com.opensymphony.xwork2.validator.validators.VisitorFieldValidator"/>
<validator name="conversion"
class="com.opensymphony.xwork2.validator.validators.ConversionErrorFieldValidator"/>
<validator name="stringlength"
class="com.opensymphony.xwork2.validator.validators.StringLengthFieldValidator"/>
<validator name="regex"
class="com.opensymphony.xwork2.validator.validators.RegexFieldValidator"/>
<validator name="conditionalvisitor"
class="com.opensymphony.xwork2.validator.validators.ConditionalVisitorFieldValidator"/>
</validators>
ActionItemTrackingAction-findByCriteria-validation.xml in WEB-INF/classes directory is given below:
<!DOCTYPE validators PUBLIC "-//OpenSymphony Group//XWork Validator 1.0.2//EN"
"http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
<validators>
<field name="searchCriterion" >
<field-validator type="required">
<message>You must enter a search criterion.</message>
</field-validator>
</field>
</validators>
My struts mapping xml:
<struts>
<constant name="struts.enable.DynamicMethodInvocation" value="false" />
<constant name="struts.devMode" value="true" />
<!-- <include file="example.xml"/> -->
<package name="action-item" extends="struts-default">
<action name = "action_item_search_input">
<result name = "success">/action-item-search.jsp</result>
</action>
<action name="action_item_search" class="gov.nasa.spacebook.ActionItemTrackingAction" method="fetchByCriteria">
<result name = "success">/action-item-result.jsp</result>
<result name = "input">/action-item-search.jsp</result>
<result name = "error">/action-item-search.jsp</result>
</action>
</package>
</struts>
My action class
public class ActionItemTrackingAction extends ActionSupport {
private List<ActionItem> actionItems;
public List<ActionItemTracking> getActionItems() {
return actionItems;
}
public void setActionItems(List<ActionItemTracking> actionItems) {
this.actionItems = actionItems;
}
private String searchCriterion;
public String getSearchCriterion() {
return searchCriterion;
}
public void setSearchCriterion(final String criterion) {
this.searchCriterion = criterion;
}
public String fetchByCriteria() throws Exception {
final ActionItemTrackingService service =
new ActionItemTrackingService();
this.actionItems = service.getByField(this.actionItem);
return super.execute();
}
}
I have the same issue when I do not have internet connection on my development machine.
Once internet connection to my development machine is established, I recompile and run the application and the validation works. Seems like the validators.xml requires internet.
You must inlcude <s:head/> tag in your jsp. Other wise client side validations are not possible with struts2x. By default it will not show any alert boxes. you must use onSubmit=<true/false> folowed by function name generated by the HTML . you can check name of the function by seeing source code of generated form in your browser. Hope this will help you.