The struts-config.xml File

I l @ ve RuBoard

You can think of struts-config.xml as the traffic cop that controls the entire flow of an application under Struts. It lives in the WEB-INF subdirectory of your newly created struts-bfg directory under Tomcat. Listing 16.1 shows one modified for your application.

Listing 16.1 struts-config.xml
 <?xml version="1.0" encoding="ISO-8859-1" ?> <!DOCTYPE struts-config PUBLIC           "-//Apache Software Foundation//DTD Struts Configuration 1.0//EN"           "http://jakarta.apache.org/struts/dtds/struts-config_1_0.dtd"> <!--     BFG Struts Configuration File --> <struts-config>   <!-- ========== Form Bean Definitions =================================== -->   <form-beans>     <form-bean  name="creditcardForm" type="com.bfg.struts.creditcardForm"/>     <form-bean  name="addressForm" type="com.bfg.struts.addressForm"/>     <form-bean  name="accountForm" type="com.bfg.struts.accountForm"/>   </form-beans>   <!-- ========== Global Forward Definitions ============================== -->   <global-forwards>     <forward  name="myaccount"   path="/myAccount.jsp"/>   </global-forwards>   <!-- ========== Action Mapping Definitions ============================== -->   <action-mappings>     <action    path="/CreditCard"                type="com.bfg.struts.cardAction"                name="creditcardForm"                scope="request">         <forward  name="CCaddress"   path="/CCAddress.jsp"/>     </action>     <action    path="/CreditCardAddr"                type="com.bfg.struts.cardAddrAction"                name="addressForm"                scope="request">     </action>     <action    path="/Address"                type="com.bfg.struts.addressAction"                name="addressForm"              input="/Address.jsp"                scope="request">         <forward  name="address"   path="/Address.jsp"/>     </action>     <action    path="/myAccount"                type="com.bfg.struts.accountAction"                name="accountForm"                scope="request">         <forward  name="address"   path="/Address.jsp"/>         <forward  name="creditcard"   path="/CreditCard.jsp"/>     </action>   </action-mappings> </struts-config> 

The form-beans section provides a mapping between a text name for the form bean and the class that implements it. In general, you need a form bean for each page that submits data, but there are exceptions. The form bean has placeholder variables to store the results of submitting the form, and it has validation logic to ensure that the form is filled out correctly. Form beans extend the class ActionForm .

Forward directives map strings that will be handled back from Action objects to the JSP to which they should be directed. The global-forwards section defines strings that any Action can use; forwards defined in a specific action definition can be used only for that action.

Now you get into the meat of the file ”the action mappings. Each entry starts with a path entry. This corresponds to the URL that you would put in a form ACTION tag. Struts does some magic behind the scenes, adding .do to the URL to get it processed here. The .do is removed before matching against the actions. The mapping for the .do is set up in the web.xml descriptor for the Web application; the one provided by Struts in its WAR file has it already defined.

The type refers to the class of the object (which is derived from the Action class) that will handle the processing of the action and direct the controller to forward to the appropriate next page. Action classes contain the business logic of the bean.

The name tells Struts what ActionForm to use to store the data coming off the JSP. Remember that you defined the mapping between these names and the actual classes in the first section of the file. ActionForm s act a bit like a jsp:setProperty tag, using self-reflection to extract the properties from the request and set the ActionForm 's properties using them. The advantage of using an ActionForm (the model) rather than setting the bean used for the business logic directly is that if you have to back out or reset the values due to validation, for example, you don't affect the underlying state of the business bean.

The scope specifies how long the actionForm will persist. This allows you to have the data available through several Action steps. Remember, the scope refers to the processing of the submit, not the display of the previous page; if you specify a request, you'll have access to the data all the way through the JSP display of the view.

You finish by defining the valid forwarding tags for this action step (in addition to any global ones) and what JSP this forwarding should take you to.

In this file, you're defining four distinct actions: going from the first page of the credit card form to the credit card address (credit cards are broken into two pages for this example), moving from the credit card address to the main page again, moving from an address book edit to the main page, and moving from the main page to an address or credit card edit.

If an action does form validation and might need to return to the form to display errors, the input entry defines the page to which the step should return.

You'll get a better idea of how this all fits together by looking at the code in action. Start with a rewrite of the MyAccount page from the original application (see Listing 16.2). You should put the JSP files into a new directory called strutsjsp. This will prevent them from interfering with the regular application.

