1. Trang chủ
  2. » Công Nghệ Thông Tin

Building Spring 2 Enterprise Applications phần 9 ppt

35 355 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Nội dung

JSP J SP is part of the J2EE specification as an extension of the Java servlet technology, which makes it an out-of-the-box view technology option for all servlet containers and application servers. It is currently the mostly widely used view technology for Java web applications. In the previous chapter, you used JSP as a means of rendering your views. Based on the data in the model, the JSP file took care of rendering the HTML. Preventing Scriplet Use JSP allows you to write scriptlets in your view files; however, you should not use them. Using Java code in your view files increases the risk of including more than just view-related functionality in your view files. This will prevent you from migrating to another view technology at a later stage. You can prevent the use of scriptlets in your view files by adding the JSP property to your web.xml file, as follows: <jsp-property-group> <url-pattern>*.jsp</url-pattern> <scripting-invalid>true</scripting-invalid> </jsp-property-group> Using an Expression Language and Spring-Provided Tags As of JSP 2.0, and older versions in combination with JSTL tags, it is also possible to use an expres- sion language to simplify accessing data in your model. You have already seen this expression language at work in the previous chapter. It uses the ${xxx} notation to access variables in your model, where xxx is the key under which the requested data is in the model. To help you implement views using JSP pages, Spring provides a number of tags as part of its web framework. These tags help you use the JSP technology in conjunction with the Spring Frame- work. Table 9-2 lists the most commonly used tags Spring provides. Table 9-2. Commonly Used Spring-Provided Tags Tag Name Description <spring:bind> Evaluates the status of a certain bean or property. The status is bound to the request context in the form of a BindStatus instance. <spring:transform> Allows you to transform a certain value that is not part of your com- mand object in the same way as a property that is part of your command object. This tag can be used only inside a <spring:bind> tag. <spring:nestedPath> Allows you to set a nested path on the command object. This supports working with nested bean properties. <spring:hasBindErrors> Allows you to bind errors on the command object. Using this tag binds an Errors instance in the page scope from which you can get informa- tion about err ors on the command object. <spring:message> Allo ws you to internationalize the contents of your pages. This tag uses Spring’s MessageSource and locale support to retrieve messages in the correct language. You can use the tags sho wn in T able 9-2 to cr eate forms using a Spring FormController. N ote that the previous chapter used the new form tags provided in Spring 2.0, which will be discussed later in this chapter. Listing 9-2 shows part of the form used to subscribe a member from the previ- ous chapter , but uses the tags listed in Table 9-2. CHAPTER 9 ■ VIEW TECHNOLOGIES266 9187ch09CMP2.qxd 7/26/07 1:10 PM Page 266 Listing 9-2. The Register a New Member Page Using the Spring-Provided Tags <?xml version="1.0" encoding="ISO-8859-1" ?> <%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> < head> <title>Register a New Member</title> </head> <body> <h1>Register a New Member</h1> <form method="post"> <table> <tbody> <tr> <spring:bind path="member.sex"> <td>Sex:</td> <td> <select name="${status.expression}"> <option>FEMALE</option> <option>MALE</option> </select> </td> </spring:bind> </tr> <spring:nestedPath path="member.name"> <tr> <spring:bind path="name.first"> <td>First Name:</td> <td> <input type="text" name="${status.expression}" value="${status.value}"/> </td> </spring:bind> </tr> <tr> <spring:bind path="name.last"> <td>Last Name:</td> <td> <input type="text" name="${status.expression}" value="${status.value}"/> </td> </spring:bind> </tr> </spring:nestedPath> <tr> <spring:bind path="member.age"> <td>Age:</td> <td> <input type="text" name="${status.expression}" value="${status.value}"/> CHAPTER 9 ■ VIEW TECHNOLOGIES 267 9187ch09CMP2.qxd 7/26/07 1:10 PM Page 267 </td> </spring:bind> </tr> <spring:nestedPath path="member.address"> <tr> <spring:bind path="address.line1"> < td>Line 1:</td> <td> <input type="text" name="${status.expression}" v alue="${status.value}"/> </td> </spring:bind> </tr> <tr> <spring:bind path="address.line2"> <td>Line 2:</td> <td> <input type="text" name="${status.expression}" value="${status.value}"/> </td> </spring:bind> </tr> <tr> <spring:bind path="address.city"> <td>City:</td> <td> <input type="text" name="${status.expression}" value="${status.value}"/> </td> </spring:bind> </tr> <tr> <spring:bind path="address.state"> <td>State:</td> <td> <input type="text" name="${status.expression}" value="${status.value}"/> </td> </spring:bind> </tr> <tr> <spring:bind path="address.zip"> <td>Zip:</td> <td> <input type="text" name="${status.expression}" value="${status.value}"/> </td> </spring:bind> </tr> </spring:nestedPath> CHAPTER 9 ■ VIEW TECHNOLOGIES268 9187ch09CMP2.qxd 7/26/07 1:10 PM Page 268 <tr> <td/> <td><input type="submit" value="Register" /></td> </tr> </tbody> </table> < /form> </body> </html> The sample JSP form in Listing 9-2 uses the <spring:bind> and <spring:nestedPath> tags to render and capture the data that is needed to register a member. Notice the use of the <spring:nestedPath> tag to allow all containing <spring:bind> tags to emit the member command name. Also notice that the name and value attributes of the fields are set using the BindStatus instance, which is set by the <spring:bind> tag. You can also use this status object to retrieve the value in case the form is shown twice and some values have already been filled in on the com- mand object. Velocity Velocity is a Java-based templating engine that can be used as a view technology for web appli- cations. Velocity uses its own templating engine to render the templates. Using Velocity as a view technology promotes the separation between your Java code and the presentation layer by not allowing you to write Java code inside a template. This enables a clear separation of responsibilities between HTML developers and Java developers. Setting Up Your Application to Use Velocity To use Velocity as your view technology, first you need to add a configurer to your servlet applica- tion context to configure Velocity. Second, you need to change the view resolver to the one that is specific to Velocity. Setting up your web applications to use Velocity as the view technology is demonstrated in Listing 9-3. Listing 9-3. Velocity Configurer and the Corresponding View Resolver Configuration <bean id="velocityConfigurer" class="org.springframework.web.servlet.view.velocity.VelocityConfigurer"> <property name="resourceLoaderPath" value="/WEB-INF/velocity/"/> </bean> <bean id="velocityViewResolver" class="org.springframework .web.servlet.view.velocity.VelocityViewResolver"> <property name="suffix" value=".vm"/> </bean> N ote that the configurer is configured with the path to retrieve the templates, relative to the root of the web application. Be sure to place the template files inside the WEB-INF folder so they are not dir ectly accessible to users . The view resolver is configured with a suffix, just as when JSP is used as the view technology. The .vm extension is the default Velocity extension; however, you are free to use any extension for your template files. CHAPTER 9 ■ VIEW TECHNOLOGIES 269 9187ch09CMP2.qxd 7/26/07 1:10 PM Page 269 Creating Velocity Templates Now that the web application has been set up to use Velocity as the view technology, you can s tart to write your view templates. Listing 9-4 shows the list members page rewritten as a Velocity template. Listing 9-4. List Members Rewritten As a Velocity Page <?xml version="1.0" encoding="ISO-8859-1" ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>List Members</title> </head> <body> <h1>List Members</h1> <form action="searchformembers" method="get"> <p> <label for="q">First or Last Name:</label> <input type="text" name="q" value=" $param.q" /> <input type="submit" value="Search" /> </p> </form> #if( $memberList.size() == 0 ) <p>No members found.</p> #end <table> <thead> <tr> <th>Name</th> <th>Age</th> <th>Address</th> </tr> </thead> <tbody> #foreach( $member in $memberList ) <tr> <td>$member.name.last, $member.name.first</td> <td>$member.age</td> <td>$member.address</td> </tr> #end </tbody> </table> </body> </html> For more information about Velocity, see Pro Jakarta Velocity: From Professional to Expert (Apress, 2004). CHAPTER 9 ■ VIEW TECHNOLOGIES270 9187ch09CMP2.qxd 7/26/07 1:10 PM Page 270 FreeMarker F reeMarker is another template engine that works in a manner similar to Velocity. Like Velocity, it provides a clear separation between the logic and the actual presentation. Setting Up Your Application to Use FreeMarker Setting up your web application to use FreeMarker as the view technology is very similar to setting it up to use Velocity, as demonstrated in Listing 9-5. Listing 9-5. Freemarker Configurer and the Corresponding View Resolver Configuration <bean id="freemarkerConfigurer" class="org.springframework .web.servlet.view.freemarker.FreemarkerConfigurer"> <property name="resourceLoaderPath" value="/WEB-INF/freemarker/"/> </bean> <bean id="freemarkerViewResolver" class="org.springframework .web.servlet.view.freemarker. ➥ FreemarkerViewResolver"> <property name="suffix" value=".ftl"/> </bean> In this case, we use a configurer and view resolver specific to FreeMarker, and configure them in a manner similar to the Velocity configuration. For FreeMarker templates, .ftl is the default file- name extension. Creating FreeMarker Templates FreeMarker templates are also very similar to Velocity templates. Listing 9-6 shows the list members page rewritten as a FreeMar ker template. Listing 9-6. List Members Rewritten As a FreeMarker Page <?xml version="1.0" encoding="ISO-8859-1" ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>List Members</title> </head> <body> <h1>List Members</h1> <form action="searchformembers" method="get"> <p> <label for="q">First or Last Name:</label> <input type="text" name="q" value=" ${param.q}" /> <input type="submit" value="Search" /> </p> </form> CHAPTER 9 ■ VIEW TECHNOLOGIES 271 9187ch09CMP2.qxd 7/26/07 1:10 PM Page 271 <#if ${memberList}?size == 0> <p>No members found.</p> </#if> <table> <thead> < tr> <th>Name</th> <th>Age</th> < th>Address</th> </tr> </thead> <tbody> <#list memberList as member> <tr> <td>${member.name.last}, ${member.name.first}</td> <td>${member.age}</td> <td>${member.address}</td> </tr> </#list> </tbody> </table> </body> </html> For more information about FreeMarker, see the FreeMarker project page at SourceForge ( http://freemarker.sourceforge.net). XSLT XML has gained significant popularity over the past years as the means to model and store data. XSLT is a transformation language for XML and allows you to transform XML to, for instance, HTML using XSL. If you are already familiar with XSLT, and your web application works with data in the form of XML, this view technology is a good choice. Implementing an XSLT View To use XSLT as your view technology, first you need to create your custom implementation of the AbstractXsltView class . The implementation should implement the createDomNode() method to provide an XML source to transform. Listing 9-7 demonstrates how to implement the abstract view class to provide access to a Resource (discussed in Chapter 2), which is available in the model under the key xmlResource. It uses classes from http://www.jdom.org/. Listing 9-7. A Sample Implementation of the AbstractXsltView Class package com.apress.springbook.chapter09.web.view; import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.w3c.dom.Node; CHAPTER 9 ■ VIEW TECHNOLOGIES272 9187ch09CMP2.qxd 7/26/07 1:10 PM Page 272 import org.jdom.Document; import org.jdom.input.SAXBuilder; import org.springframework.core.io.Resource; import org.springframework.web.servlet.view.xslt.AbstractXsltView; public class XmlView extends AbstractXsltView { p rotected Node createDomNode(Map model, String root, HttpServletRequest request, HttpServletResponse response) throws Exception { Resource resource = (Resource) model.get("xmlResource"); Document doc = org.jdom.input.SAXBuilder.build(resource.getInputStream()); return new org.jdom.output.DOMOutputter().output(doc); } } The view implementation is called with the model containing the data to render, the name of the root element (which defaults to DocRoot), and the request and response. In this case, the Resource that is available in the model is returned as a Node instance. Cr eating an XSL File The next step is to create an XSL file, which will transform the XML resource to HTML. A sample XSL file is shown in Listing 9-8. Listing 9-8. A Sample XSL File That Transforms XML to HTML <?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"> <xsl:output method="text/html" omit-xml-declaration="yes"/> <xsl:template match="/"> <html> <head><title>List members</title></head> <body> <h1>List members</h1> <xsl:for-each select="memberList/member"> <xsl:value-of select="."/><br /> </xsl:for-each> </body> </html> </xsl:template> </xsl:stylesheet> Note that this is just a simple example that will list all member names contained in the source XML file. Configuring Your Application to Use XSLT Now that you have implemented the XSLT view and created the XSL file, you need to configure your web application to use them both. You can do this by changing (or adding) a view resolver to your servlet application context. In this case, you want to access the view as a bean. Spring provides a CHAPTER 9 ■ VIEW TECHNOLOGIES 273 9187ch09CMP2.qxd 7/26/07 1:10 PM Page 273 view resolver implementation that does exactly that: BeanNameViewResolver. As the name suggests, it uses the view name returned by the controller to look up a bean (by name) that will be used as the view to render. Listing 9-9 shows how to configure this view resolver and the XSLT view in your application context. Listing 9-9. Configuration for Resolving the XSLT View As a Bean < bean id="beanNameResolver" class="org.springframework.web.servlet.view.BeanNameViewResolver"/> <bean name="viewName" class="com.apress.springbook.chapter09.web.view.XmlView"> <property name="stylesheetLocation" value="/WEB-INF/stylesheet.xsl"/> </bean> Note that you need to configure the XSLT view implementation with the location where it can find the XSL file shown in Listing 9-8. This path should be relative to the web application root and should be within the WEB-INF folder so it is not directly accessible to users . XSLT is a very powerful language that you can use to perform complex transformations of data in XML format. You can find more information about XSLT in Beginning XSLT 2.0: From Novice to Professional (Apress, 2005). PDF Adobe PDF is a document format that is widely used to shar e mainly r ead-only data. It provides a cross-platform document structure that ensures a consistent layout across these platforms. Spring provides suppor t for cr eating PDF documents as part of your web application using iText, a library for creating PDF documents. To demonstrate the ease of adding a PDF view to your application, the following example will generate a PDF version of the list members page of the sample application. Implementing a PDF View As with the XSLT view, you need to extend an abstract view class to render the specific view. In this case, you need to extend the AbstractPdfView class. Listing 9-10 shows a sample implementation that assumes a list of members is available in the model data. The members in that list are rendered as a PDF document. Listing 9-10. A Sample Implementation of the AbstractPdfView Class package com.apress.springbook.chapter09.web.view; import java.util.Map; import java.util.List; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.lowagie.text.Document; import com.lowagie.text.Paragraph; import com.lowagie.text.pdf.PdfWriter; import org.springframework.web.servlet.view.document.AbstractPdfView; import com.apress.springbook.chapter09.Member; CHAPTER 9 ■ VIEW TECHNOLOGIES274 9187ch09CMP2.qxd 7/26/07 1:10 PM Page 274 public class MatchPdfView extends AbstractPdfView { protected void buildPdfDocument(Map model, Document document, PdfWriter writer, HttpServletRequest request, H ttpServletResponse response) throws Exception { document.addTitle("Members"); L ist<Member> memberList = (List<Member>) model.get("memberList"); for (Member member : memberList) { document.add(new Paragraph(member.getName().getLast() + ", " + member.getName().getFirst())); } } } The example in Listing 9-10 extends the AbstractPdfView by implementing the abstract buildPdfDocument() method. This method accepts several parameters, of which the model and the created document are the most important. The model can be used to retrieve the data you want to render. The document is the main class of iText and can be used to add content and metadata to the document. Note that Spring takes care of creating, opening, and closing the document for you. This exam- ple sets the title of the document and adds the content of the model to the document. For more information about working with iText to generate PDF documents, visit the iText website: www.lowagie.com/iText/. Configuring Your Application to Use PDF To use the created PDF view, you need to configure a view resolver to correctly resolve the view. You can use the previously discussed BeanNameViewResolver to resolve the view based on its name in the bean container. However, Spring provides an alternative way to resolving views defined as beans. You can use the ResourceBundleViewResolver, which uses the Java built-in ResourceBundle mecha- nism to define your views. This view resolver uses one or more properties files to resolve a view name. To use this view resolver, you need to define a properties file and define the created PDF view, as shown in Listing 9-11. Listing 9-11. The views.properties Properties File Defining the Created PDF View # The match pdf view matchPdfView.class=com.apress.springbook.chapter09.web.view.MatchPdfView Next, you need to define the view resolver and configure it to use the previously created prop- er ties file , as shown in Listing 9-12. You configure the view resolver using the name of the file without the extension, as the ResourceBundle mechanism will append the extension. Listing 9-12. The ResourceBundleViewResolver Configuration <bean id="resourceViewResolver" class="org.springframework.web.servlet.view.ResourceBundleViewResolver"> <property name="basename" value="views"/> </bean> Note that you can also specify multiple properties files by using the basenames property, which takes a list of names as an argument. CHAPTER 9 ■ VIEW TECHNOLOGIES 275 9187ch09CMP2.qxd 7/26/07 1:10 PM Page 275 [...]... with each other When working with Spring, you wire those dependencies together using Spring s configuration files In order to test part of your whole application, you typically want to load the Spring application context and test one or more beans configured in that application 29 7 91 87ch10.qxd 29 8 8/1/07 10:04 AM Page 29 8 CHAPTER 10 s TESTING context Fortunately, Spring provides convenient support... the path attribute It should be used in conjunction with the and tags in order to correctly render the selected value Continued 27 9 9187ch09CMP2.qxd 28 0 7 /26 /07 1:10 PM Page 28 0 CHAPTER 9 s VIEW TECHNOLOGIES Table 9- 5 Continued Tag Name Description Generates an HTML option element and sets the selected attribute based on the bound value Generates... 91 87ch09CMP2.qxd 28 2 7 /26 /07 1:10 PM Page 28 2 CHAPTER 9 s VIEW TECHNOLOGIES As you can see in Listing 9- 19, using these new Spring- provided form tags greatly reduces the length of your forms More important, your forms are easier to read and maintain Also note that the tag will determine the currently selected value when reshowing the form in case of validation errors Another advantage of using Spring. .. in Listing 9- 16) 27 7 91 87ch09CMP2.qxd 27 8 7 /26 /07 1:10 PM Page 27 8 CHAPTER 9 s VIEW TECHNOLOGIES JasperReports reports need to be either configured in XML or designed using a graphical editor, such as OpenReports (http://oreports.com) or iReport (http://jasperforge.org/sf/projects/ ireport) These reports must also be compiled in order for them to be rendered by JasperReports When using Spring s JasperReports... using Spring s test support Listing 10-14 shows this integration test, which extends the Abstract DependencyInjectionSpringContextTests base class 91 87ch10.qxd 8/1/07 10:04 AM Page 29 9 CHAPTER 10 s TESTING Listing 10-14 An Integration Test for the Currency Converter Using Spring s Test Support package com.apress.springbook.chapter10; import org.springframework.test.AbstractDependencyInjectionSpringContextTests;... "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> Register a New Member Register a New Member Sex: 91 87ch09CMP2.qxd 7 /26 /07 1:10 PM Page 28 1 CHAPTER 9 s VIEW TECHNOLOGIES First... the view implementation renders the report in PDF format Listing 9- 18 demonstrates a sample controller that retrieves the extension from the requested file path and stores it in the model under the format key for retrieval by the JasperReportsMultiFormatView 91 87ch09CMP2.qxd 7 /26 /07 1:10 PM Page 27 9 CHAPTER 9 s VIEW TECHNOLOGIES Listing 9- 18 The Controller Implementation That Retrieves the Format from... mfc.calculateMembershipFee(payingMember); assertEquals((double )25 , result); } 28 9 9187ch10.qxd 29 0 8/1/07 10:04 AM Page 29 0 CHAPTER 10 s TESTING public void testLessThan14YearsOldPerAnnumNoNTFMember() { MembershipFeeCalculator mfc = new RegularMembershipFeeCalculator(); PayingMember payingMember = new TestPayingMember(13, false, false); double result = mfc.calculateMembershipFee(payingMember); assertEquals((double )90 , result); } public void... RegularMembershipFeeCalculatorTests( "testLessThan14YearsOldPerAnnumNoNTFMember" )); suite.addTest(new RegularMembershipFeeCalculatorTests( "testLessThan14YearsOldPerTrimesterNTFMember" )); return suite; } 29 1 91 87ch10.qxd 29 2 8/1/07 10:04 AM Page 29 2 CHAPTER 10 s TESTING Now that we have created fully functional tests, we can run them (for instance, in an IDE) Of course, the tests will all fail because they are not yet implemented... currencies 29 3 91 87ch10.qxd 29 4 8/1/07 10:04 AM Page 29 4 CHAPTER 10 s TESTING double exchangeRate = exchangeRateService.getExchangeRate(fromCurrency, toCurrency); // return the amount multiplied with the exchange rate return amount * exchangeRate; } } The default implementation of the CurrencyConverter has a collaborator defined by an interface, ExchangeRateService, shown in Listing 10 -9 Listing 10 -9 The . uses the tags listed in Table 9 -2. CHAPTER 9 ■ VIEW TECHNOLOGIES266 91 87ch09CMP2.qxd 7 /26 /07 1:10 PM Page 26 6 Listing 9 -2. The Register a New Member Page Using the Spring- Provided Tags <?xml. org.w3c.dom.Node; CHAPTER 9 ■ VIEW TECHNOLOGIES2 72 91 87ch09CMP2.qxd 7 /26 /07 1:10 PM Page 27 2 import org.jdom.Document; import org.jdom.input.SAXBuilder; import org.springframework.core.io.Resource; import org.springframework.web.servlet.view.xslt.AbstractXsltView; public. name="${status.expression}" value="${status.value}"/> CHAPTER 9 ■ VIEW TECHNOLOGIES 26 7 91 87ch09CMP2.qxd 7 /26 /07 1:10 PM Page 26 7 </td> < /spring: bind> </tr> < ;spring: nestedPath path="member.address"> <tr> < ;spring: bind

Ngày đăng: 12/08/2014, 09:21

TỪ KHÓA LIÊN QUAN