Você está na página 1de 44

Green text: to read again (not read yet) Red: Find more on it.

Struts 1.3
What is framework? It is a bunch of some readymade reusable classes and interfaces, which helps to improve application development, modularity, maintainability, to reduce plumbing code (i.e. the code supporting business n app but not actual business code. E.g. logging, authentication, controlling of flow, transaction management etc.) and lets us focus on business logic and externalization of code flow. Few frameworks are application wide i.e. they can take a role all over the app. E.g. struts, spring. They are called Application Framework. And few have role in particular layer only. E.g. Hibernate works only for DAO layer. So it is not application framework. Problems with app without struts: 1) In the web app containing servlets and JSP, container calls init() method on the 1st request for the servlet / jsp. And destroy() is called when container shuts down. So for this time period, servlet instance remains alive in the memory. When there are large number of servlets n jsps involved in the app, instances for all of them who have received a request will be alive which becomes performance overhead for memory. 2) All code flow from servlets to jsp or otherway has to be coded in servlet. E.g. if one servlet redirects the flow to somewhereelse, that path is written as a parameter to redirect method. So we have to open servlet n trace the flow. It reduces code flow visibility and maintainability. 3) When data is to be shared amongst servlets n jsps, only way is to use attributes of different scopes. Which is not a good design. 4) Separation of concerns is also not easily possible using servlets n jsp only. Servlets which are supposed to contain controlling logic only usually contain business logic also many times. N also, jsps who are supposed to handle only view also contain controlling n business using scriptlets. It is not good design. How struts handles drawbacks: 1) There is only one servlet reqd using struts, which handles all controlling. So only one servlet instance alive. 2) For externalizing things, all mappings and flows are handled by external xml file used for configuring struts. All flows in app are visible here. So maintainability increases. 3) Not clear yet 4) Struts follow MVC design pattern. So separation of concerns is easier here. Web app with Struts: Deployment Descriptor: web.xml
1

1. When container starts, it loads web.xml file i.e. Deployment Descriptor. 2. DD contains only one servlet, which is controlling servlet, which is of type ActionServlet provided by struts. (If we want, we can add multiple ActionServlets too. But it wont achieve anything. Since all functionality can be handled by just one. If we wish, we can add other simple servlets too, which wont be controlled by struts. But these things can complicate implementation details. So it is perfectly unnecessary though legal. ) 3. Its mapping is done to all urls. Wild card entries are used here. So all urls to this app will have entry point thro this controller only. 4. Particular input to business logic handler for it is mapped in another xml file. It is supposed to be the configuration for struts regarding flow control. This file can be single or multiple and can have any name. Path to this file or files (with respect to WebContent folder, which is root folder, and WEB-INF lies inside it.) is provided as init param to ActionServlet. The name of the init param must be config (since it refers to parameter used in ActionServlet class provided by struts). Multiple files are given by separating by comma.

Web.xml
<web-app > <servlet> <servlet-name>ActionServlet </servlet-name> <!name can be different also --> <servlet-class>org.apache.struts.action.ActionServlet</servlet-class> <!this class is mandatory. It is provided by struts. --> <init-param> <param-name>config</param-name> <!name of this param must be config --> <param-value>/WEB-INF/struts-config_1.xml,/WEBINF/Abc.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name> ActionServlet </servlet-name> <url-pattern>*.do</url-pattern> <!it can be anything *.foo,*.jsp etc. --> </servlet-mapping> </web-app> So in all ActionServlet is a controller which is initialized on reading of web.xml.

Struts-config.xml (Any name can be given.)


The five important sections are: 1. Form bean definition section 2. Global forward definition section 3. Action mapping definition section 4. Controller configuration section 5. Application Resources definition section 1. FormBean section: The form bean definition section contains one or more entries for each ActionForm. Each form bean is identified by a unique logical name. The type is the fully qualified class name of the ActionForm. An interesting to note is that you can declare the same ActionForm class any number of times provided each entry has a unique name associated with it. This feature is useful if you want to store multiple forms of the same type in the servlet session. <form-beans> This section contains your form bean definitions. Form beans are descriptors that are used to create ActionForm instances at runtime. You use a <form-bean> element for each form bean, which has the following important attributes: name: A unique identifier for this bean, which will be used to reference it in corresponding action mappings. Usually, this is also the name of the request or session attribute under which this form bean will be stored. type: The fully-qualified Java classname of the ActionForm subclass to use with this form bean.

<form-beans> <form-bean name= type=/> </form-beans> ActionForm classes: ActionForm: <-> formbean in config file. JavaBeans can also be used to manage input forms. A key problem in designing Web applications is retaining and validating what a user has entered between requests. You can define your own set of input bean classes, by subclassing ActionForm[org.apache.struts.action.ActionForm]. The ActionForm class makes it easy to store and validate the data for your application's input forms. The ActionForm bean is automatically saved in one of the standard, shared context collections, so that it can be used by other objects, like an Action object or another JSP. The form bean can be used by a JSP to collect data from the user ... by an Action object to validate the user-entered data ... and then by the JSP again to re-populate the form fields. In the case of validation errors, the framework has a shared mechanism for raising and displaying error messages. Another element of the Configuration are the ActionFormBeans[org.apache.struts.action.ActionFormBeans]. This is a collection of descriptor objects that are used to create instances of the
3

ActionForm objects at runtime. When a mapping needs an ActionForm, the servlet looks up the form-bean descriptor by name and uses it to create an ActionForm instance of the specified type. Here is the sequence of events that occur when a request calls for an mapping that uses an ActionForm: The controller servlet either retrieves or creates the ActionForm bean instance. The controller servlet passes the bean to the Action object. If the request is being used to submit an input page, the Action object can examine the data. If necessary, the data can be sent back to the input form along with a list of messages to display on the page. Otherwise the data can be passed along to the business tier. If the request is being used to create an input page, the Action object can populate the bean with any data that the input page might need.

1. Global Forwards:

Explained later while explaining struts-config file. 3. Action Mapping section: When initialized, the controller parses a configuration file (struts-config.xml) and uses it to deploy other control layer objects. Together, these objects form the Struts Configuration. The Configuration defines (among other things) the collection of ActionMappings[org.apache.struts.action.ActionMappings] for an application. The controller component consults the ActionMappings as it routes HTTP requests to other components in the framework. Requests may be forwarded to JavaServer Pages or Action[org.apache.struts.action.Action] subclasses provided by the application developer. Often, a request is first forwarded to an Action and then to a JSP (or other presentation page). The mappings help the controller turn HTTP requests into application actions. An individual ActionMapping[org.apache.struts.action.ActionMapping] will usually contain a number of properties including: <action-mapping> <action ></action> <action ></action> </action-mapping> <action-mapping> tag contains 0 to multiple action tags.

<action> tag attributes:


a request path (or "URI"), the object type (Action subclass) to act upon the request, and
4

other properties as needed.

