01. <%@taglib uri="/struts-tags" prefix="s" %>
02. < html >
03. < head >
04. < meta http-equiv = "Content-Type" content = "text/html; charset=UTF-8" >
05. < title >Login Page</ title >
06. < s:head />
07. </ head >
08. < body >
09. < s:form action = "Login" >
10. < s:textfield name = "userName" label = "User Name" />
11. < s:password name = "password" label = "Password" />
12. < s:submit value = "Login" />
13. </ s:form >
14. </ body >
15. </ html >
When the user clicks the Login button the request will be forwarded to the Login action.
We do the action mapping using the struts.xml file. First we need to create a package for our action.
1. < struts >
2. < package name = "default" extends = "struts-default" >
3. < action name = "Login" class = "vaannila.Login" >
4. < result name = "input" >/login.jsp</ result >
5. < result name = "success" >/success.jsp</ result >
6. </ action >
7. </ package >
8. </ 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.
Here the "Login" action is mapped to the "Login" class in the "vaannila"
package. The results are defined using the
"<result>" element. If any validation errors occur the user will
be forwarded to the login.jsp page. If the login is successfull then the
user will be forwarded to the success.jsp page.
The defaultstack contains the following interceptors.
01. < interceptor-stack name = "defaultStack" >
02. < interceptor-ref name = "exception" />
03. < interceptor-ref name = "alias" />
04. < interceptor-ref name = "servletConfig" />
05. < interceptor-ref name = "prepare" />
06. < interceptor-ref name = "i18n" />
07. < interceptor-ref name = "chain" />
08. < interceptor-ref name = "debugging" />
09. < interceptor-ref name = "profiling" />
10. < interceptor-ref name = "scopedModelDriven" />
11. < interceptor-ref name = "modelDriven" />
12. < interceptor-ref name = "fileUpload" />
13. < interceptor-ref name = "checkbox" />
14. < interceptor-ref name = "staticParams" />
15. < interceptor-ref name = "actionMappingParams" />
16. < interceptor-ref name = "params" >
17. < param name = "excludeParams" >dojo\..*,^struts\..*</ param >
18. </ interceptor-ref >
19. < interceptor-ref name = "conversionError" />
20. < interceptor-ref name = "validation" >
21. < param name = "excludeMethods" >input,back,cancel,browse</ param >
22. </ interceptor-ref >
23. < interceptor-ref name = "workflow" >
24. < param name = "excludeMethods" >input,back,cancel,browse</ param >
25. </ interceptor-ref >
26. </ interceptor-stack >
Our Login Action class extends ActionSupport. It is good to extend
ActionSupport class as it provides default implementation for most
common tasks.
01. public class Login extends ActionSupport {
02.
03. private String userName;
04. private String password;
05.
06. public Login() {
07. }
08.
09. public String execute() {
10. return SUCCESS;
11. }
12.
13. public void validate() {
14. if (getUserName().length() == 0 ) {
15. addFieldError( "userName" , "User Name is required" );
16. } else if (!getUserName().equals( "Eswar" )) {
17. addFieldError( "userName" , "Invalid User" );
18. }
19. if (getPassword().length() == 0 ) {
20. addFieldError( "password" , getText( "password.required" ));
21. }
22. }
23.
24. public String getUserName() {
25. return userName;
26. }
27.
28. public void setUserName(String userName) {
29. this .userName = userName;
30. }
31.
32. public String getPassword() {
33. return password;
34. }
35.
36. public void setPassword(String password) {
37. this .password = password;
38. }
39. }
The ActionSupport class implements Action interface which exposes the execute() method.
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"
public static final String INPUT = "input"
public static final String LOGIN = "login"
public static final String NONE = "none"
public static final String SUCCESS = "success"
ERROR is returned when the action execution fails.
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 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 addFiledError() 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.
On executing the sample example the following page will be displayed to the user.
For each field the error messages can be added using the addFieldError()
method. The error messages can either be added directly or it can be
specified in a seperate properties file.
The properties files should have the same name as the Action class. In our case the properties file name is "Login.properties" and the Action name is "Login.java".
The Login.properties file contains the following entry.
1. password.required = Password is required.
The getText() method provided by the TextProvider interface can be used
to retrive the error messages.
You can also do the business validations in the validate() method.
If there are no errors, then the execute() method will be invoked by the workflow interceptor.
In our execute() method we simply return "success". The user will be forwarded to the success page.
|