MELJUN_CORTES_JEDI Course Notes Web Programming Lesson8 Advanced Struts

Embed Size (px)

Citation preview

  • 8/3/2019 MELJUN_CORTES_JEDI Course Notes Web Programming Lesson8 Advanced Struts

    1/16

    Advanced Struts Topics

    In the previous chapter, we were able to tackle the basics of Struts. We have learnedhow to include the Struts framework in our application by configuring the provided

    ActionServlet to handle our requests. Also, we have learned how to create instances ofAction classes that serve as action handlers for form submissions and other userrequests. We have seen how to create ActionForm classes that provide an easy way oftransferring data from our forms into the designated ActionHandlers. Finally, we haveseen how to use the included tag libraries to help tie in the HTML forms in our JSP pagesmore firmly into the framework.

    In this chapter, we will cover some advanced techniques and features of the Struts

    framework. First, we will see how we can make use of DynaActionForms to minimize thenumber of classes we need to do for the framework. Next, we'll look at how the Validator

    framework eases the task of providing server-side validation into our application. Andfinally, we'll be introduced to the Tiles framework, with which we can compartmentalizeour presentation layer, as well as providing access to a templating mechanism for ourpages.

    DynaActionForms

    Especially in large applications, the number of classes that needs to be created and

    maintained can become staggeringly high. Struts support classes can contribute a lot tothis number, especially with regards to its ActionForms, which require a solid

    implementation for nearly all the forms in an application. A lot of developers chafedunder this restriction since ActionForms are mostly simple JavaBeans with get and setmethods for each of the form fields it needs to represent.

    Struts came up with a solution in its 1.1 version release, called DynaActionForms.DynaActionForms behave exactly like ActionForms, in that an instance of it can be

    obtained and its methods called upon by the Action handlers that need its data. Themain difference is, each DynaActionForm is not defined or declared as a separate class.

    A DynaActionForm is simply configured from within the struts-config.xml file.

    Below is an example of how to configure and declare DynaActionForms. We have madeuse of our example in the previous chapter, creating here an ActionForm that will handle

    the data required for logging in.

  • 8/3/2019 MELJUN_CORTES_JEDI Course Notes Web Programming Lesson8 Advanced Struts

    2/16

    As we can see, creating a DynaActionForm is very simple. In some cases declaring aDynaActionForm from within the configuration file is simpler and faster compared towriting an actual ActionForm instance. We no longer have to list down all of the formproperties and create get and set methods for each of them. With DynaActionForms, we

    simply declare the property name and type. It is then the framework's responsibility toprovide a working instance based on this information.

    Providing this configuration information is the only thing necessary to make use of

    DynaActionForms. There are no changes that need to be made to any of our Actioninstances. As far as they are concerned, they still have a valid ActionForm instance that

    they can retrieve data from.

    The following are the Java types supported by DynaActionForm:

    java.lang.BigDecimal java.lang.BigInteger

    boolean and java.lang.Boolean char and java.lang.Character

    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.lang.Date java.lang.Time

    java.sql.TimeStamp

  • 8/3/2019 MELJUN_CORTES_JEDI Course Notes Web Programming Lesson8 Advanced Struts

    3/16

    While using DynaActionForms may be more convenient, they are not always the bestsolution. There are still cases where using ActionForms are more appropriate.

    DynaActionForms only support a limited set of Java types. If our form needs tostore information expressed as a data type other than those supported, then

    ordinary ActionForms are still the way to go. An example of this would be if wewere to use custom Java objects as form properties.

    DynaActionForms do not support the concept of inheritance. There is no way tocreate a base definition for a form that can be extended later on to provide forspecifics.

    Validators

    Validation is an activity that should be performed for all cases of data input. Byvalidation, we mean the checking of the correctness of the format and content of user-

    given values. Users, after all, do not always enter correct input: letters might be enteredinto a numeric only field and vice-versa; a field that requires 3 digits is given only 2, andso on. It is the application's responsibility to be aware of and handle such input errorsaside from any errors resulting from processing of business logic (password does notmatch for given login, etc.).

    Struts alleviates the developer's burden in performing this validation by providing avalidation framework called the Validator Framework. Usage of this framework provides

    a couple of benefits:

    The framework provides several pre-defined validation rules. There arecommon set of checks performed in any number of applications such as format

    checking, length checking, checking for existence, etc. The framework providesthe components necessary such that developers no longer need to create codethat will perform these types of validation. Generally, the components theframework provides are enough for most applications, though custom validatorscan also be created.

    It eliminates redundancy in validation code. The framework separates the

    components performing the validation from the components needing validation.Instead of having multiple components incorporating the same validation code,

    the functionality can be externalized into a separate validation component thatcan be reused throughout the whole application.

    It provides a single point of maintenance. Developers no longer need to goall over their application to check on the validation rules that they enforce on

    their various components. All such rules are declared in configuration filesprovided by the framework.

    There are several steps required in including Validator functionality within an existing

    Struts application:

    Configure the Validator Plug-in. Declare the forms requiring validation and the type of validation they require. Create the messages that will be displayed in case of validation failure. Modify the struts-config file to enable automatic validation.

  • 8/3/2019 MELJUN_CORTES_JEDI Course Notes Web Programming Lesson8 Advanced Struts

    4/16

    Configuring the Validator Plug-In

    This step is required to make the Struts framework aware of our usage of the Validator

    framework. All that needs to be done is to add a few lines into our struts-config.xml file.Below is a sample:

    ...

    The pathnames property informs the framework where it can find the configuration filesthat it needs. There are two configuration files: validator-rules.xml and validator.xml.

    validator-rules.xml

    This configuration file defines the classes implementing the validation code. Theframework comes with a copy of this file with the pre-defined validator classes already

    configured.

    The following is a list of the logical names of the validators that came shipped in with theframework:

    required properties marked as required must have at least one character asidefrom any whitespace.

    mask properties subjected to the mask validator must match the regularexpression that we submit using the maskparameter.

    minlength if applied to a property, the property must have a length equal to orgreater than the value of the min parameter that we pass.

    maxlength - if applied to a property, the property must have a length equal to or

    less than the value of the maxparameter that we pass. range - the property must fall in between the min and max values that we supply

    using the min and maxparameter byte, short, integer, long, float, double the property must be convertible to

    the specified primitive type. date succeeds if the value of the property is a valid date. creditCard succeeds if the value of the property can be a valid credit card

    number. email succeeds if the value of the property can be a valid email address.

    These predefined validators are enough for most validation purposes. In cases whereyour application's validation requirements cannot be met by these validators, custom

  • 8/3/2019 MELJUN_CORTES_JEDI Course Notes Web Programming Lesson8 Advanced Struts

    5/16

    implementations can be created, and their definitions added to the validator-rules.xmlfile. The creation of custom validator components is an advanced topic and will not becovered in this course.

    validation.xml

    This configuration file declares to the framework which forms require validation andwhich validation rules it would like to implement. The framework only provides the

    structure of the file. Developers would have to configure this file themselves to avail ofthe framework's functionality.

    . Configuring the validation.xml file

    The validation.xml file provides a structure which we can use to specify our validationconfiguration. The following are the XML elements that it defines:

    The root element of this configuration file.

    Each form in our application that requires validation should have a corresponding element. The name attribute in this case should map to the name of a form-

    bean configured in struts-config.xml. This element can contain one or more elements.

    Each field element represents a property in the form that requires validation. Thiselement has the following attributes:

    property the name of the property within the form that will be validated.

    depends the comma-separated list of the validators that will be applied to theproperty. The names of the validators are defined within the validator-rules.xml

    file.

    Defines the key to the error message that will be displayed in case the property does notpass validation rules. The key and the actual error message that will be displayed can befound in a resource bundle that the developer should create.

    Some validators require certain values to be passed to them as parameters so that theycan function properly. These parameters can be supplied by using one or more var

    elements, with each var element corresponding to a parameter given to the validator.This element defines two child elements:

    - defines the name of the parameter to be supplied. - defines the value of the parameter.

    An example of such configuration file is provided below.

  • 8/3/2019 MELJUN_CORTES_JEDI Course Notes Web Programming Lesson8 Advanced Struts

    6/16

    min

    4

    The sample file provided configures the loginForm used in our earlier examples.loginForm here directly corresponds to an ActionForm that is defined within the struts

    configuration file under the name loginForm. This was expressed by setting loginForm asthe value to the name attribute of the element.

    After the element, we find that there are two elements defined. The first element configures the loginName property of our form, the second configuresthe password property. We can determine which is which by looking at the value of theproperty attribute.

    Defining the resource bundle

    The element above defined a key that needs to be matched to an entry in aresource bundle. This entry is then used to determine the message that will be displayedto the user. The Validator framework makes use of the same resource bundle that theStruts framework uses, which, by default, can be found in the WEB-INF/classes directoryunder the name ApplicationResources.properties. If such a resource bundle does not

    currently exist in your application, create a text file with that name.

    Entries in the resource bundle are simple key=value pairs. For the configuration exampleabove, we can have the following content:

    error.loginname.required=Please enter your login nameerror.password.required=You have supplied a blank password or a password with lessthan 4 characters

    The last step in enabling the validation framework is to change our ActionForm andDynaActionForm classes to make use of the classes provided. Making use of our earlierDynaActionForm example:

  • 8/3/2019 MELJUN_CORTES_JEDI Course Notes Web Programming Lesson8 Advanced Struts

    7/16

    Tiles

    Another framework that works especially well with Struts is the Tiles framework. UsingTiles, we can easily define templates and screen instances which we can use with ourapplication.

    What are templates?

    Simply put, a template page is a page layout design that can be reused by any of thepages in your application. Making use of templates gives your application a more

    consistent look and feel.

    To better appreciate the concept of templates, let us take a look at a couple of pagesfrom a web application:

  • 8/3/2019 MELJUN_CORTES_JEDI Course Notes Web Programming Lesson8 Advanced Struts

    8/16

    Figure 1: Sample Page from a Web Application

  • 8/3/2019 MELJUN_CORTES_JEDI Course Notes Web Programming Lesson8 Advanced Struts

    9/16

    Looking through the pages, we can see that there are several design elements commonfor all of them. All of them share the same set of navigational links on the left, the sameset of images on top of the page, the same set of images on the links on the bottom ofthe page. Most of what has changed between the different pages is the contentpresented in the middle of the page.

    Think of how we would be able to implement a set of similar pages. If we were toimplement each page as we see it, that is, exactly one page to correspond with each of

    the screens we can see, we would have trouble maintaining it in the future. That wouldbe because there would be a lot of code that would be duplicated if later on someonedecided that the images on top didn't really look that good or that the navigational menuon the left isn't intuitive enough, the changes would have to be manually propagatedacross all of the pages.

    Being the programmers that we are, we know enough to refactor into separate entitiescode that would be duplicated across the application. This concept can also be applied to

    JSP/HTML pages: the navigational links could be implemented as one page, the headerimages as another, the footer yet another. These pages could then be added into a page

    implementing the body content. This can be performed without the use of anyframework, using the action we have discussed in the basic JSP lecture.

    Figure 2: Sample Page from a Web Application

  • 8/3/2019 MELJUN_CORTES_JEDI Course Notes Web Programming Lesson8 Advanced Struts

    10/16

    A better solution would be to make the body content a separate JSP fragment itself, andto create a JSP page that defines the default formatting and layout of the pages, andsimply leaves placeholders for the other elements that could be included into the page. A

    developer implementing a screen would then only have to make use of this "template"page and define a content page that the template would insert into the content

    placeholder.

    The benefits of this solution are obvious: any changes that would need to be performedon one aspect of the presentation layer, say the header page, would be applied to all ofthe pages while modifying only one page. If you wanted to change your site's layout,while still maintaining its content, it could be done by simply changing the templatepage.

    We will be learning how to do this templating using the Tiles framework.

    Preparing Tiles

    Before we can help ourselves to the benefits that the Tiles framework can give, we needto perform several preparatory steps.

    1. The first thing that we need to do is to add the following lines to struts-config.xml,just before the closing element:

    This informs Struts that we want to make use of the Tiles framework, and that theconfiguration file that it would read can be found in the /WEB-INF directory, with thename tiles-defs.xml.

    2. Next, we need to copy the struts-tiles.tld and tiles-config.dtd files from the Struts' lib

    directory into the /WEB-INF directory of our application. The first file containsinformation on the custom tags that we will need to use for Tiles, and the second defines

    the structure of the tiles-defs configuration file.

    3. Create a blank configuration file that we can fill up later. Make an xml file, name it

    tiles-defs.xml and place it in the WEB-INF directory. Then place the following content:

    After we have performed the previous steps, Tiles is ready for use.

    http://jakarta.apache.org/struts/dtds/tiles-config.dtdhttp://jakarta.apache.org/struts/dtds/tiles-config.dtd
  • 8/3/2019 MELJUN_CORTES_JEDI Course Notes Web Programming Lesson8 Advanced Struts

    11/16

    Building a Layout template

    The first step in building a template is to identify the components that that will be placedin it. For example, most web pages have a header, footer, menu bar, and body ascomponents.

    If we were to draw a quick sketch, such a layout might look like the one in the diagram

    below.

    To create a template page implementing this layout, follow these steps:

    1. Create a new JSP page.

    2. Import the Tiles tag library.3. Create the HTML implementing the layout, leaving as blank the implementation

    for the actual components.4. Use the tag to act as placeholders for the layout components.

    The HTML implementing the layout could be as simple as a table, with the componentsmodeled as table cells as shown in the JSP below:

    Figure 3: Basic layout

  • 8/3/2019 MELJUN_CORTES_JEDI Course Notes Web Programming Lesson8 Advanced Struts

    12/16

    There are two custom tags in the above sample: and .

    - has a number of uses in the Tiles framework. In this case, what

    it does is to insert a JSP fragment referred to by the name supplied in theattribute attribute. Which fragment corresponds to the name will be specified in

    the screen definition that will make use of this template. - this tag simply retrieves as a String a value supplied in a

    screen definition using the name in the name attribute.

    Creating Screen Definitions

    Once we have a template, we can make use of it to wholly define a screen. Creatingscreen definitions can be done in two ways within the Tiles framework: the definitionscan be defined within JSP pages, or within an XML file recognized by the framework.

    . Creating a definition using JSP pages

    Creating a definition within a JSP page makes use of more custom tags supplied by Tiles:

    - base tag with which to define a screen. The value of the id

    attribute is the name by which this definition can be referred to by othercomponents. The value of the page attribute is the location of the template file itwill use as its base.

  • 8/3/2019 MELJUN_CORTES_JEDI Course Notes Web Programming Lesson8 Advanced Struts

    13/16

    - this tag is used to place a value into a specified attribute inside atemplate. The name attribute specifies the name of the target location inside thetemplate. The value attribute defines the location of the JSP fragment to be

    used.

    Consider the example below:

    In this sample, we create a screen definition for a welcome page. It makes use of thelayout we defined earlier and places the specified title, header, footer, menu, and bodycomponents into locations defined in the template.

    By default, this definition is visible only within the JSP page containing the declaration.

    To change this, we can supply a value into the optional scope attribute of the tag. The possible values are: page, request, session, and application.

    . Creating a definition using an XML configuration file

    The second way of creating a screen definition is by placing a configuration entry in the

    tiles-defs.xml configuration file that we initially created. The syntax in creating an entryis very similar to the used earlier:

    What is the difference between the two methods? Both methods load the definition as a

    JavaBean into memory. The JSP method though, loads the definition only after the JSPfragment containing it has been accessed and, by default, makes it visible only in the

    same page. This condition makes reuse of the screen definition throughout theapplication a bit more problematic, since extra caution must be taken to avoid loadingand unloading the definition into and from memory unnecessarily.The XML method, on the other hand, makes the screen definition available to the whole

    http://jakarta.apache.org/struts/dtds/tiles-config_1_1.dtdhttp://jakarta.apache.org/struts/dtds/tiles-config_1_1.dtd
  • 8/3/2019 MELJUN_CORTES_JEDI Course Notes Web Programming Lesson8 Advanced Struts

    14/16

    application immediately after startup. The Tiles framework takes care of persisting themin memory. The only thing that components require to make use of the definition is tosupply its name.

    Another benefit of using the XML method for creating the screen definition is that the

    definitions themselves can be used as ActionForwards by the Struts framework. This candrastically cut down the number of JSP files required by our application. Using definitions

    as ActionForwards is a topic that will be discussed in more detail later.

    . Using the screen definitions

    Creating the screen definition is not enough for it to be displayed to the user. To put aDefinition into use, we can use the tag and supply it the name of thedefinition to display:

    The above page is all that is needed to display the welcome screen to the user.

    One of the problems with this approach is that it increases the number of JSPs required

    to display different screens to the user: aside from a body content component, eachscreen would require a separate page that would make use of the screen definition. Forapplications that requires a 100 or so screens, the number of pages that would need tobe created is doubled!

    A better approach would be to make use of the definitions as the targets of

    ActionForwards. By including the Tiles framework as a plugin for Struts (one of thepreparatory steps we performed), Struts is made aware of the screen definitions created

    using Tiles. The screen names can be used in place of actual locations in tags. Consider the example below:

    Here we have modified our earlier sample of struts-config.xml so that the success logical

    condition is now mapped to our welcomePage definition. As we can see, this approach issimple, easy to use, and cuts down on the number of JSP files that needs to be created.

    . Extending definitions

    One of the strengths of the Tiles framework over other templating methods is that it

  • 8/3/2019 MELJUN_CORTES_JEDI Course Notes Web Programming Lesson8 Advanced Struts

    15/16

    allows the extension of screen definitions. Screen extension works in much the sameway as class inheritance in Java: the extended screen inherits all the properties andattributes of the parent Definition. This allows us to create a base definition screen that

    declares default values for attributes that can be extended by Definitions specialized forspecific pages.

    Take the following example:

    By creating a base screen that can simply be extended, we avoid repetition of attributevalue definition. Also, when a change needs to be made with regards to whichcomponent is placed in one of the base attributes, this change is immediately and

    automatically propagated to all of the screens by simply making the change on the basescreen definition.

    EXERCISES

    The exercise of this chapter will build on the exercise introduced in the earlier chapter.Students should form the same groupings as done in the last exercise.

    1) Using the Validator framework, include validation code for all the forms in theprevious exercise.-- Download Material Management --

    Add Download Material form ->

    Update Download Material form ->

    Delete Download Material form -> Input is required, must be of integer format.-- User Management --

    Add User form ->Update User form ->Delete User form -> input is required, must be of integer format.

    2) Convert all ActionForms used in the previous exercise into its DynaActionFormequivalent.

    3) Implement the screens defined in the previous exercise using the Tiles framework.The layout to be used is the basic layout defined earlier in this chapter. This activity

  • 8/3/2019 MELJUN_CORTES_JEDI Course Notes Web Programming Lesson8 Advanced Struts

    16/16

    consists of several tasks:a) Separate the actual content previously created for each page into separate "body"

    pages.

    b) Create side bar pages consisting of a list of links applicable for each subsection ofthe application. For example, if the user is an administrator and is in the Main ContentPage, he would be able to see links to the Download Material Management page, User

    Management page, and User Activity page, as well as a link that he could click to logoutof the application.

    In general, the side bars should be implemented such that they:- Present a link to its parent page as defined in the screen flow definition in the

    previous exercise.- Present links to the next set of pages that can be accessed according to the same

    screen flow.

    - Present a link that will enable the user to log out of the application.

    c) Create Tiles definitions for each of the screens in the application and use them

    instead of ActionForwards.