Attribute/Elemen Description t name The URL path (either path mapping or suffix mapping) for which this Path Action Mapping is used. The path should be unique Type The fully qualified class name of the Action The logical name of the Form bean. The actual ActionForm associated with this Action Mapping is found by looking in the Form-bean definition Name section for a form-bean with the matching name. This informs the Struts application which action mappings should use which ActionForms. Scope Scope of the Form bean Can be session or request Can be true or false. When true, the Form bean is validated on submission. Validate If false, the validation is skipped. The physical page (or another ActionMapping) to which control should be Input forwarded when validation errors exist in the form bean. The physical page (or another ActionMapping) to which the control Forward should be forwarded when the ActionForward with this name is selected in the execute method of the Action class.

Action class:
The Action object can handle the request and respond to the client (usually a Web browser) or indicate that control should be forwarded elsewhere. For example, if a login succeeds, a login action may wish to forward the request onto the mainMenu page. Action objects have access to the application's controller component, and so have access to that members's methods. When forwarding control, an Action object can indirectly forward one or more shared objects, including JavaBeans, by placing them in one of the standard contexts shared by Java Servlets. For example, an Action object can create a shopping cart bean, add an item to the cart, place the bean in the session context, and then forward control to another mapping. That mapping may use a JavaServer Page to display the contents of the user's cart. Since each client has their own session, they will each also have their own shopping cart. Most of the business logic in an application can be represented using JavaBeans. An Action can call the properties of a JavaBean without knowing how it actually works. This encapsulates the business logic, so that the Action can focus on error handling and where to forward control.

4. Controller section: The controller is optional. Unless otherwise specified, the default controller is always the org.apache.struts.action.RequestProcessor. There are cases when you want to replace or extend this to have your own specialized processor. For instance, when using Tiles (a JSP page template framework) in conjunction with Struts, you would use TilesRequestProcessor.
5

RequestProcessor

The RequestProcessor Class is the actual place where the request processing takes place in a Struts controller environment. When the request object first reaches the actionservlet class then it invokes the process method of the underlying RequestProcessor Class. This process method then looks into the struts-config.xml file and tries to locate the name of the action that has come with the request.Once it identifies the action in the xml file it continues the rest of the steps needed for request processing. processor has most of the following responsibilities: 1. Determine path, 2. Handle Locale, 3. Process content and encoding type, 4. Process cache headers 5. Pre Processing hook 6. Pre-processing hook, 7. Determine mapping, 8. Determine roles, 9. Process and validate actionForm, 10. Return a response It is one instance per application module; it invokes proper Action instance Of course processes all requests for a module.
<controller processorClass="org.apache.struts.action.RequestProcessor" />

5.Application Resourse definition section: Well, we declare that properties file in the struts-config.xml in the Message Resources definition section. The declaration in Listing above states that the Message Resources Bundle for the application is called ApplicationResources.properties and the file is located in the java package mybank. If you are wondering how (and why) can a properties file be located in a java package, recall that any file (including class file) is a resource and is loaded by the class loader by specifying the package.

Struts Configuration file: any_name.xml: (Contents can be divided


in multiple files too.) Root tag: <struts-config> (like <web-app > tag in DD)
1) <!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.1//EN" "http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd"> The DTD to validate and interpret the tags in configuration file. 2) <action-mappings> 6

<action path= type= name= scope= validate= input= > <!there can be multiple action tags under action-mapping tag.--> <!path is unique per application--> <!type= fully qualified name of action class. Different actions can use same type--> <!name= name of corresponding form bean. Can be found under formBean tag in configuration--> Other attributes explained in table above. <forward name= path= redirect= /> <!forward is a child tag of action. They can be multiple.--> <!name is unique for this action : name of the forward which is used by action class.--> <!path is the path of servlet/jsp where control is to be redirected.--> <!redirect- true/false. -> </action> Action class implements business logic to be executed when request comes on particular path. e.g. http://localhost:8080/MyApp/add.do is the request url, due to .do here, ActionServlet will come in control. And /add should be the path value. And the class represented by type will be handling business logic for it. The class given by type is called action class and it has to extend Action class provided by struts. In Action class, there is a method which is by default called by struts. (Same like in servlets, service() method is called.) this method is execute(). This must be implemented by out action class given in type. Signature of the method is:
public ActionForward execute(ActionMapping mapping, ActionForm form, httpServletRequest request, HttpServletResponse response)

here, 4 parameters provided in argument: request and response : as they r available to service() method in servlet. Remaining two are addition by struts. As per given details in configuration file, ActionMapping and ActionForm objects are created using reflection. So that configured classes and forms are available for use in business logic.
Instead of specifying an actual JSP page in the code, you can declaratively associate as action forward throughout the application. The action forward are specified in the configuration file by <forward> tag. This tag is child tag of <action> tag. They can be multiple per <action> tag. For forward tag, attribute redirect is optional. And false by default. If it is true, the forward works as request dispatcher. So in this case, new request is initiated from client browser and again it passes thro controller. All attributes of old request are lost. If the redirect attribute is false, it is just like forwarding of the response to next jsp. In which

request attributes of original request are retained. If we want to use redirect is true, it is better to use session attributes.

The execute() method returns ActionForward. The ActionForward class represents a


destination to which the controller may send control once an action has completed. In action class, forward is obtained as: mapping.findForward(name_of_the_forward); 3) <global-forwards> <forward name="Success" path="/action/somejsp.jsp" /> <forward name="Failure" path="/someotherjsp.jsp" /> </global-forwards> The action forward mappings also can be specified in a global section, independent of any specific action mapping. It is available for whole app. Specifically forwards like login, logout etc. are handled globally. Same mapping.findForward( ); is used for retrieving these forwards. In action class, control first checks for matching forward name of that action class and if not found checks for global forwards.

4) <form-beans> <form-bean name= type= /> <!Can be single or multiple per application --> <!name is a name of form bean which is unique per app.--> <!type is a POJO class containing properties as form parameters of jsps.--> </form-beans> In struts, there is no need to get values of inputs filled in html form by calling request.getParameter(); . Instead, struts populates a POJO containing properties corresponding to html form fields. This POJO is called ActionForm. POJO class has to extend ActionForm. This form bean or POJO can be single per app or multiple. Since it is just a POJO, even single POJO can serve whole application. But to make it memory efficient, multiple form beans are preferable. Because, they get loaded, only when requested. Loading a huge single POJO will be performance overhead. This POJO extends org.apache.struts.action.ActionForm To provide mapping regarding which form bean i.e. ActionForm is to be populated for which action, name attribute in <action> tag is used. Its value should be identical to name of appropriate <form-bean>. Now we use form.getVariableName() instead of request.getParameter(). So approach is more Object oriented now. Struts application:

Libraries:

Web.xml:
<?xml version="1.0" encoding="UTF-8"?> <web-app id="WebApp_ID" 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>Struts_app</display-name>

