MELJUN CORTES Jedi course notes web programming-lesson7-mvc i intro and struts


Published on

MELJUN CORTES Jedi course notes web programming-lesson7-mvc i intro and struts

Published in: Technology
  • Be the first to comment

  • Be the first to like this

No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide

MELJUN CORTES Jedi course notes web programming-lesson7-mvc i intro and struts

  1. 1. MVC I – Introduction to MVC and the Struts Framework Introduction to Model-View-Controller ArchitectureThe Model-View-Controller (MVC) architecture is an architectural pattern that is provento be effective in development projects. It does so by defining three separatecomponents - the Model, View and Controller – and partitioning the project into thesecomponents. MotivationIn any application, the part of the code most likely to change is the portion regarding theuser interface. The user interface is the aspect most visible to the user and the aspect heinteracts with, making it the most likely target of change requests or usabilityimprovements.Having your business logic tightly coupled with your user interface makes the process ofmaking changes to the interface more complex and error-prone. Changes to one parthave the potential to cascade into the rest of the application. SolutionThe MVC pattern provides a solution to these problem by partitioning the application intoModel, View, and Controller components, decoupling them from each other whileproviding a set of recommendations about their interactions.
  2. 2. - Encapsulates application state - Responds to state queries - Exposes application functionality - Notifies views of changes - Renders the models - Defines application behavior - Requests updates from models - Maps user actions to model updates - Sends user gestures to controller - Selects view for response - Allows controller to select view - One for each functionality Figure 1: The MVC PatternThe diagram above shows the three components defined by the MVC pattern as well astheir proscribed interactions. Lets go over them bit by bit. MODELThe MVC pattern defines a layer called the Model which represents the data used by theapplication as well as the business operations associated with them. By defining this as aseparate layer, such details as data retrieval, persistence, and manipulation areabstracted from the rest of the application.There are several benefits to this kind of approach. First, this makes sure that data anddata operation details can be found in a well-defined area (the model) instead of beingscattered across the whole application. This proves to be beneficial during themaintenance phase of the application. Second, by having the data details totallyseparate from any interface implementation, the model components can be more easilyreused in other applications needing similar functionality. VIEWThis layer comprises all the details of user interface implementation. Here, graphicalcomponents provide representations of internal application state and provides users withways to interact with the application. No other layer interacts with the user, only theView.Having a separate View layer provides several benefits. For one, it is easier to includethe presence of a separate design group into the development team. This design groupcan wholly concentrate on style, look & feel, etc. of the application without having to
  3. 3. worry about other details.Also, having a separate View layer makes it possible to provide for multiple interfaces tothe application. Since core application functionality is located somewhere else (in theModel), multiple interfaces can be created (Swing-based, web-based, console-based), allof them having a different look and feel but all of them simply querying the Modelcomponents for its functionality. CONTROLLERFinally, the MVC architecture calls for a Controller component layer. This layer containsdetails about program flow / screen transition, and is also responsible for capturingevents generated by the user from the View layer and possibly updating the Modelcomponents using user-provided data.There are several benefits in having a separate controller layer. One, by having aseparate application component to contain the details of screen transition, viewcomponents can be designed such that they do not need to be aware of each other. Thismakes it easier to have multiple interface development teams working independent ofeach other simultaneously. The interactions between the view components areabstracted into the controller.Second, by having a separate layer that updates the model components, those detailsare removed from the presentation layer. The presentation layer can devote itself to itsprimary purpose of presenting data to the user. The details of how the users datachange the state of the application is hidden within the Controller component. Thisprovides for a clean separation between presentation logic and business logic.It is not to say that the MVC pattern comes with all benefits without any side-effects.Partitioning the application into three separate components results to an increase incomplexity. For small applications which do not benefit from loose coupling of the Model,this may be a stumbling block in the use of this pattern. However, it is probably best tokeep in mind that applications often start out small and grow into complex systems, soloose coupling should always be aimed for. MVC Architecture for the Web: The Model 2 ArchitectureThe MVC Architecture was slightly modified and adapted for the use of web applications.The resulting architecture was then called the Model 2 architecture.Model 2 applications typically have the following: • A servlet controller that provides a single point of access to the rest of the application. This controller is responsible for providing central management of application flow and such services as security handling and user management. This type of controller is often referred to as the Front Controller. • The controller servlet typically uses XML configurations to determine application flow and command processing. It also commonly makes use of helper components that serve as Command objects. This means that these helper
  4. 4. components are associated with user actions and are created/called on to handle those actions as they occur, calling on Model components as necessary. This serves to decouple the controller servlet from the Model.Using such an architecture has been proven to be advantageous for our application.Implementing it can be made easier though the use of existing third-party frameworks.These frameworks provide a lot of the plumbing details (request forwarding, reading ofconfiguration files, etc.) so that we can concentrate on more important matters. Theyalso provide additional useful functionality.For this course, we will be dealing with two popular frameworks: Struts andJavaServerFaces(JSF). The Struts discussion will be tackled here and in the next chapter.JSF will be discussed after that. STRUTSStruts is an open-source framework provided and managed by the Apache SoftwareFoundation. Below is a representation of how Struts manages the Model 2 Architecture: Figure 2: Struts and the Model 2 ArchitectureLet us take a look at the objects provided for us by the framework for each of the Model,View, and Controller components.
  5. 5. Controller . ActionServletAt the center of the controller implementation of the Struts framework is theActionServlet. This serves as a Front Controller servlet and provides a single point ofaccess to the rest of the web application. It also contains the logic behind client requesthandling – it looks through the clients HTTP request, and based on that request eitherforwards the user directly to a Web page or dispatches the request to handler objectscalled Actions which will then be responsible for determining the outcome of theresponse.The ActionServlet knows all these details – which Action to call to handle which request,which view component should next be called – by reading this information from an XMLconfiguration file, usually named struts-config.xml.This servlet is provided to us ready-for-use by the Struts framework. All that isnecessary to include it in our application, is to configure it properly in our appsdeployment descriptor.Below is a web.xml snippet showing how to configure the ActionServlet for use:...<servlet><servlet-name>action</servlet-name><servlet-class>org.apache.struts.action.ActionServlet</servlet-class><init-param><param-name>application</param-name><param-value>ApplicationResources</param-value></init-param><init-param><param-name>config</param-name><param-value>/WEB-INF/struts-config.xml</param-value></init-param></servlet>...<servlet-mapping><servlet-name>action</servlet-name><url-pattern>*.do</url-pattern></servlet-mapping> . ActionAs we have mentioned before, some client requests are delegated to instances of Actionobjects by our front controller servlet. All Action objects define a method calledexecute(), and it is this method that is called by the ActionServlet to handle the request.The Struts framework only provides developers with the base Action class. To include
  6. 6. Action objects as request handlers in their application, developers must subclass thisbase class and provide an implementation for the execute method.A common activity in web applications is user log-in. Shown below is an implementationof a LoginAction class that can possibly be used to handle such requests.import org.apache.struts.action.*public class LoginAction extends Action {public ActionForward execute(ActionMapping mapping,ActionForm form,HttpServletRequest request,HttpServletResponse response)throws Exception {// cast the generic ActionForm object// to the specific ActionForm implementation// configured for this ActionLoginForm loginForm = (LoginForm)form;// Retrieve the user -specified data.String loginName = form.getLoginName();String password = form.getPassword();// Create the business object that will handle the request.UserService service = new UserService();user = service.login(loginName, password);// if user does not exist – login failed – forward// the user to an error pageif (user == null) {return mapping.findForward("failure");}// Store the result into session scope for use in the rest of the// application, using a predefined constantHttpSession session = request.getSession();session.setAttribute(ApplicationConstants.USER_OBJECT, user);// user has successfully logged in. Forward the user to the// rest of the application.return mapping.findForward("success");}}Take note that the above implementation makes use of a business object, calledUserService, to determine user authentication and does not directly provide its ownimplementation in its execute method. Action instances should be developed this way –core functionality should be redelegated to business objects (which can be considered
  7. 7. part of the Model), not implemented within the Action itself. The only activities that anAction should perform are: • Retrieval of user-provided information from the associated ActionForm bean (more on ActionForms later). • Translating form data into parameters required by the business objects that implement the functionality. • Retrieve the result from the operation of the business object and determine the next view the user should be forwarded to. • Optionally store the data results of the business operation into the session or request objects for use by the rest of the application.Another thing to keep in mind when coding instances of Action objects is that theframework will only instantiate a single copy of the object and use it to facilitate allrequests. This means that we must always code the Action to be thread-safe, and makesure that we always use local variables not instance variables.Action instances are able to instruct the ActionServlet which view component to delegatethe response to by returning instances of ActionForward objects. Actions have accessto these ActionForward objects through the use of an ActionMapping object whichencapsulates the data of logical path mappings for each Action. These mappings are readfrom the configuration file by the ActionServlet, which is then responsible for passing thenecessary ActionMapping to the Action. So, to instruct the ActionServlet to pass controlto a logical mapping named success, our Action performed the following statement:return mapping.findForward("success"); . ActionFormThe Struts framework provides for a class called an ActionForm. Instances of this classare used to facilitate the retrieval of data from user-populated forms to the Actioninstances handling those form events.Each instance of an ActionForm represents a form or a series of forms. They defineproperties that correspond to the form elements of the form(s) they represent, andexpose them using publicly accessible setters and getters. Actions which then need thedata from the forms simply call on the ActionForm instances getter methods.Struts provides the base class definition; developers have the responsibility of creatingtheir own implementations.Listed below is the ActionForm used in the example above:
  8. 8. import org.apache.struts.action.*;public class LoginForm extends ActionForm {private String loginName;private String password;public String getLoginName() {return loginName;}public void setLoginName(String loginName) {this.loginName = loginName;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}}Some things to remember when coding ActionForms: • Define properties (with associated get and set methods) for each element in the form it will represent. • Do NOT place any business logic in the ActionForm. They are meant merely to transfer data between View and Controller components and as such is not suited for business logic. • Optionally, include a validate method to perform validation of data before control even passes to the Action. (More on validation later) . struts-config.xmlThis file serves as the configuration file for the components of the Struts framework.Here, we are able to define which action is called for which request, which formcomponent to use for each action, and the mapping of logical names to actual paths,among other things. Provided below is a copy of the struts-config.xml used for the aboveexample:
  9. 9. <?xml version=”1.0”?><!DOCTYPE struts-config PUBLIC “-//Apache Software Foundation//DTD StrutsConfiguration 1.1//EN” “” ><struts-config><form-beans><form-bean name=”loginForm” type=”login.LoginForm”/></form-beans><action-mappings><action name=”loginForm”path=”/login”scope=”request”type=”login.LoginAction”><forward name=”success” path=”/success.jsp”/><forward name=”failure” path=”/failure.jsp”/></action></action-mappings></struts-config>Lets go through each of these elements.<!DOCTYPE ...>This element defines the XML file as a configuration file for use by the Struts framework.Excluding this line, or mistyping it, will result in errors when the application loads.<struts-config>The root element of the configuration file. All other elements are child nodes of thiselement.<form-beans>This element marks the start and end of definitions of ActionForm instances. <form-bean> elements MUST be located as child nodes of this element.<form-bean>Defines an ActionForm instance that can be used by the application. It has twoattributes: • name – the logical name to be associated with the ActionForm class • type – the fully qualified class name of the ActionForm class.<action-mappings>This element marks the start and end definitions of actions and their mappings. All<action> elements MUST be located as child nodes of this element.<action>Defines an instance of an Action object for use by the application. Most action elementswill implement the following attributes: • path – the context-relative path to be used by this Action. Any requests to this path results in the defined Action being called. • type – the fully qualified class name of the Action class. • name – the name of the <form-bean> element to use with this action. • scope – the context scope where our ActionForm can be accessed. This dictates
  10. 10. where the ActionServlet will store the instance of the ActionForm.<forward>Actions can have zero to many forward elements. This element defines a logical mappingbetween a name and an actual path in our application.It has the following attributes: • name – the logical name of the forward which can be used by the Action instance. • path – the path to the view component associated with this forward. . Summary of things to do for the controller layer:For one-time setup: • Configure the ActionServlet in your apps deployment descriptor.For each form handler to be added to the application: • Create an ActionForm object that will represent all data gathered from the form. • Create an Action object which, in its execute method, defines how the form will be handled. • Create a configuration entry for the ActionForm object in struts-config.xml, inside the <form-beans> section. • Create a configuration entry for the Action object in struts-config.xml, inside the <action-mappings section. • Configure all forwards used by the Action, by placing <forward> elements inside the body of the <action> definition. ModelThe Struts framework does not explicitly provide for any components within the Model.Which objects to use as Model components are left for the developer to decide, thoughusually they are JavaBeans or, on occassion, Enterprise JavaBeans (EJBs). ViewStruts can make use of any presentation layer technology, though in most cases JSPsand/or HTML is used. What Struts provides for this layer though, is a set of tag librariesthat allows us to make use of Struts features for automatic form population andvalidation. . struts-htmlStruts provides a tag library called struts-html that mimics a lot of functionality we havecome to expect from standard HTML tags but also provides extra features.This tag library is most often used when creating forms to be used for the application.Take the example of the form below.
  11. 11. <%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %><html><head><title>Login Page</title></head><body><h1> Login Page </h1><br/><html:form action="/login">User Name : <html:text property="loginName"/> <br/>Password : <html:password property="password"/> <br/><html:submit></html:form>This was the form used in our previous example. Notice how standard HTML elementslike <form>, <input type="text">, <input type="password">, and <inputtype="submit"> were replaced by tags from the struts-html library. Let us go throughthese tags.<html:form>The <html:form> tag renders an HTML form. Each form tag is associated with an actionmapping defined by the action attribute. The value inside this action attribute specifiesthe path of the action mapping.Looking back at the configuration file that we used for the previous example,...<action name=”loginForm”path=”/login”scope=”request”type=”login.LoginAction”>...we can see that the value in the path attribute defined in the configuration file matchesthat of the value in the action attribute in the <html:form> tag. This indicates that thisform, when submitted, will be presented to the LoginAction for handling.One of the conditions for a valid html:form tag is that each of the fields it contains mustbe defined in the ActionForm specified for the particular action mapping.Other possible attributes: • method – can either be POST or GET. Defines the HTTP method to be used when submitting the form<html:text>This tag renders a standard HTML text input field. The property attribute specifies whichproperty in the associated ActionForm is it bound to. Since the value of the propertyattribute in the example above is "loginName", this text field is bound to the loginNameproperty of the LoginForm.
  12. 12. Other attributes available for this tag: • size – defines the size of the text field to be displayed • maxlength – defines the maximum length of the value user can input<html:password>This tag renders a standard HTML password field. The property attribute specifies whichproperty in the associated ActionForm is it bound to. In our example, this field is boundto the password property of LoginForm.In our earlier discussions of the html:text and html:password fields, it was mentionedthat they are bound to properties of the ActionForm instance associated with the form.What this means in practical terms is that the values entered by the user into thesefields will automatically be set into the bound properties in the ActionForm object.Moreover, if there were previous existing values in the ActionForm object (the form hasalready been accessed before), the form fields will automatically be prepopulated withvalues from the ActionForm object.Other tags in the struts-html tag library:<html:hidden>Renders an HTML hidden form fieldSample usage:<html:hidden property="hiddenField"/><html:radio>Renders a HTML radio check boxSample usage:<html:radio property="radioField"/><html:select>, <html:option>html:select is used to render a drop-down list box. The options for this list box arespecified using html:option tags.Sample usage:<html:form action="/sampleFormAction"><html:select property="selectField" size="5"><html:option value="0 value">0 Label</html:option><html:option value="1 value">1 Label</html:option><html:option value="2 value">2 Label</html:option></html:select></html:form>
  13. 13. The above example would generate a list box 5 items long (size=5). Notice that the bodyof the html:option tag acts as the label for the list item, while the value of the valueattribute specifies the value that will be given to the Action on form submission.<html:checkbox>, <html:textarea>Are used to render checkbox field and textarea field, respectively.As we have seen in the previous chapter (see Advanced JSP), there are things we needto do before we are able to make use of custom tag libraries in our application.First, we need to place the JAR file implementing the actual tag functionality inside theWEB-INF/lib directory of our application. . Summary of things to do for the View layer:For one-time setup: • Configure the tag libraries for use in the applications deployment descriptor. • Place the JAR files containing the implementation for the tag libraries in the appliactions WEB-INF/lib directory.For each form to be created: • Add a taglib directive to the JSP page to enable use of the struts-html tag library. • In place of the standard <form> tag, use <html:form>. Specify in its action attribute the path of the Action that will handle the form. • In place of the HTML field tags (<input type="text">, etc), make use of the tags included in the struts-html tag library that perform the same functionality (<html:text>, etc). • Make sure that all input fields present in the form definition are present as properties in the ActionForm object associated with this request. It is NOT necessary that all properties in the object be displayed as fields, but it is required that all fields are present as properties. • Remember to close the <html:form> tag. Looking at Things as a WholeTo gain an understanding of how the Struts framework functions as a whole, lets take inthe scenario of the example given above: of a user logging in.Before the user even enters the site, the ActionServlet takes in the configuration file andreads the details. So, when the user accesses the login form, the framework alreadyknows the associated ActionForm that will store its details and the Action that will handleform submission.When the login page loads, the struts-html tags that we have used attempt to render theHTML fields. If the ActionForm for this form does not exist, the page will not display. Ifthere are more fields in the form than there are properties in the ActionForm to backthem up, the page will also not display. If the ActionForm does exist, the tags will see ifthere were any previous values stored in the ActionForm. If there are, the form fields areprepopulated with data. If not, the form fields are left empty and the user will see ablank form.
  14. 14. When the form is submitted, the values in the form fields are automatically set into theActionForm object by the Struts Framework. This object is then passed into theappropriate Action handler, along with the ActionMapping object that reflects mappingdetails as specified in the configuration file.The Action object performs its handling, then tells the ActionServlet where to go next byspecifying one of the forwards configured in the mapping. The ActionServlet thenredirects the user to that page.EXERCISESFor this exercise, refer to the Entity Relationship Diagram. Further questions can beaddressed to the instructor.This is a hands-on exercise that will be accomplished in groups. The instructor will giveinstructions on how many members there will be per group.Create a Struts-based web applicationBrief DescriptionThe application is used to manage and administer a site that allows downloads ofeducational materials. There are two levels of users for this application: an ordinaryuser and an administrator.The activities available for an administrator are:a) Download material management -> includes addition, modfication, and deletion.b) User management -> includes addition, update, and deletion of users.c) User activity reporting -> administrators have access to a page that can show themthe list of users ordered in descending order according to the total amount ofdownloads. Clicking on a user in this list will show them a detailed history of the usersdownloads.The activities available for a user are:a) Browsing of available download materials.b) Selecting a material for download -> your implementation does NOT actually have toprovide a material for download. What your application should have is a link which,when clicked, will simulate a download.Both users will have a common starting point for the application: a login page that willtake in a login name and password. The application will then have to determine theusers authentication level based on that information and redirect them to theappropriate content page.Screen DescriptionsAside from the login page, which can be implemented simply as a form with two inputelements and a submit button, there are several other screens that make up thisapplication.For the administrators, the screen flow can be described by the following mini-diagram:
  15. 15. Login Page ->Main Content Page - presents three links, each corresponding to one of the majoractivity groups allowed for an admin. -> Download Material Management Page - presents the admin with an option toeither add, update, or delete a download material. -> Add Download Material Page - contains a form with the necessary inputelements to insert a new download material. -> Update Download Material Page - contains a form with the necessary inputelements to update an existing download material. -> Delete Download Material Page - contains a form with a text field whichwill take in a material id as input. -> User Management Page - presents admin with an option to either add, update,or delete a download material. -> Add User Page - contains a form with necessary input elements to add anew user. -> Update User Page - contains a form with the necessary input elements toupdate an existing user. -> Delete User Page - contains a form with a text field which will take in auserID as input. -> User Activity Page - list of users ordered in descending order according to thetotal amount of downloads. Clicking on a user in this list will bring the administrator to adetail page. -> User Download Detail Page - presents a detailed download history for aparticular user.Admin Error Page -- page to go to in case of any errors within the application. Showsthe nature of the error to the user.The user side is a bit more simple:Login Page -> Browse Download Material List - the list contains only the name of the download.Clicking on a name brings the user to a detail page. -> Download Material Detail Page - contains complete details about a selecteddownload item. This page contains a link that can be used to "download" the material.Error Page -- page to go to in case of errors.