Listing 16.2 myAccount.jsp
 <%@ page language="java" %> <%@ page import="com.bfg.customer.Address" %> <%@ page import="com.bfg.customer.CreditCard" %> <%@ taglib uri="/WEB-INF/struts-html.tld"         prefix="html" %> <%@ taglib uri="/WEB-INF/struts-logic.tld"         prefix="logic" %> <%@ taglib uri="/WEB-INF/struts-bean.tld"         prefix="bean" %> <%@ include file="/jsp/cust/AutoLogin.jsp" %> <jsp:useBean id="customer" class="com.bfg.customer.Customer" scope="session"/> <% if (customer.getEmail() == null) {     response.sendRedirect("Login.jsp");     return; } %> <html:html> <head> <title>   <bean:message key="myaccount.title"/> </title> <%@ include file="/jsp/includes/bfgheader.jsp" %> <h2 align="center"><bean:message key="myaccount.title"/></h2> <center><h2><bean:message key="myaccount.addrbook"/></h2></center>   <html:form action="/myAccount">   <html:hidden property="action" value="newaddr"/>   <html:submit>     <bean:message key="myaccount.createaddr"/>   </html:submit>   </html:form> <TABLE WIDTH="100%"> <logic:iterate id="entry" name="customer" property="addressBook" type="java.util.Map. graphics/ccc.gif Entry">     <% Address addr = (Address) entry.getValue(); %>   <TR><TD><%= addr.getFirstName() %> <%= addr.getLastName() %></TD> <TD><%= addr.getCity() %></TD> <TD>       <html:form action="/myAccount">   <html:hidden property="action" value="editaddr"/>   <INPUT TYPE="HIDDEN" NAME="addressIndex" value="<%= addr.getAddressID() %>">     <html:submit>       <bean:message key="myaccount.edit"/>     </html:submit>    </html:form> </TD> <TD>       <html:form action="/myAccount">   <html:hidden property="action" value="deleteaddr"/>   <INPUT TYPE="HIDDEN" NAME="addressIndex" value="<%= addr.getAddressID() %>">     <html:submit>       <bean:message key="myaccount.delete"/>     </html:submit>    </html:form>   </TD>  </TR> </logic:iterate> </TABLE> <center><h2><bean:message key="myaccount.wallet"/></h2></center>   <html:form action="/myAccount">   <html:hidden property="action" value="newcard"/>   <html:submit>     <bean:message key="myaccount.createcard"/>   </html:submit>   </html:form> <TABLE WIDTH="100%"> <logic:iterate id="entry" name="customer" property="wallet" type="java.util.Map.Entry">     <% CreditCard card = (CreditCard) entry.getValue(); %>   <TR><TD><%= card.getCardOwner() %> <%= card.getObscuredNumber() %></TD> <TD>       <html:form action="/myAccount">   <html:hidden property="action" value="editcard"/>   <INPUT TYPE="HIDDEN" NAME="cardIndex" value="<%= card.getCardID() %>">     <html:submit>       <bean:message key="myaccount.edit"/>     </html:submit>    </html:form> </TD> <TD>       <html:form action="/myAccount">   <html:hidden property="action" value="deletecard"/>   <INPUT TYPE="HIDDEN" NAME="cardIndex" value="<%= card.getCardID() %>">     <html:submit>       <bean:message key="myaccount.delete"/>     </html:submit>    </html:form>   </TD>  </TR> </logic:iterate> </TABLE> </html:html> 

The JSP starts normally enough, except for some directives to make the Struts taglibs available. The <html:html> is the first new thing. You're using HTML creation constructs from the Struts library rather than doing them yourself. Some, such as the HTML tag here, are fairly straightforward: It outputs a HTML tag.

The bean:message tag lets you drop a value from a resource file (adjusted for the appropriate locale) into JSP. This allows you to automatically internationalize your content by supplying locale-specific property files. You define your message property file using an ApplicationResource tag in your web. xml file, as you'll see later in the chapter when you edit it.

The html:form tag sets up this form to be handled by Struts, adding a .do to the end of the action, among other things. Remember that Struts maps all files ending in .do to be handled via the Struts controller.

You will also use special tags for the form fields. In the case of the Create button for the address book, you'll use a hidden field in the Action to decide where to go next.

The logic:iterate tag is a useful one, repeating the JSP between the start and end of the tag, once for each entry in the Collection specified in the property of the named object. In this case, it is iterating over the addressBook HashMap of the customer object. The id property of the iterate tag specifies the name of a Java variable to hold each value. In turn , the type field specifies the name of the class that each entry will be cast to, so the collection had better actually hold values of this type to avoid throwing an exception.

Even with the best tag library, I find that sometimes I need to code something using straight JSP. In this case, there's no good way with Struts to create a hidden form field with a computed value. Craig points out that you could create a custom taglib to do it, but for a one-shot deal like this, it is easier to code it as JSP.

The wallet and individual credit cards are displayed using similar code.

I l @ ve RuBoard


MySQL and JSP Web Applications. Data-Driven Programming Using Tomcat and MySQL
MySQL and JSP Web Applications: Data-Driven Programming Using Tomcat and MySQL
ISBN: 0672323095
EAN: 2147483647
Year: 2002
Pages: 203
Authors: James Turner

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