<servlet> <servlet-name>ActionServlet</servlet-name> <servlet-class>org.apache.struts.action.ActionServlet</servlet-class> <init-param> <param-name>config</param-name> <param-value>/WEB-INF/Struts-Config.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>ActionServlet</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping> </web-app>

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts-config SYSTEM "lib/struts-config_1_2.dtd" > <struts-config> <form-beans> <form-bean name="loginFormBean" type="java_classes.LoginForm"/> </form-beans> <action-mappings> <action path="/LoginActionPath" type="java_classes.LoginAction" name="loginFormBean"> <forward name="success" path="/Success.jsp"/> </action> </action-mappings> </struts-config>

Struts-config.xml

LoginPage.jsp
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <!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>Insert title here</title> </head> <body> <form action=LoginActionPath.do> Username: <input type="text" name="username"> Password: <input type="password" name="password"> <input type="submit" value="Submit"> </form> </body> </html>

LoginForm.java
package java_classes; import org.apache.struts.action.ActionForm; public class LoginForm extends ActionForm {

10

String username; String password; public String getUsername() { return username; } public String getPassword() { return password; } public void setUsername(String username) { this.username = username; } public void setPassword(String password) { this.password = password; }

LoginAction.java
package java_classes; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import import import import org.apache.struts.action.Action; org.apache.struts.action.ActionForm; org.apache.struts.action.ActionForward; org.apache.struts.action.ActionMapping;

public class LoginAction extends Action { @Override public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { /* * if action forward is not used, this response is used. here form is available to use. */ LoginForm myForm = (LoginForm) form; response.getWriter().write("username:" + myForm.getUsername()); response.getWriter().write("password:"+myForm.getPassword()); //return super.execute(mapping, form, request, response); /* can use below return to forward control to success.jsp. * then no use of above response writings*/ return mapping.findForward("success"); return null; } }

//

Success.jsp
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"

11

pageEncoding="ISO-8859-1"%> <!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>Insert title here</title> </head> <body> Hello there. </body> </html>

Flow: LoginPage.jsp is the entry point. Its url is http://localhost:8080/Struts_app/LoginPage.jsp When username and password is filled and submit button is clicked, struts controller starts working. On submit url becomes: http://localhost:8080/Struts_app/LoginActionPath.do? username=sdsdsd&password=sds LoginActionPath.do is written as action attribute of form tag in LoginPage.jsp. So the url is formed this way. In web.xml, ActionServlet is defined which has url pattern *.do. So above url has to cross action servlet. Then ActionServlet i.e. controller looks in configuration i.e. Struts-Config.xml. In it action is mapped for path /LoginActionPath. It checks the class for corresponding action. i.e. type attribute. And sends control to execute method of that action class. At the same time, POJO for the corresponding form bean is populated. This ActionMapping and populated FormBean pojo are now available to execute method in action class alog with request response. The form parameters can be accessed in same action class using form object obtained by execute method. This object is casted to our form bean class i.e. LoginForm here. And on that object, getters of the POJO are called. If response is to be redirected to another jsp, forward can be used. For that forward tag is defined as sub-tag of action. It has name attribute to specify name of the forward and path to specify location of jsp. In action class, in execute method, mapping object obtained in execute method can be used to accomplish forward action. mapping.findForward(name of the forward); This forward gives ActionForward, which is returned by execute method.

Validation inside form bean:


of validator framework of struts.)

it can be done in struts only. (It is not a part

12

In non-struts app: Client side validation: javascript Server side: in servlet though its not business or control code. ActionForm gives validate method. So extending ActionForm is not just for retrival of form entries, but also for validation of those values. So now form bean POJO will contain validate() method in addition to getters n setters. There can be 2 different actions which can use same form bean. For one of it we need validation n for other, we may not need. So for this validate attribute in <action> tag is used. <action validate=true if validation is required. Here, input is a mandetory attribute because I have to keep track of from where the page control came , so that I can go back to display validation errors. Public ActionErrors validate(ActionMapping mapping, HttpServletRequest request ) ActionErrors: ActionErrors can be many per validation flow. Each ActionError contains one ActionMessage. ActionMessage: class from action package. I would require error id for each error and a message so that I would know validation for which field is failed and what is the message to be displayed. This id will be used for displaying the message in front of proper field in jsp page. Public ActionErrors validate(ActionMapping mapping, HttpServletRequest request ) { ActionErrors errors = new ActionErrors(); If(getPassword() == null ) { Errors.add(password, new ActionMessage(password required)); } Return errors; } RequestProcessor fills in the form data before flow goes to action execution. So this validation is triggered by request processor calls validate() method of form before it goes to action. N if there is some problem with validation, control goes back to same jsp page to indicate the error. By default errors are returned to input page. But if I need to redirect it to some error page, I need to change this input. So to retrieve input and change path given to input we need mapping object in validation. The path will be changed only for this instance may be for certain conditions. E.g. multiple login attempts failed so account deactivated.

13

How to use data populated in form bean in the forward page?


Usual way of setting it is a session or request attribute in action class and retrieving in next jsp works. But there is some special provision to use direct formbean. Getting value from action and putting it in jsp: we need tags here. If we are not supposed to business logic, scriptlet then we need to use jsp tags.

Struts Taglib is composed of four distinct tag libraries: Bean, HTML, Logic, and Nested.
tags: It is something that broweser understands. Which is used in presentation layer only either for data manipulation or displaying something in proper format. E.g. <table> Struts tags are used for data manipulation only. E.g. 1) html tags: input, textbox, checkboxes, form etc. html tags are object oriented. We have property attributes in side it. 2) Logic: all logical operations e.g. loopings, iterators etc which we do in scriptlets. 3) Bean: display operations done by bean.write() now. 4) Nested: The Nested tags extend the base Struts tags to allow them to relate to each other in a

nested nature. The fundamental logic of the original tags doesn't change, except in that all references to beans and bean properties will be managed in a nested context.
These tags are described in TLDs i.e. tag libs. When jsp compiles that is at load time of container, tlds are compiled and get converted in simple html. Container does it. Because, browser understands simple html tags only. So when we do view source in the browser , we see html tags only and no tld specific tags. We write on every jsp page which tld I am using in this page. And all the TLDs are imported in web.xml under <taglib> tag. <taglib> <taglib-uri>/abc.tld</> <taglib-location>/WEB-INF/lib/abc.tld</> </taglib> In jsp, %@taglib uri=/abc.tld prefix=pqr% Bean: prefix:bean as per convention for using tags related struts-bean.tld Bean:write Bean:message From login action, on success forward, we are going to success.jsp in which we can write: <bean:write property="username" name="loginFormBean"/ http://j2ee.masslight.com/Chapter4.html 14

Bean Tags
The Struts framework provides other tags for dealing with issues concerning copying cookies, request headers, JSP implicity defined objects, request parameters, web application resources, Struts configuration objects, and including the dynamic response data from an action. These tags are not discussed here, but it is important to be aware of their existence.
<bean:cookie ... > <bean:header ... > <bean:page ... > <bean:parameter ... > <bean:header ... > <bean:resource ... > <bean:struts ... >

