Table of Contents
This is 4 of 7 part of struts 2 tutorial.
Tutorial Content:
- Introduction to struts 2
- configuring struts 2 in eclipse
- Struts 2 hello world example
- Login page with validation in struts 2
- Struts 2 interceptors with example
- File upload in struts 2
- Struts 2 ajax example
- Struts 2 spring 3 integration example
In this example we will see how we can validate a login page using Struts 2.
In previous post, we have learned about mapping from client request to action class and rendering appropriate jsp on the basis of returned string of execute() method of action class.
In this post,we will use struts ui tags to create login page so we will learn how to use tags.
Create project named “LoginAppInStruts2”.For configuring struts 2 in your eclipse IDE please refer configuring struts 2 link.
Web.xml:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
<?xml version="1.0" encoding="UTF-8"?> <web-app id="WebApp_9" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemalocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <display-name>LoginAppInStruts2</display-name> <filter> <filter-name> struts2 </filter-name> <filter-class> org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter </filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <welcome-file-list> <welcome-file>login.jsp</welcome-file> </welcome-file-list> </web-app> |
JSP:
Login.jsp:
Create login page as login.jsp under WebContent.
1 2 3 4 5 6 7 8 9 10 11 12 |
&<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <%@taglib uri="/struts-tags" prefix="s" %> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>Login Page</title> |
The tag should be placed in the head section of the HTML page. The s:head tag automatically generates links to the css and javascript libraries that are necessary to render the form elements.
The s:form tag contains all the form elements. The action attribute contains the action name to wich the form should be submitted. This action name should be same as the one specified in the XML declarative architecture. In this example we use struts.xml file to do the configuration.
The textfield tag is used create a text box. The label attribute of the textfield tag contains the name to be displayed on the page and the name attribute contains the name of the property in the action class to be mapped. The password tag is same as the textfield tag except that the input value is masked. The submit tag is used to create a submit button, the value “Login” represents the label of the button.
Note that the code is simple without any HTML tables, this is because Struts 2 will automatically create the necessary tables for the page based on the theme selected. By default the XHTML theme is selected.
When user click on login button,Request is forwarded to Login action.
Welcome.jsp:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" Â Â Â pageEncoding="ISO-8859-1"%> <%@taglib uri="/struts-tags" prefix="s"%> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>login Successful</title> Welcome <property value="userName"></property>!!! |
Action class:
copy following code into LoginAction.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
package org.arpit.javapostsForLearning; import com.opensymphony.xwork2.ActionSupport; public class LoginAction extends ActionSupport { private String userName; private String password; public String execute() { return SUCCESS; } 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 void validate() { if (getUserName().length() == 0) { addFieldError("userName", "UserName.required"); } else if (!getUserName().equals("Arpit")) { addFieldError("userName", "Invalid User"); } if (getPassword().length() == 0) { addFieldError("password", getText("password.required")); } } } |
The following constants are declared in the Action interface which can be used as return values in the execute() method.
public static final String ERROR = “error”
INPUT is returned when the action requires more input from the user.
LOGIN is returned when the user is not logged into the system.
NONE is returned when the action execution is successfull and there are no views to display.
SUCCESS is returned when the action executed successfully and the corresponding result is displayed to the user.Now in our action class we have two attributes:
private String userName;– It should be same as name of textfield for getting userName as input defined in login.jsp.
private String password;-It should same as name of textfield for getting password as input defined in login.jsp
tag -you can notice that we have used Struts tag .It renders value of attribute of action class.In this case,attribute is userName of loginAction.java.So whatever user entered in userName textfield will appear at that place in Welcome.jsp.
Struts.xml:
Create struts.xml in src.struts.xml provides mapping between url to action mapping.
copy following code into struts.xml:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<?xml version="1.0" encoding="UTF-8" ?> <struts> <constant name="struts.custom.i18n.resources" value="LoginAction"></constant> Â Â Â <package name="default" extends="struts-default" namespace="/"> Â Â Â Â Â Â <action name="Login" class="org.arpit.javapostsForLearning.LoginAction"> Â Â Â Â Â Â Â Â Â <result name="success">Welcome.jsp</result> Â Â Â Â Â Â Â Â Â <result name="input">login.jsp</result> Â Â Â Â Â Â </action> Â Â Â </package> </struts> |
Here our “default” package extends “struts-default” package. By extending the “struts-default” package the action will by default inherit the set of interceptors defined in the defaultstack. The “struts-default” package is defined in the struts-default.xml file.
All the common tasks done by the Actions are seperated and placed in different interceptors. You can define an interceptor stack for each action. Most commonly used interceptors are grouped in defaultstack of the struts-default package. The defaultstack will be sufficient in most cases. The inteceptors will be fired in the order in which they are declared in the stack both before and after the action is executed.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
<interceptor-stack name="defaultStack"> <interceptor-ref name="exception"></interceptor-ref> <interceptor-ref name="alias"></interceptor-ref> <interceptor-ref name="servletConfig"></interceptor-ref> <interceptor-ref name="prepare"></interceptor-ref> <interceptor-ref name="i18n"></interceptor-ref> <interceptor-ref name="chain"></interceptor-ref> <interceptor-ref name="debugging"></interceptor-ref> <interceptor-ref name="profiling"></interceptor-ref> <interceptor-ref name="scopedModelDriven"></interceptor-ref> <interceptor-ref name="modelDriven"></interceptor-ref> <interceptor-ref name="fileUpload"></interceptor-ref> <interceptor-ref name="checkbox"></interceptor-ref> <interceptor-ref name="staticParams"></interceptor-ref> <interceptor-ref name="actionMappingParams"></interceptor-ref> <interceptor-ref name="params"> <param name="excludeParams">dojo\..*,^struts\..* </interceptor-ref> <interceptor-ref name="conversionError"></interceptor-ref> <interceptor-ref name="validation"> <param name="excludeMethods">input,back,cancel,browse </interceptor-ref> <interceptor-ref name="workflow"> <param name="excludeMethods">input,back,cancel,browse </interceptor-ref> </interceptor-stack> |
Now lets see the roles played by the different interceptors.
The params interceptor helps in transfering the request data onto the action object.
The workflow interceptor controls the flow of cotrol.
The workflow interceptor checks whether the action implements the Validateable interface , if it does, the workflow interceptor will invoke the validate() method of the Action class.
In the validate() method we validate the user name and the password. If the validation fails an error is added using the addFieldError() method.
The validate() method doesn’t return any errors, instead it stores all the errors with the help of the ValidationAware interface.
Now the workflow interceptor will check any validation errors has occured. If any error has occured the workflow interceptor will stop the request processing and transfer the control to the input page with the appropriate error messages.
The ResourceBundle:
The properties files should have the same name as the Action class. In our case the properties file name is “LoginAction.properties” and the Action name is “LoginAction.java“. This property file should be present in WEB-INF/classes folders when the source is compiled.
Create LoginAction.properties under src.Copy following content to LoginAction.properties.
1 2 3 4 |
userName.required=user name is required password.required=password is required |
Run Project:
so when you paste resultant url(https://localhost:8080/LoginAppInStruts2/) to your browser,you will get some thing like this.
if you enter userName as “mandliya” .you will get following.
If you enter userName as “arpit” and password also as “arpit”.you will get
Source code:
1 2 3 4 |
<b>Source:</b><a href="https://dl.dropbox.com/s/au5b5db2xbaa3b1/LoginAppInStruts2.7z" target="_blank" rel="noopener"><b>Download without jars files</b></a><b> Source + lib: </b><a href="https://dl.dropbox.com/s/4navsp6g8wmeygc/LoginAppInStruts2WithJars.7z" target="_blank" rel="noopener"><b>Download with jars files</b></a> |
Now in next post,we will understand concept of interceptors in detail.