Struts Configuration File - struts-config.xml


Struts Configuration File ‚ struts-config.xml

As you learnt in Chapter 1, the configurable controller is the answer to the Fat controller problem. In a Fat Controller, the programmers can code ‚“ if ‚½ blocks on need basis. Not so with the configurable controllers. The expressive and configuration capability is limited to what the built-in controller can support. In Struts, the built-in controller supports a variety of cases that can arise while developing web applications. It even provides points to extend the configuration capabilities. These points known as Extension points , take the configuration capability to the next dimension. We will deal with extending Struts in Chapter 7. In this section, we will just look at the normal facilities offered by the struts-config.xml .

The Struts configuration file adheres to the struts-config_1_1.dtd . The struts config dtd can be found in the Struts distribution in the lib directory. It shows every possible element, their attributes and their description. Covering all of them at once would only result in information overload. Hence we will only look at the five important sections of this file relevant to our discussion and their important attributes. In fact we have already covered most of these in the lifecycle discussion earlier, but are summarizing them again to refresh your mind. 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

Listing 2.3 shows a sample Struts Config file showing all the five sections. 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.

Listing 2.3: Sample struts-config.xml
 

The ActionMapping section contains the mapping from URL path to an Action class (and also associates a Form bean with the path). The type attribute is the fully qualified class name of the associated Action. Each action entry in the action-mappings should have a unique path. This follows from the fact that each URL path needs a unique handler. There is no facility to associate multiple Actions with the same path. The name attribute is the name of the Form bean associated with this Action. The actual form bean is defined in Form bean definition section. Table 2.1 shows all the relevant attributes discussed so far for the action entry in action-mappings section.

Table 2.1: Important attributes and elements of ActionMapping entry in struts-config.xml

Attribute/Element name

Description

Path

The URL path (either path mapping or suffix mapping) for which this Action Mapping is used. The path should be unique

Type

The fully qualified class name of the Action

Name

The logical name of the Form bean. The actual ActionForm associated with this Action Mapping is found by looking in the Form-bean definition 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

Validate

Can be true or false. When true, the Form bean is validated on submission. If false, the validation is skipped .

Input

The physical page (or another ActionMapping) to which control should be forwarded when validation errors exist in the form bean.

Forward

The physical page (or another ActionMapping) to which the control should be forwarded when the ActionForward with this name is selected in the execute method of the Action class.

In the ActionMapping there are two forward s. Those forward s are local forward s ‚ which means those forward s can be accessed only within the ActionMapping. On the other hand, the forwards defined in the Global Forward section are accessible from any ActionMapping. As you have seen earlier, a forward has a name and a path. The name attribute is the logical name assigned. The path attribute is the resource to which the control is to be forwarded. This resource can be an actual page name as in

 <forward   name="logon"  path="/logon.jsp"/> 

or it can be another ActionMapping as in

 <forward   name="logoff"  path="/logoff.do "/> 

The /logoff (notice the absence of ‚“.do ‚½) would be another ActionMapping in the struts-config.xml. The forward ‚ either global or local are used in the execute() method of the Action class to forward the control to another physical page or ActionMapping.

The next section in the config file is the controller. 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 .

The last section of immediate interest is the Message Resource definition. In the ActionErrors discussion, you saw a code snippet that used a cryptic key as the argument for the ActionError . We stated that this key maps to a value in a properties file. Well, we declare that properties file in the struts-config.xml in the Message Resources definition section. The declaration in Listing 2.1 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. An example in the next chapter will really make things clearer.

View Components

In Struts, View components are nothing but six custom tag libraries for JSP views ‚ HTML , Bean , Logic , Template , Nested , and Tiles tag libraries. Each one caters to a different purpose and can be used individually or in combination with others. For other kinds of views (For instance, Template based presentation) you are on your own. As it turns out, majority of the developers using Struts tend to use JSPs. You can extend the Struts tags and also build your own tags and mix and match them.

You already know that the ActionForm is populated on its way in by the RequestProcessor class using Java Introspection. In this section you will learn how Struts tags interact with the controller and its helper classes to display the JSP using two simple scenarios ‚ how FormTag displays the data on the way out and how the ErrorsTag displays the error messages. We will not cover every tag in Struts though. That is done in Chapter 6.

What is a custom tag?

Custom Tags are Java classes written by Java developers and can be used in the JSP using XML markup. Think of them as view helper beans that can be used without the need for scriptlets. Scriptlets are Java code snippets intermingled with JSP markup. You need a Java developer to write such scriptlets. JSP pages are normally developed and tweaked by page authors, They cannot interpret the scriptlets. Moreover this blurs the separation of duties in a project. Custom Tags are the answer to this problem. They are XML based and like any markup language and can be easily mastered by the page authors. You can get more information on Custom Tags in Chapter 6. There are also numerous books written about JSP fundamentals that cover this topic very well.

 

How FromTag Works

Consider a case when the user requests a page CustomerDetails.jsp . The CustomerDetails JSP page has a form in it. The form is constructed using the Struts html tags and shown in Listing 2.4. The < html:form > represents the org.apache.struts.taglib.html.FormTag class, a body tag. The < html:text > represents the org.apache.struts.taglib.html.TextTag class, a normal tag. The resulting HTML is shown in Listing 2.5.

Listing 2.4: CustomerDetails JSP
 <html>   <head>     <html:base/>   </head>   <body>   <  html:form action="/submitDetailForm"  >     <  html:text property="firstName" /  >   <  html:text property="lastName" /  >   <  html:submit  >  Continue  <  /html:submit  >   <  /html:form  >   </body> </html> 
 