Bean Output
In non-strut app we write all messages in properties file and retrieve it in scriptlet in jsp using io operation passing key. In struts its easier. We specify <bean:message key=keyname/>

The <bean:message> and <bean:write> tags from the Struts framework will write bean and aplication resources properties into the current HttpResponse object. This tag allows locale specific messages to be displayed by looking up the message in the application resources .properties file.
<!-- looks up the error.divisionByZero resource --> <!-- and writes it to the HttpResponse object --> <bean:message .. <bean:message key="error.divisionByZero"/> . > <!-- looks up the prompt.name resource -->

<!-- and writes it to the HttpResponse object; --> <!-- failing that, it writes the string --> <!-- contained in the attribute arg0--> <bean:message key="prompt.name" arg0='Enter a name:'/>

This tag writes the string equivalent of the specified bean or bean property to the current HttpResponse object.
<bean:write ... <!-- writes the value of customer.getStreetAddress().toString() > --> <!-- to the HttpResponse object --> <bean:write name="customer" property="streetAddress"/>

Struts-html tld wont work for 1st jsp e.g. index.jsp because struts is not in action yet. Control is not forwarded to ActionServlet yet. It will work only when ActionServlet will be clicked in.
<html:base> <html:button>

Generates a <base> tag. This tag should be used inside of a <head> tag.
Top of Form Bottom of Form

15

Generates an <input type="button"> tag. This tag should be used inside a <form> element.
Top of Form Bottom of Form

<html:cancel>

Generates an <input type="submit"> tag and causes the Action servlet not to invoke its validate() method. This tag should be used inside a <form> element.
Top of Form

Wheat

Wood

Clay

<html:checkbox> <html:multibox>

Stone

Sheep
Bottom of Form

<html:checkbox> <html:multibox>

Generates an <input type="checkbox">.

Generates an <input type="checkbox">. "Checkedness" depends upon whether the property array specified contains a corresponding value as the one specified for the multibox.
<html:errors>

Generates html to display any errors that may have occurred during invocation of the validate() method.
Top of Form Bottom of Form

<html:file> <html:form> <html:hidden> <html:html> <html:image>

Generates <form>. There is a hidden element here which is invisible. :-) Generates <input type="hidden">. Generates <html>.

16

<html:img>

<html:link>

A link to an external site Generates an html link.


Top of Form

******

<html:password>

Bottom of Form

Generates <input type="password"> for use in collecting information that should not be shown on-screen.
Top of Form

<html:radio>

Credit

Debit
Bottom of Form

Generates a radio button (<input type="radio">).


Top of Form Bottom of Form

<html:reset>

Generates <input type="reset">.


<html:rewrite>
Top of Form

<html:select> <html:options> <html:option> <html:select>

Bottom of Form

Generates <select>. Generates html for an entire list of <option> tags.


Top of Form Bottom of Form

<html:options> <html:option> <html:submit>

Generates a single <option>.

17

Generates <input type="submit"> to submit form data entered by the user.


Name
<html:text>

Email Address Generates <input type="text">.


Top of Form

Four-score and seven years ago

<html:textarea>
Bottom of Form

Generates <textarea>.

The Struts Taglib component provides custom tags that can automatically populate fields from a JavaBean. JavaServer Pages really need to know is the field names to use and where to submit the form. Other tags can automatically output messages queued by an Action or ActionForm and simply need to be integrated into the page's markup. The messages are designed for localization and will render the best available message for a user's locale.

MessageResources and internationalization: Internationalized Messages


18

A few years ago, application developers could count on having to support only residents of their own country, who are used to only one (or sometimes two) languages, and one way to represent numeric quantities like dates, numbers, and monetary values. However, the explosion of application development based on web technologies, as well as the deployment of such applications on the Internet and other broadly accessible networks, have rendered national boundaries invisible in many cases. This has translated (if you will pardon the pun) into a need for applications to support internationalization (often called "i18n" because 18 is the number of letters in between the "i" and the "n") and localization. The framework builds upon the standard classes available on the Java platform to build internationalized and localized applications. The key concepts to become familiar with are:
Locale - The fundamental Java class that supports internationalization is Locale . Each Locale represents a particular choice of country and language (plus an optional language variant), and also a set of formatting assumptions for things like numbers and dates. ResourceBundle - The java.util.ResourceBundle class provides the fundamental tools for supporting messages in multiple languages. See the Javadocs for the ResourceBundle class, and the information on Internationalization in the documentation bundle for your JDK release, for more information. PropertyResourceBundle - One of the standard implementations of ResourceBundle allows you to define resources using the same "name=value" syntax used to initialize properties files. This is very convenient for preparing resource bundles with messages that are used in a web application, because these messages are generally text oriented. MessageFormat - The java.text.MessageFormat class allows you to replace portions of a message string (in this case, one retrieved from a resource bundle) with arguments specified at run time. This is useful in cases where you are creating a sentence, but the words would appear in a different order in different languages. The placeholder string {0} in the message is replaced by the first runtime argument, {1} is replaced by the second argument, and so on. MessageResources - The framework class org.apache.struts.util.MessageResources lets you treat a set of resource bundles like a database, and allows you to request a particular message string for a particular Locale (normally one associated with the current user) instead of for the default Locale the server itself is running in.

Please note that the i18n support in a server-side framework is limited to the presentation of internationalized text and images to the user. Support for Locale specific input methods (used with languages such as Japanese, Chinese, and Korean) is left up to the client device, which is usually a web browser.
Struts Internationalization (i18n) can be done with some handy modifications in our existing application. We have to know the two Internationalization (i18n) components that are packaged with the Struts Framework. The first of these components, which is managed by the application Controller, is a Message class that references a resource bundle containing Locale-dependent strings. The second Internationalization (i18n) component is a JSP custom tag, <bean:message />, which is used in the View layer to present the actual strings managed by the Controller. In this section we will move with an example to understand the whole process. We are

19

