dynamic web application development using xml and java · dynamic web application development using...
TRANSCRIPT
Cengage Learning 2008 - 2010
Dynamic Web Application Development using XML and Java
by David Parsons
Chapter 15
The Struts Web Application Framework
1
Cengage Learning 2008 - 2010
Learning Objectives
To understand how Struts can be used as a framework for building Java Web applications
To understand the design patterns that underlie the Struts architecture
To be able to build and configure Web applications using Struts
To be able to use the Struts html and bean tag libraries To be able to create internationalized Web applications To be able to use the JavaScript Struts validator
2
Cengage Learning 2008 - 2010
The Struts Framework
http://struts.apache.org– An open source framework– Based on Model View Controller architecture
There are now two Struts frameworks, Struts 1 and Struts 2 (WebWork)– These slides look at Struts 1
There are many similar frameworks (Java Server Faces, Spring etc.)
3
Cengage Learning 2008 - 2010
Why Struts?
Like any framework, the purpose of Struts is to save development effort by factoring out common code.
Most Web applications need the same basic set of components:– Controller for client requests– JavaBeans as Data Transfer Objects– Tag libraries for JSPs
4
Cengage Learning 2008 - 2010
Struts Command and Control Patterns
Struts is based on implementing Web applications using the Model View Controller (MVC) architecture and JSP Model 2
Applies the ‘Front Controller’ pattern The controller delegates to ‘Command objects’ to
handle requests
5
Cengage Learning 2008 - 2010
Front Controller Pattern
ServerServerClientClient
browserbrowser
http request
Frontcontroller
Frontcontroller
http response
Uses resources on the server to assemble and generate the client page
Command objects
6
Cengage Learning 2008 - 2010
The Command Pattern
Encapsulates the execution of particular processes into an object.– Each object that represents a process implements a
polymorphic method that executes the process
Action
execute
Action 1
execute
Action 2
execute
Handler
doPostdoGet
7
Cengage Learning 2008 - 2010
Struts Components
Struts Controller– ActionServlet– Front Controller
Action– Command object
ActionForm– JavaBean for form data
StrutsController
StrutsController
JSP ViewJSP View JavaBeanModel
JavaBeanModel
ModelFacadeModel
Facade
ActionFormActionForm
ActionAction
8
Cengage Learning 2008 - 2010
Struts Servlet – web.xml
Modify your "WEB-INF/web.xml" file to include a <servlet> element to define the controller servlet
<servlet> <servlet-name>action</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> <init-param> <param-name>…</param-name> <param-value>…</param-value> </init-param> <load-on-startup>1</load-on-startup></servlet>
Struts controller servlet
Location of config file.
A number of different init-param entries can be used
9
Cengage Learning 2008 - 2010
Add a <servlet-mapping> element to establish which request URIs are mapped to this servlet. – Normally a filename extension pattern ("*.do").
Servlet Mapping – web.xml
<servlet-mapping><servlet-name>action</servlet-name><url-pattern>*.do</url-pattern>
</servlet-mapping>
All requests with *.do extension are sent to controller servlet.
10
Cengage Learning 2008 - 2010
The Struts Configuration file
struts-config.xml– usually deployed in the WEB-INF folder of the Web application
Specifies form beans, action mappings, properties file<?xml version="1.0"?><!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.3//EN" "http://struts.apache.org/dtds/struts-config_1_3.dtd"><struts-config> <form-beans> … </form-beans> <action-mappings> … </action-mappings> <message-resources … /></struts-config>
11
Cengage Learning 2008 - 2010
Configuring Struts
Requires library files, XML configuration file and message resource (properties) fileswebhomecoverwebhomecover
/WEB-INF/WEB-INF web.xmlstruts-config.xmlweb.xmlstruts-config.xml
/classes/classes
*.jsp*.jsp
/lib/lib
Compiled Java classes (beans, actions…) message resource files
Compiled Java classes (beans, actions…) message resource files
Struts jars for final deploymentStruts jars for final deployment
Server’s ‘lib’ folderServer’s ‘lib’ folder Struts jars for developmentStruts jars for development12
Cengage Learning 2008 - 2010
Managing the Webflow
Page routing is done via the ActionServlet and the Struts configuration file
In web.xml we specify the file extension ‘.do’ to be mapped to the Struts ActionServlet
– all request URIs with a ‘.do’ extension will automatically route via the ActionServlet
– Any other request URIs will be handled normally.
ActionServletActionServlet
http://host/app/welcome.do
http://host/app/shop.do
http://host/app/checkout.do
http://host/app/logout.jsp logout.jsplogout.jsp
13
Cengage Learning 2008 - 2010
Simple Page Routing
Only the ActionServlet and the configuration file are required
– each page can use an anchor with a ‘.do’ extension– the URIs do not specify what the next page should be, only where
the request has come from
ActionServlet
struts-config.xml
page1.jsp<a href="frompage1.do">click here</a>
page2.jsp<a href="frompage2.do">click here</a>
page3.jsp<a href="frompage3.do">click here</a>
home.jsp<a href="fromhome.do">click here</a>
14
Cengage Learning 2008 - 2010
Configuring Action Mappings
‘action’ elements– A ‘path’ attribute that specifies the request URI– A ‘forward’ attribute contains the path to another page in the
application <?xml version="1.0"?><!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.3//EN" "http://struts.apache.org/dtds/struts-config_1_3.dtd"><struts-config> <action-mappings> <action path="/fromhome" forward="/page1.jsp" /> <action path="/frompage1" forward="/page2.jsp" /> <action path="/frompage2" forward="/page3.jsp" /> <action path="/frompage3" forward="/page1.jsp" /> </action-mappings></struts-config>
15
Cengage Learning 2008 - 2010
Webflow with Action Mappings
16
Cengage Learning 2008 - 2010
Action Objects
To integrate server side components into a Struts Web application
– link between the controller layer and the underlying object model– Included in action mappings in the ‘struts-config.xml’ file
Actions contribute to the webflow page routing by returning a string (inside an ‘ActionForward’object) that represents the result of the process
ActionServletActionServlet
struts-config.xmlstruts-config.xml
“success”
“success”
“success”
Page1ActionPage1Action
Page2ActionPage2Action Page3ActionPage3Action
17
Cengage Learning 2008 - 2010
Writing Action Classes
Subclass ‘org.apache.struts.action.Action’ Override ‘execute’
– validate the user’s state– delegate server side processes– return the ActionForward
org.apache.struts.action.Action
execute(ActionMapping, ActionForm, HttpServletRequest, HttpServletResponse) : ActionForward
org.apache.struts.action.Page1Action
execute(ActionMapping, ActionForm, HttpServletRequest, HttpServletResponse) : ActionForward
18
Cengage Learning 2008 - 2010
A Very Simple Action Class
Only returns the ActionForward object. returns the String that will be used by the
ActionServlet to route the webflow.package com.webhomecover.action;import org.apache.struts.action.* ;import javax.servlet.http.*;public class Page1Action extends Action{ public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { return mapping.findForward("success"); }}19
Cengage Learning 2008 - 2010
Configuring Actions in the Struts Configuration File
The ‘action’ element needs to have a body with one or more nested ‘forward’ elements.– The ‘action’ elements may specify several attributes, – It is possible for an action to return one of several
different ActionForward strings<action-mappings> <action path="/frompage1" type="com.webhomecover.action.Page1Action" input="/page1.jsp" > <forward name="success" path="/page2.jsp" /> </action> …other mappings</action-mappings>20
Cengage Learning 2008 - 2010
Global Forwards
Useful where a number of actions all direct to the same resource– e.g. the home page
Defined in ‘struts-config.xml’ using a ‘global-forwards’ element<global-forwards type="org.apache.struts.action.ActionForward"> <forward name="home" path="/home.jsp" redirect="false" /></global-forwards>
21
Cengage Learning 2008 - 2010
Struts Tag Libraries
HTML– Struts-aware HTML tags
Bean– Tags for working with beans
Logic– Iteration, conditional logic and application flow
Template– Create composite views with a common format
22
Cengage Learning 2008 - 2010
Using Taglibs in JSPs
In each JSP page that will use the Struts custom tags, add the namespace prefix and URI
You can use a prefixes other than “bean” and “html”– But you must be consistent in the page
<jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" xmlns:html="http://struts.apache.org/tags-html" xmlns:bean="http://struts.apache.org/tags-bean" version="2.1">
23
Cengage Learning 2008 - 2010
<html:html xhtml="true"> <head> <title> <bean:message key="home.title" /> </title> </head> <body> <h2> <bean:message key="home.heading" /> </h2> <div> <bean:message key="home.messagepart1" /> <html:link action="claimdetails"> <bean:message key="home.messagepart2" /> </html:link> <bean:message key="home.messagepart3" /> </div> </body> </html:html>
HTML and Bean Tags
24
Cengage Learning 2008 - 2010
Struts HTML tags
<?xml version="1.0"?><jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" xmlns:html="http://struts.apache.org/tags-html" version="2.1"><jsp:directive.page contentType="text/html"/> <jsp:output omit-xml-declaration="false" doctype-root-element="html" doctype-public="-//W3C//DTD XHTML 1.1//EN" doctype-system="http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd" /> <html:html xhtml="true"> <head><title>Welcome to WebHomeCover</title></head> <body> <h2>Welcome to the claims department at WebHomeCover.com</h2> <div>click <html:link action="claimform">here</html:link> to enter your claim</div> </body> </html:html></jsp:root>
25
Cengage Learning 2008 - 2010
Using Struts HTML Tags to Populate JavaBeans
The HTML tags make it easy to match form data to bean properties<html:form action="/processclaim" > …<html:text property="policyNumber" size="10" />…<html:text property="amount" size="10" />…<html:radio property="type" value="buildings"/>…<html:radio property="type" value="contents"/>…<html:textarea property="description" rows="5" cols="30" />…<html:submit>Submit</html:submit>…</html:form>26
Cengage Learning 2008 - 2010
ActionForm JavaBeans
The JavaBeans used with the Struts framework to gather data from client form pages are subclasses of ‘org.apache.struts.action.ActionForm’
package com.webhomecover.beans;import org.apache.struts.action.ActionForm;import java.text.NumberFormat;import java.io.Serializable;public class ClaimBean extends ActionForm implements Serializable{// 'get' and 'set' methods as before, but no ‘validate’ method}
27
Cengage Learning 2008 - 2010
ActionForm Configuration
The configuration file includes the declaration of ActionForms inside a ‘form-beans’ element– The body of the ‘form-beams’ element consists of one
or more nested ‘form-bean’ elements that define the name and the type of the ActionForm
<form-beans> <form-bean name="claimBean" type="com.webhomecover.beans.ClaimBean" /></form-beans>
28
Cengage Learning 2008 - 2010
Action Mappings and Form Beans
Define an action that includes attributes related to the use of the ActionForm
– Name the name of a bean declared in a ‘form-bean’ element
– Scope the scope into which the bean will be put
– validate’ if bean’s ‘validate’ method will be called
<action path="/processclaim" type="com.webhomecover.action.ClaimAction" validate="false" name="claimBean" scope="request" input="/claimform.jsp" > <forward name="found" path="/displayclaim.jsp" /> <forward name="notfound" path="/notfound.jsp" /></action>
29
Cengage Learning 2008 - 2010
ActionServlet and Form Beans
Using this information in ‘struts-config.xml’, the ActionServlet can perform the following tasks:– Look for a bean of the appropriate type in the specified
scope– Create a new bean and add it to the specified scope if
it is not already there– Populate bean properties from the request– Pass the bean to the ‘execute’ method of the
appropriate Action class
30
Cengage Learning 2008 - 2010
Struts Webflow
ActionServlet Action object
ActionForm JavaBean
Struts TagLibs
JavaServer Page
CONTROLLER LAYER
1. http request
3b. forward
2. populate and validate
4. process bean data5. forward based
on config file and ActionForward
VIEW LAYER
6. use
7. http response
Struts form page
Struts Client page
Struts TagLibs
use3a. invalid
MODEL LAYER
DTO JavaBean
31
Cengage Learning 2008 - 2010
Validation with Message Resources
We can configure ActionForms to validate the contents of their associated form page
To do this effectively we need to take several steps:– Create a resource file that contains error messages– Create a CSS file that can manage the presentation of error messages– Register the message resource file in the Struts configuration file– Add ‘html:errors’ elements to the form page to display error messages– Implement a ‘validate’ method in the ActionForm that checks the state of
the bean properties and reads the error messages from the resource file– Ensure that the value of the ‘validate’ attribute of the relevant ‘action’
element in the Struts configuration file has been set to ‘true’.
32
Cengage Learning 2008 - 2010
Creating an Error Message Resource File
The file that contains the error message text is knows as a message resources file, which consists of a set of key/value pairs
The keys can contain periods, which means we can use the first part of the key to identity the type of property, and the second part to identify the property name
There are special ‘errors.header’ and ‘errors.footer’ entries that you can use to top and tail each error message
In a linked CSS file, we can apply a suitable format
error.policyNumber=You must enter your policy number
errors.header=<span class="errormessage">errors.footer=</span>
errormessage{color: red}
33
Cengage Learning 2008 - 2010
Registering Message Resources
The message resources file has to be registered in the ‘struts-config.xml’ file
– In the ‘message-resources’ element In this example, the name of the file is
‘ApplicationResources.properties’– The name of the resource file is declared in ‘struts-config.xml’
without the ‘properties’ extension.
Message resource files need to be on the classpath of the Web application
– e.g. the WEB-INF/classes folder.
<message-resources parameter="ApplicationResources" />
34
Cengage Learning 2008 - 2010
Implementing the ‘validate’ Method of an ActionForm
To enable input validation, the ActionForm class includes a ‘validate’ method that can optionally be overridden in subclasses
org.apache.struts.action.ActionFormpublic ActionErrors validate(ActionMapping mapping, HttpServletRequest request)
com.webhomecover.beans.ClaimBean
getXxx()setXxx()public ActionErrors validate(ActionMapping mapping, HttpServletRequest request)
35
Cengage Learning 2008 - 2010
Validating Forms
public ActionErrors validate(ActionMapping mapping, HttpServletRequest request) { ActionErrors errors = new ActionErrors(); if(policyNumber == null || policyNumber.equals("")) {
errors.add("policyNumber", new ActionMessage("error.policyNumber")); } if(claimValue == 0.0) { errors.add("amount", new ActionMessage("error.amount")); } if(claimType==null) {
errors.add("type", new ActionMessage("error.type")); } if(description == null || description.equals("")) {
errors.add("description", new ActionMessage("error.description")); } return errors; }
Optionally override validate(). Returns ActionErrors – a container of errors.
The error messages are specified in a resource file. Struts maps the messages automatically.
36
Cengage Learning 2008 - 2010
struts-config.xml – Action Mappings
<action path="/processclaim" type="com.webhomecover.action.ClaimAction" name="claimData" scope="request" validate="true" input="/claimdetails.jsp" > <forward name="success" path="/display.jsp" /></action>
Map this path to this action.
Use the Form Bean with this name to validate and put it in the session. Return to this page if
validation fails.
This is the forward we specified in the Action.
37
Cengage Learning 2008 - 2010
Using the Struts Bean Tag Library
The bean tag library includes the ‘bean:message’ tag Enables us to substitute literal text in a JSP with text read
from the properties file– This makes it possible to change the text that appears on a
generated client page without changing the JSP itself
e.g. if this message appears in the message resources file
– it can be used in a JSP using a bean:message tag
claim.title=WebHomeCover.com - claim details form
<bean:message key="claim.title" />
38
Cengage Learning 2008 - 2010
The bean:write Tag
As well as the ‘message’ tag, the bean library includes a ‘write’ tag that is similar to <jsp:getProperty>
With this tag, there is no need to use the ‘jsp:useBean’ and ‘jsp:getProperty’ tags– Struts will look up the bean name in all four possible
scopes until it finds a match, in order of visibility page, request, session and application
<bean:write name="claimBean" property="policyType" />
39
Cengage Learning 2008 - 2010
Error messages in action
40
Cengage Learning 2008 - 2010
Internationalization
We can use html and bean tags to enable internationalization (i18n)
Set the ‘lang’ attribute to true
To add a language, we simply define another resource file with the ISO Language Code appended to the file name, preceded by an underscore, e.g.
<html:html xhtml="true" lang="true">
ApplicationResources_fr.properties41
Cengage Learning 2008 - 2010
Providing Multi-Language Resources
The keys in each resource file are the same but the values are different– English
– French
error.policyNumber=You must enter your policy numbererror.amount=Please enter a monetary valueerror.type=You must select either "buildings" or "contents"
error.policyNumber=Vous devez écrire votre nombre de politiqueerror.amount=Veuillez écrire une valeur monétaireerror.type=Vous devez choisir les "bâtiments" ou le "contenu"
42
Cengage Learning 2008 - 2010
Setting Up The Browser - IE
Tools -> Internet Options -> Languages (button)
43
Cengage Learning 2008 - 2010
Setting Up The Browser - Firefox
Tools -> Options -> Languages (button)
44
Cengage Learning 2008 - 2010
French version of the page
45
Cengage Learning 2008 - 2010
The Struts Validator
Struts enables automatic client side form validation via the Struts validator, (based on the Jakarta commons validator) which generates JavaScript in client form pages.
There are a number of steps required in order to use the Struts validator:
– The JavaBean that is populated by the form must extend ValidatorForm rather than ActionForm
– There are a set of standard error message keys that need to be included in the application resources file.
– The validation rules have to be specified in an XML file.– You need to enable the validator plugin in struts-config.xml.– The form’s JSP must include the <html:javascript …/> tag for client side
validation.– The form must submit to the validation function.
46
Cengage Learning 2008 - 2010
Extending ValidatorForm
A standard Struts form bean used with the Struts Validator must extend org.apache.struts.validator.ValidatorForm
– To force a user to actually enter a numeric value we can change the numeric primitive property types to use wrapper classes like Integer and Float
package com.webhomecover.beans;// we need to import the ValidatorForm classimport org.apache.struts.validator.ValidatorForm;//other imports…public class ClaimBean extends ValidatorForm implements java.io.Serializable{// make the claim attribute a Double (object) rather than a double (primitive) private Double claimValue;//…etc.47
Cengage Learning 2008 - 2010
Standard Message Keys
You have to add a set of standard message keys to your message resource files– These messages allow you to replace portions of a
message string with arguments specified at run time
# Struts Validator Error Messageserrors.required={0} is required.errors.minlength={0} can not be less than {1} characters.errors.maxlength={0} can not be greater than {1} characters.errors.invalid={0} is invalid.errors.byte={0} must be a byte.Etc…
48
Cengage Learning 2008 - 2010
The XML Validation File
Has a root element of ‘form-validation’, with nested ‘formset’ and ‘form’ elements
– Each ‘form’ element defines the name of the ValidatorForm bean and the fields to be validated.
– A ‘field’ element has ‘property’ and ‘depends’ attributes, and includes nested elements for each message argument
<form-validation> <formset> <form name="ValidatorFormName"> <field> elements… </form> </formset></form-validation>
<field property="propertyName" depends="validationtype"> <arg position="n" key="messageKey"/></field>49
Cengage Learning 2008 - 2010
Enabling the Validator Plugin
You must enable the ValidatorPlugin in the ‘struts-config.xml’ file– The ‘value’ property refers first to the ‘validator-
rules.xml’ file (in the Struts core jar file) and then to the name and location of your own validation file
<plug-in className="org.apache.struts.validator.ValidatorPlugIn"> <set-property property="pathnames" value="/org/apache/struts/validator/validator-rules.xml, /WEB-INF/validation.xml"/> </plug-in>
50
Cengage Learning 2008 - 2010
Enabling JavaScript
You need to include the ‘html:javascript’ tag in the body of the ‘html:html’ element
– For the ‘formName’ attribute, use the name of the ValidatorForm bean defined for that page in the Struts configuration file.
You also need to add an ‘onsubmit’ attribute to the form element so that it calls the JavaScript validation function
The JavaScript validator uses JavaScript Alerts to provide error messages
<html:javascript formName="claimData" />
<html:form action="/processclaim" onsubmit="return validateClaimData(this);">
51
Cengage Learning 2008 - 2010
Struts Validator Alert
52