struts notes updated in june2011

Upload: anup-kulkarni

Post on 16-Jul-2015

50 views

Category:

Documents


0 download

TRANSCRIPT

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

Struts 1.3What 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.xml1

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 ActionServlet org.apache.struts.action.ActionServlet config /WEB-INF/struts-config_1.xml,/WEBINF/Abc.xml ActionServlet *.do So in all ActionServlet is a controller which is initialized on reading of web.xml.

2

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. This section contains your form bean definitions. Form beans are descriptors that are used to create ActionForm instances at runtime. You use a 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.

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 the3

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: tag contains 0 to multiple action tags.

tag attributes:

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

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.

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 dividedin multiple files too.) Root tag: (like tag in DD)1) The DTD to validate and interpret the tags in configuration file. 2) 6

Other attributes explained in table above. 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 tag. This tag is child tag of tag. They can be multiple per 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

7

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 adestination 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) 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) 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 tag is used. Its value should be identical to name of appropriate . Now we use form.getVariableName() instead of request.getParameter(). So approach is more Object oriented now. Struts application:

8

Libraries:

Web.xml: Struts_app

9

ActionServlet org.apache.struts.action.ActionServlet config /WEB-INF/Struts-Config.xml ActionServlet *.do

Struts-config.xml

LoginPage.jsp Insert title here Username: Password:

LoginForm.javapackage 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.javapackage 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 Insert title here Hello there.

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 tag is used.