continuing the same example which we used earlier to understand the simple struts example in the section Struts Example. First thing we will require for Internationalization (i18n) is a set of simple Java properties files. Each file contains a key/value pair for each message that you expect your application to present, in the language appropriate for the requesting client. This property file contains the key/value pairs for the default language of your application. The naming format for this file is ResourceBundleName.properties. An example of this default file, using English as the default language, would be ApplicationResources.properties A sample entry in this file would be app.name=Name, this tells Struts that for every occurrence of the app.name key the Name will be substituted. We must define a properties file for each language that your application will use. This file must follow the same naming convention as the default properties file, except that it must include the two-letter ISO language code of the language that it represents. Example of this naming convention For an German-speaking client would be ApplicationResources_de.properties For an French-speaking client would be ApplicationResources_fr.properties For an Italian-speaking client would be ApplicationResources_it.properties For an Spanish-speaking client would be ApplicationResources_es.properties Now add the respective entries in each properties files you require. After you define all of the properties files for your application, you need to make Struts aware of them. It is achieved by adding a <message-resources> sub-element to the struts-config.xml file. Then you should copy all the resource bundles into the application classpath, /WEBINF/classes/example, and then use the package path plus the base file name as the value of the <message-resources> subelement. The following snippet shows an example of using the <message-resources> subelement to configure a resource bundle, using the properties files described above <message-resources parameter="example.ApplicationResources"/> Once this part is done we customise the view part , this is achieved throught the second i18n component defined by the Struts Framework is a JSP custom tag, <bean:message />, which is used to present the actual strings that have been loaded by the Controller. To use the <bean:message />, we must first deploy the bean tag library, which contains the <bean:message /> tag. Deploying a tag library is a very simple process that requires only the addition of a new <taglib> entry in the web.xml file of the Web application using the bean library. Here is an example of this entry: <taglib> <taglib-uri>/WEB-INF/struts-bean.tld</taglib-uri> <taglib-location>/WEB-INF/struts-bean.tld</taglib-location> </taglib> Also check that the struts-bean.tld file is copied to the /WEB-INF/ folder. <bean:message /> tag and how it is configured for use. Now we are done we will check step by step of our saple application. 1. WeCreate the resource bundles that will contain the key/value pairs used in your application. For our application, we will have four properties files that contain our resource bundles.

20

The German ApplicationResources_de.properties file. app.name=Name app.hello=Hallo The French ApplicationResources_fr.properties file. app.name=Nom app.hello=Bonjour The Italian ApplicationResources_it.properties file. app.name=Nome app.hello=Ciao The Spanish ApplicationResources_fr.properties file. app.name=Nombre app.hello=Hola The English ApplicationResources.properties file. app.name=Name app.hello=Hello 2. Copy all of the properties files to the /WEB-INF/classes/example directory. Add an application <message-resources /> subelement, naming the wiley. ApplicationResources to the struts-config.xml file, as shown <struts-config> <form-beans> <form-bean name="nameForm" type="example.NameForm"/> </form-beans> <action-mappings> <action path="/Name" type="example.NameAction" name="NameForm" > <forward name="success" path="/quote.jsp"/> <forward name="failure" path="/index.jsp"/> </action> </action-mappings> <message-resources parameter="example.ApplicationResources"/> </struts-config> 3. Modify the web.xml file as discussed above by adding <taglib> <taglib-uri>/WEB-INF/struts-bean.tld</taglib-uri> <taglib-location>/WEB-INF/struts-bean.tld</taglib-location> </taglib> 4. Modify the index.jsp file

Here we don't specify any language specific values in the jsp page, instead we specify them in the ApplicationResource.properties file and display them using <bean:message> tag. According to the language selected in the browser, the corresponding properties file will be used to fetch the key values. If the language is "en" then the key values will be taken from the ApplicationResource.properties file. If the language is "fr" then the key values will be taken from the

21

ApplicationResource_fr.properties file. That is why we append iso code of the language at the end of name of properties file.
index.jsp <%@ page language="java" %> <%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %> <%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %> <html> <head> <title>Sample Struts Application</title> </head> <body> <html:form action="Name" name="nameForm" type="example.NameForm"> <table width="80%" border="0"> <tr> <td><bean:message key="app.name" />:</td> <td><html:text property="name" /></td> </tr> <tr> <td><html:submit /></td> </tr> </table> </html:form> </body> </html> Modify the diplayname.jsp displayname.jsp <%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %> <html> <head> <title>Sample Struts Display Name</title> </head> <body> <table width="80%" border="0"> <tr> <td><bean:message key="app.hello" /><%= request.getAttribute("NAME") %> !!</td> </tr> </table> </body> </html> So we are done with Internationalization (i18n) you need to open your Web browser to the following URL: http://localhost:port/example/

22

For the simplest applications, an Action object may sometimes handle the business logic associated with a request. However, in most cases, an Action object should invoke another object, usually a JavaBean, to perform the actual business logic. This lets the Action focus on error handling and control flow, rather than business logic. To allow reuse on other platforms, business-logic JavaBeans should not refer to any Web application objects. The Action object should translate needed details from the HTTP request and pass those along to the business-logic beans as regular Java variables. In a database application, for example: A business-logic bean will connect to and query the database, The business-logic bean returns the result to the Action, The Action stores the result in a form bean in the request, The JavaServer Page displays the result in a HTML form.

Neither the Action nor the JSP need to know (or care) from where the result comes. They just need to know how to package and display it. Types of actions: Action, ForwardAction, DispatchAction Types of forms: ActionForm, DianaActionForm Only functionality will change as per type. Flow will remain same.

23

Action: org.apache.struts.actions.Action : for every submit, we have to create separate action. Or I need to send it to same acion n check with if else blocks. It will hamper modularization. DispatchAction:To overcome it, we use dispatch action. It takes name of the method as parameter. Then for dispatch action, execute method is not called.
we will extend DispatchAction instead of Action. http://www.java-samples.com/showtutorial.php?tutorialid=581 Multiple methods are to called on basis of parameter. (org.apache.struts.actions.DispatchAction) is one of the Built-in Actions provided along with the struts framework.

Struts Dispatch Action Example


Struts Dispatch Action (org.apache.struts.actions.DispatchAction) is one of the Built-in Actions provided along with the struts framework. The org.apache.struts.actions.DispatchAction class enables a user to collect related functions into a single Action. It eliminates the need of creating multiple independent actions for each function. Here in this example you will learn more about Struts Dispatch Action that will help you grasping the concept better. Let's develop Dispatch_Action class which is a sub class of org.apache.struts.actions.DispatchAction class. This class does not provide an implementation for the execute() method because DispatchAction class itself implements this method. This class manages to delegate the request to one of the methods of the derived Action class. An Action Mapping is done to select the particular method (via Struts-Configuration file). Here the Dispatch_Action class contains multiple methods ie.. add() , edit() , search() , save(). Here all the methods are taking the same input parameters but each method returns a different ActionForward like "add" in case of add() method , "edit" in case of edit() etc. Each ActionForward is defined in the struts-config.xml file (action mapping is shown later in this page). Here is the code for Action Class. Developing an Action Class (Dispatch_Action.java)
package roseindia.net; import import import import import import import import java.io.*; javax.servlet.http.HttpServletRequest; javax.servlet.http.HttpServletResponse; javax.servlet.ServletException; org.apache.struts.actions.DispatchAction; org.apache.struts.action.ActionForm; org.apache.struts.action.ActionForward; org.apache.struts.action.ActionMapping;