Listing 2.5: Generated HTML from CustomerDetails JSP
 <html>   <head>     <html:base/>   </head>   <body>   <  form name="CustomerForm" action="/submitDetailForm.do"  >   <  input type="text" name="firstName" value="" /  >   <  input type="text" name="lastName" value="" /  >   <  input type="submit" name="Submit" value="" /  >   <  /form  >   </body> </html> 
 

The FormTag can contain other tags in its body. SubmitTag generates the Submit button at runtime. The TextTag < html:text > generates html textbox at runtime as follows.

 <input name=firstName type=text value= /> 

The FormTag has an attribute called action . Notice that the value of the action attribute is /submitDetailForm in the JSP snippet shown above. This represents the ActionMapping. The generated HTML < form > has action= ‚½/submitDetailForm.do ‚½ in its place. The servlet container parses the JSP and renders the HTML.

When the container encounters the FormTag , it invokes the doStartTag() method. The doStartTag() method in the FormTag class does exactly what the RequestProcessor does in the execute() method.

  1. The FormTag checks for an ActionMapping with /submitDetailForm in its path attribute.

  2. When it finds the ActionMapping, it looks for an ActionForm with the name CustomerForm , (which it gets from the ActionMapping) in the request or session scope (which it gets from ActionMapping).

  3. If it does not find one, it creates a new one and puts it in the specified context. Otherwise it uses the existing one. It also makes the Form name available in the page context.

  4. The form field tags (e.g. TextTag ) access the ActionForm by its name from the PageContext and retrieve values from the ActionForm attributes with matching names . For instance, the TextTag < html:text property= ‚½firstName / > retrieves the value of the attribute firstName from the mybank.example.CustomerForm and substitutes as the value. If the CustomerForm existed in the request or session and the firstName field in the CustomerForm had a value ‚“John ‚½, then the TextTag will generate HTML that looks like this:

     <input name=firstName" type="text" value="John" /> 
  5. If the firstName field was null or empty in the CustomerForm instance, the TextTag will generate HTML that looks like this

     <input name=firstName" type="text" value="" /> 

And thus the ActionForm is displayed as a HTML Form.

The moral of the story is that ActionForm s should be made available in advance in the appropriate scope if you are editing existing form data. Otherwise the FormTag creates the ActionForm in the appropriate scope with no data. The latter is suited for creating fresh data. The FormTag reads the same old ActionMapping while looking for the ActionForm in the appropriate scope. It then displays the data from that ActionForm if available.

How ErrorsTag works

When dealing with ActionErrors, you learnt that the validation errors in an ActionForm are reported to the framework through the ActionErrors container. Let us now see what facilities the framework provides to display those errors in the JSP. Struts provides the ErrorsTag to display the errors in the JSP. When the ActionForm returns the ActionErrors , the RequestProcessor sets it in the request scope with a pre-defined and well-known name (within the Struts framework) and then renders the input page. The ErrorsTag iterates over the ActionErrors in the request scope and writes out each raw error text to the HTML output.

You can put the ErrorsTag by adding < html:errors / > in the JSP. The tag does not have any attributes. Neither does it have a body. It displays the errors exactly in the location where you put the tag. The ErrorsTag prints three elements to the HTML output ‚ header, body and footer. The error body consists of the list of raw error text written out to by the tag. A sample error display from struts-example.war (available with Struts 1.1 download) is shown in Figure 2.2.

You can configure the error header and footer through the Message Resource Bundle. The ErrorsTag looks for predefined keys named errors.header and errors.footer in the default (or specified) Message Resource Bundle and their values are also written out AS IS. In the struts-example.war , these are set as follows:

 errors.header=<h3><font color="red">Validation Error</font></h3>  You must correct the following error(s) before proceeding:<ul> errors.footer=</ul><hr> 

For each ActionError , the ErrorsTag also looks for predefined keys errors.prefix and errors.suffix in the default (or specified) Message Resource Bundle. By setting errors.prefix= < li > and errors.suffix = < /li >, the generated HTML looks like follows and appears in the browser as shown in Figure 2.2.


Figure 2.2: Struts error display.
 <h3><font color="red">Validation Error</font></h3>  You must correct the following error(s) before proceeding: <ul>   <li>From Address is required.</li>   <li>Full Name is required.</li>   <li>Username is required</li> </ul> 

Note that all the formatting information is added as html markup into these values. The bold red header, the line breaks and the horizontal rule is the result of html markup in the errors.header and errors.footer respectively.

Tip: A common problem while developing Struts applications is that < html:errors/ > does not seem to display the error messages This generally means one of the following:

  • The properties file could not be located or the key is not found. Set the < message-resources null="false" ... > for debugging.

  • Another reason for not seeing the error messages has got to do with the positioning of the tag itself. If you added the tag itself in the < tr > instead of a < td >, the html browser cannot display the messages even though the tag worked properly by writing out the errors to the response stream.

The View Components was the last piece of the puzzle to be sorted out. As it turns out, all the work is performed in the controller part of the framework. The View Tags look for information in the request or session scope and render it as HTML. Now, that is how a view should be ‚ as simple as possible and yet elegant. Struts lets you do that, easy and fast.




Struts Survival Guide. Basics to Best Practices
Struts Survival Guide: Basics to Best Practices (J2ee Survival Series)
ISBN: 0974848808
EAN: 2147483647
Year: 2004
Pages: 96

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net