public class Dispatch_Action extends DispatchAction { public ActionForward add(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response)

24

throws Exception { System.out.println("You are in add function."); return mapping.findForward("add");

public ActionForward edit(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { System.out.println("You are in edit function."); return mapping.findForward("edit"); } public ActionForward search(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { System.out.println("You are in search function"); return mapping.findForward("search"); } public ActionForward save(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { System.out.println("You are in save function"); return mapping.findForward("save"); }

Developing an ActionForm Class Our form bean class contains only one property "parameter" which is playing prime role in this example. Based on the parameter value appropriate function of Action class is executed. Here is the code for
FormBean ( DispatchActionForm.java):
package roseindia.net; import org.apache.struts.action.ActionForm; public class DispatchActionForm extends ActionForm { private String parameter = " "; public String getParameter() { return parameter; } public void setParameter(String parameter) { this.parameter = parameter; }

Defining form Bean in struts-config.xml file


Add the following entry in the struts-config.xml file for defining the form bean <form-bean name="DispatchActionForm" type="roseindia.net.DispatchActionForm"/> Developing the Action Mapping in the struts-config.xml Here, Action mapping helps to select the method from the Action class for specific 25

requests. Note that the value specified with the parameter attribute is used to delegate request to the required method of the Dispath_Action Class.

<action path="/DispatchAction" type="roseindia.net.Dispatch_Action" parameter="parameter" input="/pages/DispatchAction.jsp" name="DispatchActionForm" scope="request" validate="false"> <forward name="add" path="/pages/DispatchActionAdd.jsp" /> <forward name="edit" path="/pages/DispatchActionEdit.jsp" /> <forward name="search" path="/pages/DispatchActionSearch.jsp"/> <forward name="save" path="/pages/DispatchActionSave.jsp" /> </action> Developing jsp page Code of the jsp (DispatchAction.jsp) to delegate requests to different jsp pages : <%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean"%> <%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html"%> <html:html locale="true"> <HEAD> <TITLE>Dispatch Action Example</TITLE> <BODY> <H3>Dispatch Action Example</H3> <p><html:link page="/DispatchAction.do?parameter=add">Call Add Section</html:link></p> <p><html:link page="/DispatchAction.do?parameter=edit">Call Edit Section</html:link></p> <p><html:link page="/DispatchAction.do?parameter=search">Call Search Section</html:link></p> <p><html:link page="/DispatchAction.do?parameter=save">Call Save Section</html:link></p> </html:html> Add the following line in the index.jsp to call the form. <li> <html:link page="/pages/DispatchAction.jsp">Struts File Upload</html:link> <br> Example demonstrates how DispatchAction Class works. </li> Building and Testing the Example To build and deploy the application go to Struts\Strutstutorial directory and type ant on the command prompt. This will deploy the application. Open the browser and navigate to the DispatchAction.jsp page. Your browser displays the following DispatchAction page.

26

Selecting Call Add Section displays the following DispatchActionAdd.jsp page

Selecting Call Edit Section displays the following DispatchActionEdit.jsp page

Selecting Call Search Section displays the following DispatchActionSearch.jsp page

27

Selecting Call Save Section displays the following DispatchActionSave.jsp page

28

ForwardAction
Travelling from one jsp to another jsp:
In non-strut app, or with normal Action, either jsp forward or redirect thro servlet or a class. But it means view controlling a flow, that is mixing of controlling and view which isnt adviceable. This is overcame using forwardAction. View has nothing to do with next page. Most of the times you will perform some processing when you navigate from one page to another. In Struts, this processing is encapsulated in the Action instances. There are times however when all you want to do is navigate from one page to another without performing any processing. You would be tempted to add a hyperlink on the first page for direct navigation to the second.

Watch out! In Model 2 paradigm, a straight JSP invocation from another JSP is discouraged, although not prohibited. For instance, suppose you want to go from PageA.jsp to PageB.jsp in your Struts application. The easy way of achieving this is to add a hyperlink in PageA.jsp as follows: <a href="PageB.jsp">Go to Page B</a> or even better, as follows: <html:link page=/PageB.jsp>Go to Page B</html:link> However this violates the MVC spirit by directly accessing the JSP. In Model 2 applications, it is the responsibility of the Controller to select and dispatch to the next view. In Struts, ActionServlet and Action classes together form the controller. They are supposed to select and dispatch to the next view. Moreover the ActionServlet is responsible for intercepting your request and providing appropriate attributes such as Message Resource Bundles. If you bypass this step, then the behavior of the Struts tags may become unpredictable. MVC compliant usage of LinkTag Struts provides a built-in Action class called ForwardAction to address this issue. With ForwardAction, the Struts Controller is still in the loop while navigating from PageA to PageB. There are two steps involved in using the ForwardAction. They are: First, declare the PageA hyperlink that takes you to PageB as follows: <html:link page=/gotoPageB.do>Go to Page B</html:link> Next, add an ActionMapping in the Struts Config file as follows: <action path=/gotoPageB parameter=/PageB.jsp type=org.apache.struts.actions.ForwardAction />
29

The PageA.jsp hyperlink now points to /gotoPageB.do instead of PageB.jsp. This ensures that the controller is still in the loop. The three attributes shown above are mandatory in a ForwardAction. The type attribute is always org.apache.struts.actions.ForwardAction instead of a custom Action of yours. The path attribute identifies the URL path, as any other ActionMapping. The parameter attribute in the above definition is the URL for the next JSP. In the above ActionMapping you might have noticed there is no ActionForm. The Struts Config file DTD specifies that the Form bean is optional in an ActionMapping. Logically speaking ActionForm makes sense only where is data to be collected from the HTML request. In situations like this where there is no HTML data involved in the navigation, there is no need for ActionForm. Using LinkTags action attribute The LinkTag (<html:link>) has several variations. It can be used in a variety of ways in conjunction with ForwardAction. You just saw one usage of the LinkTag. A second way of using the this tag is as follows: First, declare the PageA hyperlink that takes you to PageB as follows: <html:link action=gotoPageB>Go to Page B</html:link> Next, add the ActionMapping for /gotoPageB in the Struts Config file same way as before: <action path=/gotoPageB parameter=/PageB.jsp type=org.apache.struts.actions.ForwardAction /> When you use the action attribute instead of the page attribute in <html:link>, you need not specify the .do explicitly. Using LinkTags forward attribute There is yet another way to use <html:link>. In this approach you use the forward attribute of the <html:link> tag instead of the action. There are two steps involved in this approach. First, declare the PageA hyperlink that takes you to PageB as follows: <html:link forward=pageBForward>Go to Page B</html:link> Add a Global Forward for pageBForward as follows in the globalforwards section: <global-forwards> <forward name=pageBForward path=/PageB.jsp /> </global-forwards> When used in this manner, the <html:link> gets transformed into the following HTML Link. <a href=App1/PageB.jsp>Go to Page B</a> Oops, that doesnt seem right. The HTML Link is now displaying the actual JSP name directly in the browser. Ideally you would love to hide the JSP name from the user. And with a slight twist you can! First, define an ActionMapping as follows: <action path=/gotoPageB parameter=/PageB.jsp type=org.apache.struts.actions.ForwardAction /> Next, modify the global forward itself to point to the above ActionMapping. <global-forwards> <forward name=pageBForward path=/gotoPageB.do /> </global-forwards> When used in this manner, the <html:link> gets transformed into the following HTML Link. <a href=App1/gotoPageB.do>Go to Page B</a>
30

There you go! The generated HTML is not displaying the JSP name anymore. From a design perspective this seems to be the best way of using the <html:link> tag since the link is completely decoupled from the associated ActionMapping, thanks to the global-forward. The <html:link> points to the global-forward and the global-forward points to the ForwardAction. The extra level of indirection, although looks confusing in the beginning, is a good design decision due to the following reason: As is true with any application, requirements change and it might just become necessary to do some processing during the navigation from PageA to PageB. A conversion from ForwardAction to a custom Action will be easier to manage with the extra level of indirection. Using ForwardAction for Integration In general, the ForwardActions parameter attribute specifies the resource to be forwarded to. It can be the physical page like PageB.jsp or it can be a URL pattern handled by another controller, maybe somewhere outside Struts. For instance, consider the following ForwardAction. <action path=/gotoPageB parameter=/xoom/AppB type=org.apache.struts.actions.ForwardAction /> In the snippet above, the value of the parameter is not a physical page. It is a logical resource that might be mapped to another Servlet totally outside the control of Struts. Yet from PageAs perspective, you are still dealing with a Struts URL. This is the second use of ForwardAction. You can integrate Struts applications transparently with already existing non-Struts applications. NOTE: Even with the ForwardAction, you cannot prevent a nosy user from accessing the JSP directly. See the section Protecting JSPs from direct access for techniques to protect your JSPs from direct access. ForwardAction Hands-on Think of index.jsp as PageA and CustomerDetails.jsp as PageB. The <html:link> in index.jsp will look as follows: <html:link forward=CustomerDetailsPage>Customer Form</a> The following Global Forward and ForwardAction are added to the Struts Config file. <global-forwards> .. <forward name="CustomerDetailsPage" path="/gotoCustomerDetails.do" /> </global-forwards> <action-mappings> .. <action path=/gotoCustomerDetails parameter=/CustomerDetails.jsp type=org.apache.struts.actions.ForwardAction /> </action-mappings>

DynaActionForm Bean
DynaActionForm Beans are the extension of Form Beans that allows you to specify the form properties inside the struts configuration file instead of creating a seperate concreate class. It will become tedious to create a seperate form bean for each action class. Using DynaActionForm we can easily create Form Bean in struts-config.xml file. The struts-config.xml file entry for the DyanActionForm Bean is shown below.
31

<form-beans> <form-bean name="LoginForm" type="org.apache.struts.action.DynaActionForm"> <form-property name="userName" type="java.lang.String" /> <form-property name="password" type="java.lang.String" /> </form-bean> </form-beans>

The type attribute points to org.apache.struts.action.DynaActionForm and the <form-property> tag is used to define all the form variables. The <form-property> tag has the following three attributes.
name - The unique name of the property. initial - The default value of the property. type - Defines the Java type of the property. The available types are java.math.BigDecimal java.math.BigInteger boolean and java.lang.Boolean byte and java.lang.Byte char and java.lang.Character java.lang.Class double and java.lang.Double float and java.lang.Float int and java.lang.Integer long and java.lang.Long short and java.lang.Short java.lang.String java.sql.Date java.sql.Time java.sql.Timestamp

Now we will see how to access the DyanActionForm in the action class.
public class LoginAction extends org.apache.struts.action.Action { public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response)throws Exception { DynaActionForm loginForm = (DynaActionForm) form; String userName = loginForm.get("userName").toString(); String password = loginForm.get("password").toString(); if(userName.equals(password)) { return mapping.findForward("success"); } else { return mapping.findForward("failure"); } } }

We need to typecast the form object to DynaActionForm object in the execute method of the action class. After that we can access the Form Bean properties. We will consider a simple login application
32

for our example. Here we will check the user name and password, if they are equal then we will forward the user to the success page, else we will forward the user to the failure page. Now we will run the Login application. Lets enter the user name as "Eswar" and the password as "Eswar" and click the Login button.

You can download the source code of the DynaActionForm example by clicking on the Download link below.
With dynamic form bean, I can change name of the variables inside config file but need not change getters setters. Getters setters are dynamically generated at runtime. Actually they are not generated as getters and setters, but a sort of map is created using key-value pair kind of. Coz getters and setters has to be in class n classes increases dependency. So map is better. In normal case, getters n setters exist at compile time. But for dyna action form, they are created as per jsp form inputs at runtime. Disadvantage is, it wnt be object oriented approach.

33

With dyna action form, it is possible to persist a list of values. It is not possible for normal ActionForm. So it is an advantage of DynaActionForm. Disadvantage is, here no form validation possible. This form has no validate method because we are using readymade class as a type for form bean. So it is very less preferable and very less used. We need to do validation in business logic itself.

This is huge. Read: http://www.roseindia.net/struts/struts_validator_framework.shtml and further pages. For brief intro:

34

Struts Validator Framework


The Validator Framework in Struts consist of two XML configuration files. The first one is the validator-rules.xml file which contains the default Struts pluggable validator definitions. You can add new validation rules by adding an entry in this file. The second one is the validation.xml file which contain details regarding the validation routines that are applied to the different Form Beans. These two configuration file should be place somewhere inside the /WEB-INF folder of the application. To use the validator pluggin the first step is to add it in the Struts configuration files as shown below. The pluggin should be added after any message resource elements in the struts configuration file as shown below.
<plug-in className="org.apache.struts.validator.ValidatorPlugIn"> <set-property property="pathnames" value="/WEB-INF/validatorrules.xml,/WEB-INF/validation.xml"/> </plug-in>

Lets see a simple login example using the DynaValidatorForm. First we need to create a From Bean that extends org.apache.struts.validator. DynaValidatorForm.
<form-beans> <form-bean name="LoginForm" type="org.apache.struts.validator.DynaValidatorForm"> <form-property name="userName" type="java.lang.String" /> <form-property name="password" type="java.lang.String" /> </form-bean> </form-beans>

Next step is to add validations to the form fields in the validation.xml file. Our Form name is "LoginForm" and field names are "userName" and "password". The validation.xml file contains the following code.
<form-validation> <formset> <form name="LoginForm"> <field property="userName" depends="required"> <arg key="LoginForm.userName"/> </field> <field property="password" depends="required,minlength"> <arg0 key="LoginForm.password"/> <arg1 key="${var:minlength}" name="minlength" resource="false"/><br> <var> <var-name>minlength</var-name> <var-value>6</var-value> </var> </field> </form> </formset> </form-validation>

Each <formset> tag can contain multiple <form> tags. Specify the form name that you want to associate with the Validation Framework as the value of the name attribute of the form tag. Name of the form specified here should be same as the one specified in the struts-config.xml file.

35

Now you can associate each properties of the form bean with one or more predefined validation rules . The depends attribute of the field tag takes comma-delimited list of rules to associate with each property. The userName property is associated with the "required" rule which means that the value cannot be empty. The error message to be displayed when a particular rule is not satisfied is specified in the ApplicationResource.properties file.
1.LoginForm.userName = User Name 2.errors.required={0} is required.

We pass the key value as "LoginForm.userName" in the arg tag. The value for this key will be fetched from the ApplicationResource.properties file and this value will be used to generate the errors.required message. In our case if the userName is not entered, the error message will be displayed as "User Name is requierd." The only entry we need to make in the ApplicationResource.properties file is "LoginForm.userName = User Name", the other entry is already provided by the framework. Inorder to associate more than one validation rule to the property we can specify a comma-delimited list of values. The first rule in the list will be checked first and then the next rule and so on. Now lets see how the validation works. Click the Login button without entering any values, the following error messages are displayed to the user.

Enter the user name as "Eswar" and password as "ab" and click the Login button, the following error message is displayed to the user.

36

You can download the source code of the Struts Validation Framework example by clicking on the Download link below.

Tiles
Tiles is used to create reusable presentation components. With Tiles, we first define a base layout with different sections after that we define which jsp page should fill in the corresponding regions in

37

an exteranl configuration file. The same layout can be reused any number of times by specifying different jsp pages. To use Tiles in the Struts application, we need to add the following <plug-in> definition to the strutsconfig.xml file.
<plug-in className="org.apache.struts.tiles.TilesPlugin" > <set-property property="definitions-config" value="/WEB-INF/tiles-defs.xml" /> <set-property property="moduleAware" value="true" /> </plug-in>

There are two ways in which you can specify the Tiles definition and their attributes. One is using JSP Tile Definition and the other way is using XML Tile Definition. All JSP pages that uses Tiles should have the following taglib extension.
<%@taglib uri="/WEB-INF/struts-tiles.tld" prefix="tiles" %>

Lets first design the base layout page using tiles. The base layout page is a normal jsp page, which defines different sections. A region is defined using the <tiles:insert> tag. The attribute value hold the name of the region.

The layout shown above can be created using the following code.
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title><tiles:getAsString name="title" ignore="true" /></title> </head> <body> <table border="1" cellpadding="2" cellspacing="2" align="center"> <tr> <td height="20%" colspan="2"> <tiles:insert attribute="header" ignore="true" /> </td> </tr> <tr> <td width="20%" height="250"> <tiles:insert attribute="menu" /> </td> <td>

38

<tiles:insert attribute="body" /> </td> </tr> <tr> <td height="20%" colspan="2"> <tiles:insert attribute="footer" /> </td> </tr> </table> </body> </html>

If the ignore attribute is set to true, then that region is optional. Even if the attribute is not specified the code will work fine. To create our home page we need to insert title, header, menu, body and footer jsp pages. The following code is used to create our home page.
<%@taglib uri="/WEB-INF/struts-tiles.tld" prefix="tiles" %> <tiles:insert page="/baseLayout.jsp" flush="true"> <tiles:put name="title" value="Tiles Example" /> <tiles:put name="header" value="/header.jsp" /> <tiles:put name="menu" value="/menu.jsp" /> <tiles:put name="body" value="/body.jsp" /> <tiles:put name="footer" value="/footer.jsp" /> </tiles:insert>

The name attribute of the put tag specifies the region in the baseLayout in which the corresponding page specified by the value attribute should be displayed. In our example the header region is occupied by the header.jsp page, the menu part is occupied by the menu.jsp page, the body part by the body.jsp page and the footer by the footer.jsp page. The only section that will be changing when the user request a different page is the body part. On executing the application the following home page is displayed. The table border is set to 1 inorder to give a clear seperation between the regions.

39

On clicking the links in the left menu, only the body part of the page should change. So instead of forwarding each link to a jsp page, we forward it to a Tile definition. tiles-defs.xml file contains all the Tile definitions. A Tile definition can be added in the following way.
<definition name="baseLayout" path="/baseLayout.jsp"> <put name="title" value="Tiles Example" /> <put name="header" value="/header.jsp" /> <put name="menu" value="/menu.jsp" /> <put name="body" value="/body.jsp" /> <put name="footer" value="/footer.jsp" /> </definition>

The name of the Tile definition is "baseLayout" and it contains one jsp page for each region. Since the title region is specified using getAsString tag, we provide a String variable instead of a jsp page. When an action is forwarded to the Tile definition baseLayout, then the baseLayout.jsp page will be displayed with corresponding jsp pages in the Tile definition The powerful and useful feature of the Tile definition is the ability to extend an other Tile definition. In our example only the tilte and the body regions are going to change for each link in the left menu. So it is a good practice to create an new Tile definition which extends the baseLayout, with different values for title and body regions.
<definition name="friends" extends="baseLayout"> <put name="title" value="Friends" /> <put name="body" value="/friends.jsp" /> </definition>

40

<definition name="office" extends="baseLayout"> <put name="title" value="The Office" /> <put name="body" value="/office.jsp" /> </definition>

The menu.jsp contains the following code.


<html> <body> <a href="Link.do?method=friends" >Friends</a><br> <a href="Link.do?method=office" >The Office</a> </body> </html>

On clicking each link a corresponding method in the LinkAction class is invoked. The LinkAction class extends the DispatchAction and it contains the following methods.
public class LinkAction extends DispatchAction { public ActionForward friends(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { return mapping.findForward("friends"); } public ActionForward office(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { return mapping.findForward("office"); } }

Add the following action forward entries in the struts-config.xml file.


<action-mappings> <action path="/Link" parameter="method" type="com.vaannila.LinkAction"> <forward name="friends" path="friends"/> <forward name="office" path="office"/> </action> </action-mappings>

The path attribute hold the value of the Tile definition to forward. When the path value is "friends" the baseLayout.jsp page is displayed with the tilte as Friends and friends.jsp as the body.

41

When the path value is "office" the baseLayout.jsp page is displayed with the tilte as The Office and office.jsp as the body.

42

Plugin with spring n hiberanate strut uses 2 design patterns: front end controller pattern, MVC2 model architecure.

Packages provided by struts: There are eight packages provided by struts: 1. org.apache.struts.action.*: 43

classes provided: 1)Action 2)ActionServlet 3)ActionError 4)ActionMessage 5)ActionForm 6)DianaActionForm 7)DispatchAction 8)ForwardAction

Action path=a Name=bean1 Type=abc Action path=b Name=bean2 Type=abc How to implement action class abc for it? Abc extends Action { Execute() { If( checking path here. How?) { Bean1 bean = (Bean1) form; } Else { Bean2 bean = (Bean2) form; } } } MVC1 vs MVC2 Request Processor

44

Você também pode gostar