免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1745 | 回复: 0
打印 上一主题 下一主题

Chapter 14. Integrating view technologies [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-06-19 17:14 |只看该作者 |倒序浏览
14.1. Introduction
One of the areas in which Spring excels is in the separation of view
    technologies from the rest of the MVC framework. For example, deciding to
    use Velocity or XSLT in place of an existing JSP is primarily a matter of
    configuration. This chapter covers the major view technologies that work
    with Spring and touches briefly on how to add new ones. This chapter
    assumes you are already familiar with
Section 13.5, “Views and resolving them”
    which covers the basics of how views in general are coupled to the MVC
    framework.
14.2. JSP & JSTL
Spring provides a couple of out-of-the-box solutions for JSP and
    JSTL views. Using JSP or JSTL is done using a normal view resolver defined
    in the WebApplicationContext. Furthermore,
    of course you need to write some JSPs that will actually render the view.
14.2.1. View resolvers
Just as with any other view technology you're integrating with
      Spring, for JSPs you'll need a view resolver that will resolve your
      views. The most commonly used view resolvers when developing with JSPs
      are the InternalResourceViewResolver and the
      ResourceBundleViewResolver. Both are declared in the
      WebApplicationContext:
ResourceBundleViewResolver -->
  
# And a sample properties file is uses (views.properties in WEB-INF/classes):
welcome.class=org.springframework.web.servlet.view.JstlView
welcome.url=/WEB-INF/jsp/welcome.jsp
productList.class=org.springframework.web.servlet.view.JstlView
productList.url=/WEB-INF/jsp/productlist.jsp
As you can see, the ResourceBundleViewResolver needs
      a properties file defining the view names mapped to 1) a class and 2) a URL. With a
      ResourceBundleViewResolver you can mix different types of views using
      only one resolver.
  
  
  
The InternalResourceBundleViewResolver can be configured for using
      JSPs as described above. As a best practice, we strongly encourage
      placing your JSP files in a directory under the 'WEB-INF' directory, so
      there can be no direct access by clients.
14.2.2. 'Plain-old' JSPs versus JSTL
When using the Java Standard Tag Library you must use a special view
      class, the JstlView, as JSTL needs some preparation
      before things such as the i18N features will work.
14.2.3. Additional tags facilitating development
Spring provides data binding of request parameters to command
      objects as described in earlier chapters. To facilitate the development
      of JSP pages in combination with those data binding features, Spring
      provides a few tags that make things even easier. All Spring tags have
      html escaping features to enable or disable
      escaping of characters.
The tag library descriptor (TLD) is included in the
      spring.jar as well in the distribution itself.
      Further information about the individual tags can be found in the appendix entitled
      
Appendix D, spring.tld
.
14.3. Tiles
It is possible to integrate Tiles - just as any other view
    technology - in web applications using Spring. The following describes in
    a broad way how to do this.
14.3.1. Dependencies
To be able to use Tiles you have to have a couple of additional
      dependencies included in your project. The following is the list of
      dependencies you need.

  • Struts version 1.1 or higher

  • Commons BeanUtils

  • Commons Digester

  • Commons Lang

  • Commons Logging

    These dependencies are all available in the Spring distribution.
    14.3.2. How to integrate Tiles
    To be able to use Tiles, you have to configure it using files
          containing definitions (for basic information on definitions and other
          Tiles concepts, please have a look at
    http://jakarta.apache.org/struts
    ). In Spring this is done
          using the TilesConfigurer. Have a look at the
          following piece of example ApplicationContext configuration:
      
      
       
          /WEB-INF/defs/general.xml
          /WEB-INF/defs/widgets.xml
          /WEB-INF/defs/administrator.xml
          /WEB-INF/defs/customer.xml
          /WEB-INF/defs/templates.xml
       
      
    As you can see, there are five files containing definitions, which
          are all located in the 'WEB-INF/defs' directory. At initialization of the
          WebApplicationContext, the files will be loaded and the
          definitionsfactory defined by the
          factoryClass-property is initialized. After that has
          been done, the tiles includes in the definition files can be used as
          views within your Spring web application. To be able to use the views
          you have to have a ViewResolver just as with any
          other view technology used with Spring. Below you can find two
          possibilities, the InternalResourceViewResolver and
          the ResourceBundleViewResolver.
    14.3.2.1. InternalResourceViewResolver
    The InternalResourceViewResolver instantiates the given
            viewClass for each view it has to resolve.
      
      
    14.3.2.2. ResourceBundleViewResolver
    The ResourceBundleViewResolver has to be provided with a
            property file containing viewnames and viewclasses the resolver can
            use:
      
        ...
    welcomeView.class=org.springframework.web.servlet.view.tiles.TilesView
    welcomeView.url=welcome (this is the name of a definition)
    vetsView.class=org.springframework.web.servlet.view.tiles.TilesView
    vetsView.url=vetsView (again, this is the name of a definition)
    findOwnersForm.class=org.springframework.web.servlet.view.JstlView
    findOwnersForm.url=/WEB-INF/jsp/findOwners.jsp
    ...
    As you can see, when using the ResourceBundleViewResolver, you can mix view using different view
            technologies.
    14.4. Velocity & FreeMarker
    Velocity
    and
       
    FreeMarker
    are two
        templating languages that can both be used as view technologies within
        Spring MVC applications. The languages are quite similar and serve similar
        needs and so are considered together in this section. For semantic and
        syntactic differences between the two languages, see the
    FreeMarker
    web site.
    14.4.1. Dependencies
    Your web application will need to include
          velocity-1.x.x.jar or
          freemarker-2.x.jar in order to
          work with Velocity or FreeMarker respectively and
          commons-collections.jar
          needs also to be available for Velocity. Typically they are included in
          the WEB-INF/lib folder where they are guaranteed to
          be found by a J2EE server and added to the classpath for your
          application. It is of course assumed that you already have the
          spring.jar in your
          'WEB-INF/lib' directory too!
          The latest stable velocity, freemarker and commons
          collections jars are supplied with the Spring framework and can be
          copied from the relevant /lib/velocity-tools-generic-1.x.jar
          sub-directories. If you make use of Spring's dateToolAttribute or
          numberToolAttribute in your Velocity views, you will also need to include the
          
    14.4.2. Context configuration
    A suitable configuration is initialized by adding the relevant
          configurer bean definition to your '*-servlet.xml' as shown below:

      

      
      
      
      
      
      

      

      
      
      
      
      
      

    Note
    For non web-apps add a VelocityConfigurationFactoryBean or a
          FreeMarkerConfigurationFactoryBean to your application context definition file.
    14.4.3. Creating templates
    Your templates need to be stored in the directory specified by the
          *Configurer bean shown above. This document does not cover
          details of creating templates for the two languages - please see their
          relevant websites for information. If you use the view resolvers
          highlighted, then the logical view names relate to the template file
          names in similar fashion to
          InternalResourceViewResolver for JSP's. So if your
          controller returns a ModelAndView object containing a view name of
          "welcome" then the resolvers will look for the
          /WEB-INF/freemarker/welcome.ftl or
          /WEB-INF/velocity/welcome.vm template as
          appropriate.
    14.4.4. Advanced configuration
    The basic configurations highlighted above will be suitable for
          most application requirements, however additional configuration options
          are available for when unusual or advanced requirements dictate.
    14.4.4.1. velocity.properties
    This file is completely optional, but if specified, contains the
            values that are passed to the Velocity runtime in order to configure
            velocity itself. Only required for advanced configurations, if you
            need this file, specify its location on the
            VelocityConfigurer bean definition above.
      
    Alternatively, you can specify velocity properties directly in
            the bean definition for the Velocity config bean by replacing the
            "configLocation" property with the following inline properties.
      
       
          file
          
            org.apache.velocity.runtime.resource.loader.FileResourceLoader
          
          ${webapp.root}/WEB-INF/velocity
          false
       
      
    Refer to the API
            documentation for Spring configuration of Velocity, or the
            Velocity documentation for examples and definitions of the
            'velocity.properties' file itself.
    14.4.4.2. FreeMarker
    FreeMarker 'Settings' and 'SharedVariables' can be passed
            directly to the FreeMarker Configuration object
            managed by Spring by setting the appropriate bean properties on the
            FreeMarkerConfigurer bean. The
            freemarkerSettings property requires a
            java.util.Properties object and the
            freemarkerVariables property requires a
            java.util.Map.
      
      
       
          
       
      
    See the FreeMarker documentation for details of settings and
            variables as they apply to the Configuration
            object.
    14.4.5. Bind support and form handling
    Spring provides a tag library for use in JSP's that contains
          (amongst other things) a  tag.
          This tag primarily enables forms to display values from form backing
          objects and to show the results of failed validations from a
          Validator in the web or business tier. From version
          1.1, Spring now has support for the same functionality in both Velocity
          and FreeMarker, with additional convenience macros for generating form
          input elements themselves.
    14.4.5.1. The bind macros
    A standard set of macros are maintained within the
            spring.jar file for both languages, so they are
            always available to a suitably configured application. However they
            can only be used if your view sets the bean property
            exposeSpringMacroHelpers to 'true'
            on your VelocityView / FreeMarkerView
            beans. By way of a shortcut, you can also configure this property on
            VelocityViewResolver or
            FreeMarkerViewResolver too if you happen to be
            using it, in which case all of your views will inherit the value from
            it. Note that this property is not
            required
    for any aspect of HTML form handling except where you wish to take advantage of the
            Spring macros. Below is an example of a view.properties file showing
            correct configuration of such a view for either language;
    personFormV.class=org.springframework.web.servlet.view.velocity.VelocityView
    personFormV.url=personForm.vm
    personFormV.exposeSpringMacroHelpers=truepersonFormF.class=org.springframework.web.servlet.view.freemarker.FreeMarkerView
    personFormF.url=personForm.ftl
    personFormF.exposeSpringMacroHelpers=true
    Find below an example of a complete (albeit trivial) Spring Web MVC
            configuration file that exposes the Velocity macros to every (Velocity) view.
       
            
            
            
            
            
            
       
       
            
       
       
            
            
            
            
       
       
            
                
                    **/hello.htm=helloController
                
            
       
    Some of the macros defined in the Spring libraries are
            considered internal (private) but no such scoping exists in the macro
            definitions making all macros visible to calling code and user
            templates. The following sections concentrate only on the macros you
            need to be directly calling from within your templates. If you wish to
            view the macro code directly, the files are called spring.vm /
            spring.ftl and are in the packages
            org.springframework.web.servlet.view.velocity or
            org.springframework.web.servlet.view.freemarker
            respectively.
    14.4.5.2. simple binding
    In your html forms (vm / ftl templates) that act as the
            'formView' for a Spring form controller, you can use code similar to
            the following to bind to field values and display error messages for
            each input field in similar fashion to the JSP equivalent. Note that
            the name of the command object is "command" by default, but can be
            overridden in your MVC configuration by setting the 'commandName' bean
            property on your form controller. Example code is shown below for the
            personFormV and personFormF
            views configured earlier;
    ...
      Name:
      #springBind( "command.name" )
      
      #foreach($error in $status.errorMessages) $error
    #end
      
      ...
      
    ...
    ...
      Name:
       
      
       ${error}

      
      ...
      
    ...
    #springBind /
             requires a 'path' argument
            which consists of the name of your command object (it will be
            'command' unless you changed it in your FormController properties)
            followed by a period and the name of the field on the command object
            you wish to bind to. Nested fields can be used too such as
            "command.address.street". The binddefaultHtmlEscape in web.xml macro assumes
            the default HTML escaping behavior specified by the ServletContext
            parameter
    The optional form of the macro called
            #springBindEscaped /
             takes a second argument
            and explicitly specifies whether HTML escaping should be used in the
            status error messages or values. Set to true or false as required.
            Additional form handling macros simplify the use of HTML escaping and
            these macros should be used wherever possible. They are explained in
            the next section.
    14.4.5.3. form input generation macros
    Additional convenience macros for both languages simplify both
            binding and form generation (including validation error display). It
            is never necessary to use these macros to generate form input fields,
            and they can be mixed and matched with simple HTML or calls direct to
            the spring bind macros highlighted previously.
    The following table of available macros show the VTL and FTL
            definitions and the parameter list that each takes.
    Table 14.1. Table of macro definitions
    macroVTL definitionFTL definitionmessage (output a
                    string from a resource bundle based on the code
                    parameter)#springMessage($code)messageText (output a
                    string from a resource bundle based on the code parameter,
                    falling back to the value of the default parameter)#springMessageText($code
                    $text)url (prefix a relative
                    URL with the application's context root)#springUrl($relativeUrl)formInput (standard
                    input field for gathering user input)#springFormInput($path
                    $attributes)formHiddenInput *
                    (hidden input field for submitting non-user input)#springFormHiddenInput($path
                    $attributes)formPasswordInput *
                    (standard input field for gathering passwords. Note that no
                    value will ever be populated in fields of this type)#springFormPasswordInput($path
                    $attributes)formTextarea (large
                    text field for gathering long, freeform text input)#springFormTextarea($path
                    $attributes)formSingleSelect (drop
                    down box of options allowing a single required value to be
                    selected)#springFormSingleSelect( $path $options
                    $attributes)formMultiSelect (a
                    list box of options allowing the user to select 0 or more
                    values)#springFormMultiSelect($path $options
                    $attributes)formRadioButtons (a
                    set of radio buttons allowing a single selection to be made
                    from the available choices)#springFormRadioButtons($path $options
                    $separator $attributes)formCheckboxes (a set
                    of checkboxes allowing 0 or more values to be
                    selected)#springFormCheckboxes($path $options
                    $separator $attributes)showErrors (simplify
                    display of validation errors for the bound field)#springShowErrors($separator
                    $classOrStyle)
    * In FTL (FreeMarker), these two macros are not actually
            required as you can use the normal formInput macro,
            specifying 'hidden' or
            'password' as the value for the
            fieldType parameter.
    The parameters to any of the above macros have consistent
            meanings:

  • path: the name of the field to bind to (ie
                "command.name")

  • options: a Map of all the available values that can be
                selected from in the input field. The keys to the map represent
                the values that will be POSTed back from the form and bound to the
                command object. Map objects stored against the keys are the labels
                displayed on the form to the user and may be different from the
                corresponding values posted back by the form. Usually such a map
                is supplied as reference data by the controller. Any Map
                implementation can be used depending on required behavior. For
                strictly sorted maps, a SortedMap such as a
                TreeMap with a suitable Comparator may be used
                and for arbitrary Maps that should return values in insertion
                order, use a LinkedHashMap or a
                LinkedMap from commons-collections.

  • separator: where multiple options are available as discreet
                elements (radio buttons or checkboxes), the sequence of characters
                used to separate each one in the list (ie "
    ").

  • attributes: an additional string of arbitrary tags or text
                to be included within the HTML tag itself. This string is echoed
                literally by the macro. For example, in a textarea field you may
                supply attributes as 'rows="5" cols="60"' or you could pass style
                information such as 'style="border:1px solid silver"'.

  • classOrStyle: for the showErrors macro, the name of the CSS
                class that the span tag wrapping each error will use. If no
                information is supplied (or the value is empty) then the errors
                will be wrapped in  tags.

    Examples of the macros are outlined below some in FTL and some
            in VTL. Where usage differences exist between the two languages, they
            are explained in the notes.
    14.4.5.3.1. Input Fields
    ...
        Name:
        #springFormInput("command.name" "")
        #springShowErrors("
    " "")
    The formInput macro takes the path parameter (command.name)
              and an additional attributes parameter which is empty in the example
              above. The macro, along with all other form generation macros,
              performs an implicit spring bind on the path parameter. The binding
              remains valid until a new bind occurs so the showErrors macro
              doesn't need to pass the path parameter again - it simply operates
              on whichever field a bind was last created for.
    The showErrors macro takes a separator parameter (the
              characters that will be used to separate multiple errors on a given
              field) and also accepts a second parameter, this time a class name
              or style attribute. Note that FreeMarker is able to specify default
              values for the attributes parameter, unlike Velocity, and the two
              macro calls above could be expressed as follows in FTL:
    Output is shown below of the form fragment generating the name
              field, and displaying a validation error after the form was
              submitted with no value in the field. Validation occurs through
              Spring's Validation framework.
    The generated HTML looks like this:
    Name:
      
      required
    The formTextarea macro works the same way as the formInput
              macro and accepts the same parameter list. Commonly, the second
              parameter (attributes) will be used to pass style information or
              rows and cols attributes for the textarea.
    14.4.5.3.2. Selection Fields
    Four selection field macros can be used to generate common UI
              value selection inputs in your HTML forms.

  • formSingleSelect

  • formMultiSelect

  • formRadioButtons

  • formCheckboxes

    Each of the four macros accepts a Map of options containing
              the value for the form field, and the label corresponding to that
              value. The value and the label can be the same.
    An example of radio buttons in FTL is below. The form backing
              object specifies a default value of 'London' for this field and so
              no validation is necessary. When the form is rendered, the entire
              list of cities to choose from is supplied as reference data in the
              model under the name 'cityMap'.
    ...
      Town:
      
    This renders a line of radio buttons, one for each value in
              cityMap using the separator "". No additional
              attributes are supplied (the last parameter to the macro is
              missing). The cityMap uses the same String for each key-value pair
              in the map. The map's keys are what the form actually submits as
              POSTed request parameters, map values are the labels that the user
              sees. In the example above, given a list of three well known cities
              and a default value in the form backing object, the HTML would
              be
    Town:
    London
    Paris
    New York
    If your application expects to handle cities by internal codes
              for example, the map of codes would be created with suitable keys
              like the example below.
    protected Map referenceData(HttpServletRequest request) throws Exception {
      Map cityMap = new LinkedHashMap();
      cityMap.put("LDN", "London");
      cityMap.put("PRS", "Paris");
      cityMap.put("NYC", "New York");
      
      Map m = new HashMap();
      m.put("cityMap", cityMap);
      return m;
    }
    The code would now produce output where the radio values are
              the relevant codes but the user still sees the more user friendly
              city names.
    Town:
    London
    Paris
    New York14.4.5.4. HTML escaping and XHTML compliance
    Default usage of the form macros above will result in HTML tags
            that are HTML 4.01 compliant and that use the default value for HTML
            escaping defined in your web.xml as used by Spring's bind support. In
            order to make the tags XHTML compliant or to override the default HTML
            escaping value, you can specify two variables in your template (or in
            your model where they will be visible to your templates). The
            advantage of specifying them in the templates is that they can be
            changed to different values later in the template processing to
            provide different behavior for different fields in your form.
    To switch to XHTML compliance for your tags, specify a value of
            'true' for a model/context variable named xhtmlCompliant:
    ## for Velocity..
    #set($springXhtmlCompliant = true)
    Any tags generated by the Spring macros will now be XHTML
            compliant after processing this directive.
    In similar fashion, HTML escaping can be specified per
            field:
    14.5. XSLT
    XSLT is a transformation language for XML and is popular as a view
        technology within web applications. XSLT can be a good choice as a view
        technology if your application naturally deals with XML, or if your model
        can easily be converted to XML. The following section shows how to produce
        an XML document as model data and have it transformed with XSLT in a
        Spring Web MVC application.
    14.5.1. My First Words
    This example is a trivial Spring application that creates a list
          of words in the Controller and adds them to the model
          map. The map is  returned along with the view name of our XSLT view. See the section
          entitled
    Section 13.3, “Controllers”
    for details of Spring Web MVC's
          Controller interface. The XSLT view will turn the list of
          words into a simple XML document ready for transformation.
    14.5.1.1. Bean definitions
    Configuration is standard for a simple Spring application. The
            dispatcher servlet config file contains a reference to a
            ViewResolver, URL mappings and a single controller
            bean...
    ... that encapsulates our word generation logic.
    14.5.1.2. Standard MVC controller code
    The controller logic is encapsulated in a subclass of
            AbstractController, with the handler method being defined like so...
    protected ModelAndView handleRequestInternal(
        HttpServletRequest request,
        HttpServletResponse response) throws Exception {
            
        Map map = new HashMap();
        List wordList = new ArrayList();
            
        wordList.add("hello");
        wordList.add("world");
          
        map.put("wordList", wordList);
          
        return new ModelAndView("home", map);
    }
    So far we've done nothing that's XSLT specific. The model data
            has been created in the same way as you would for any other Spring MVC
            application. Depending on the configuration of the application now,
            that list of words could be rendered by JSP/JSTL by having them added
            as request attributes, or they could be handled by Velocity by adding
            the object to the VelocityContext. In
            order to have XSLT render them, they of course have to be converted into
            an XML document somehow.
            There are software packages available that will automatically 'domify'
            an object graph, but within Spring, you have complete flexibility to
            create the DOM from your model in any way you choose. This prevents
            the transformation of XML playing too great a part in the structure of
            your model data which is a danger when using tools to manage the
            domification process.
    14.5.1.3. Convert the model data to XML
    In order to create a DOM document from our list of words or any
            other model data, we must subclass the (provided)
            org.springframework.web.servlet.view.xslt.AbstractXsltView
            class. In doing so, we must also typically implement the abstract method
            createXsltSource(..) method. The first parameter passed
            to this method is our model map. Here's the complete listing of the
            HomePage class in our trivial word application:
    package xslt;
    // imports omitted for brevity
    public class HomePage extends AbstractXsltView {
        protected Source createXsltSource(Map model, String rootName, HttpServletRequest
            request, HttpServletResponse response) throws Exception {
            Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
            Element root = document.createElement(rootName);
            List words = (List) model.get("wordList");
            for (Iterator it = words.iterator(); it.hasNext();) {
                String nextWord = (String) it.next();
                Element wordNode = document.createElement("word");
                Text textNode = document.createTextNode(nextWord);
                wordNode.appendChild(textNode);
                root.appendChild(wordNode);
            }
            return new DOMSource(root);
        }
    }
    A series of parameter name/value pairs can optionally be
            defined by your subclass which will be added to the transformation
            object. The parameter names must match those defined in your XSLT
            template declared with
            defaultValue.
            To  specify the parameters, override the
            getParameters() method of the
            AbstractXsltView class and return a
            Map of the name/value pairs. If your parameters
            need to derive information from the current request, you can (from Spring version
            1.1) override the
            getParameters(HttpServletRequest request) method instead.
    Unlike JSTL and Velocity, XSLT has relatively poor support for
            locale based currency and date formatting. In recognition of the
            fact, Spring provides a helper class that you can use from within
            your createXsltSource(..) method(s) to get such
            support. See the Javadocs for the
            org.springframework.web.servlet.view.xslt.FormatHelper
            class.
    14.5.1.4. Defining the view properties
    The views.properties file (or equivalent xml definition if
            you're using an XML based view resolver as we did in the Velocity
            examples above) looks like this for the one-view application that is
            'My First Words':
    home.class=xslt.HomePage
    home.stylesheetLocation=/WEB-INF/xsl/home.xslt
    home.root=words
    Here, you can see how the view is tied in
            with the HomePage class just written which handles the model
            domification in the first property '.class'. The 'stylesheetLocation'
            property points to the XSLT file which will handle the XML
            transformation into HTML for us and the final property '.root' is the
            name that will be used as the root of the XML document. This gets
            passed to the HomePage class above in the second parameter to the
            createXsltSource(..) method(s).
    14.5.1.5. Document transformation
    Finally, we have the XSLT code used for transforming the above
            document. As shown in the above 'views.properties' file, the stylesheet is called
            'home.xslt' and it lives in the war file in the
            'WEB-INF/xsl' directory.
       
       
            
                Hello!
                
                    My First Words
                   
                
            
       
       
            
       
    14.5.2. Summary
    A summary of the files discussed and their location in the WAR
          file is shown in the simplified WAR structure below.
    ProjectRoot
      |
      +- WebContent
          |
          +- WEB-INF
              |
              +- classes
              |    |
              |    +- xslt
              |    |   |
              |    |   +- HomePageController.class
              |    |   +- HomePage.class
              |    |
              |    +- views.properties
              |
              +- lib
              |   |
              |   +- spring.jar
              |
              +- xsl
              |   |
              |   +- home.xslt
              |
              +- frontcontroller-servlet.xml
    You will also need to ensure that an XML parser and an XSLT engine are available on the
                classpath. JDK 1.4 provides them by default, and most J2EE containers
                will also make them available by default, but it's a possible source of
                errors to be aware of.
    14.6. Document views (PDF/Excel)14.6.1. Introduction
    Returning an HTML page isn't always the best way for the user to
          view the model output, and Spring makes it simple to generate a PDF
          document or an Excel spreadsheet dynamically from the model data. The
          document is the view and will be streamed from the server with the
          correct content type to (hopefully) enable the client PC to run their
          spreadsheet or PDF viewer application in response.
    In order to use Excel views, you need to add the 'poi' library to
          your classpath, and for PDF generation, the iText.jar. Both are included
          in the main Spring distribution.
    14.6.2. Configuration and setup
    Document based views are handled in an almost identical fashion to
          XSLT views, and the following sections build upon the previous one by
          demonstrating how the same controller used in the XSLT example is
          invoked to render the same model as both a PDF document and an Excel
          spreadsheet (which can also be viewed or manipulated in Open
          Office).
    14.6.2.1. Document view definitions
    Firstly, let's amend the views.properties file (or xml
            equivalent) and add a simple view definition for both document types.
            The entire file now looks like this with the XSLT view shown from
            earlier..
    home.class=xslt.HomePage
    home.stylesheetLocation=/WEB-INF/xsl/home.xslt
    home.root=words
    xl.class=excel.HomePage
    pdf.class=pdf.HomePage
    If you want to start with a
            template spreadsheet to add your model data to, specify the location
            as the 'url' property in the view definition
    14.6.2.2. Controller code
    The controller code we'll use remains exactly the same from the
            XSLT example earlier other than to change the name of the view to use.
            Of course, you could be clever and have this selected based on a URL
            parameter or some other logic - proof that Spring really is very good
            at decoupling the views from the controllers!
    14.6.2.3. Subclassing for Excel views
    Exactly as we did for the XSLT example, we'll subclass suitable
            abstract classes in order to implement custom behavior in generating
            our output documents. For Excel, this involves writing a subclass of
            org.springframework.web.servlet.view.document.AbstractExcelVieworg.springframework.web.servlet.view.document.AbstractJExcelViewbuildExcelDocument
                    (for Excel files generated by POI)
                            or
                    (for JExcelApi-generated Excel files).
            and implementing the
    Here's the complete listing for our POI Excel view which displays
            the word list from the model map in consecutive rows of the first
            column of a new spreadsheet..
    package excel;
    // imports omitted for brevity
    public class HomePage extends AbstractExcelView {
        protected void buildExcelDocument(
            Map model,
            HSSFWorkbook wb,
            HttpServletRequest req,
            HttpServletResponse resp)
            throws Exception {
       
            HSSFSheet sheet;
            HSSFRow sheetRow;
            HSSFCell cell;
            // Go to the first sheet
            // getSheetAt: only if wb is created from an existing document
            //sheet = wb.getSheetAt( 0 );
            sheet = wb.createSheet("Spring");
            sheet.setDefaultColumnWidth((short)12);
            // write a text at A1
            cell = getCell( sheet, 0, 0 );
            setText(cell,"Spring-Excel test");
            List words = (List ) model.get("wordList");
            for (int i=0; i
    And this a view generating the same Excel file, now using JExcelApi:
    package excel;
                           
    // imports omitted for brevity
    public class HomePage extends AbstractExcelView {
        protected void buildExcelDocument(Map model,
            WritableWorkbook wb,
            HttpServletRequest request,
            HttpServletResponse response)
        throws Exception {
                           
            WritableSheet sheet = wb.createSheet("Spring");
            sheet.addCell(new Label(0, 0, "Spring-Excel test");
                   
            List words  = (List)model.get("wordList");
            for (int i = -; i
                           
                   
    Note the differences between the APIs. We've found that the
                    JExcelApi is somewhat more intuitive and furthermore, JExcelApi
                    has a bit better image-handling capabilities. There have been
                    memory problems with large Excel file when using JExcelApi however.
    If you now amend the controller such that it returns
            xl as the name of the view (return new
            ModelAndView("xl", map);) and run your application again,
            you should find that the Excel spreadsheet is created and downloaded
            automatically when you request the same page as before.
    14.6.2.4. Subclassing for PDF views
    The PDF version of the word list is even simpler. This time, the
            class extends
            org.springframework.web.servlet.view.document.AbstractPdfView
            and implements the buildPdfDocument() method as
            follows..
    package pdf;
    // imports omitted for brevity
    public class PDFPage extends AbstractPdfView {
        protected void buildPdfDocument(
            Map model,
            Document doc,
            PdfWriter writer,
            HttpServletRequest req,
            HttpServletResponse resp)
            throws Exception {
            
            List words = (List) model.get("wordList");
            
            for (int i=0; i
    Once again, amend the controller to return the
            pdf view with a return new
            ModelAndView("pdf", map); and reload the URL in your
            application. This time a PDF document should appear listing each of
            the words in the model map.
    14.7. JasperReports
    JasperReports (
    http://jasperreports.sourceforge.net
    )
        is a powerful open-source reporting engine that supports the creation of report
        designs using an easily understood XML file format. JasperReports is capable of
        rendering reports output into four different formats: CSV, Excel, HTML and PDF.
    14.7.1. Dependencies
    Your application will need to include the latest release of
          JasperReports, which at the time of writing was 0.6.1. JasperReports
          itself depends on the following projects:
    BeanShell
    Commons BeanUtils
    Commons Collections
    Commons Digester
    Commons Logging
    iText
    POI

    JasperReports also requires a JAXP compliant XML parser.
    14.7.2. Configuration
    To configure JasperReports views in your Spring container configuration
          you need to define a ViewResolver to map view
          names to the appropriate view class depending on which format you want your
          report rendered in.
    14.7.2.1. Configuring the ViewResolver
    Typically, you will use the ResourceBundleViewResolver
            to map view names to view classes and files in a properties file.
       
    Here we've configured an instance of the ResourceBundleViewResolverviews. (The content of this file is described in the next section.)
            class that will look for view  mappings in the resource bundle with base name
            
    14.7.2.2. Configuring the Views
    The Spring Framework contains five different View
            implementations for JasperReports, four of which correspond to one of the four output
            formats supported by JasperReports, and one that allows for the format to be determined at runtime:
    Table 14.2. JasperReports View classes
    Class NameRender FormatJasperReportsCsvViewCSVJasperReportsHtmlViewHTMLJasperReportsPdfViewPDFJasperReportsXlsViewMicrosoft ExcelJasperReportsMultiFormatViewThe view is
    decided upon at runtime
    Mapping one of these classes to a view name and a report file is a matter of
            adding the appropriate entries into the resource bundle configured in the previous
            section as shown here:
    simpleReport.class=org.springframework.web.servlet.view.jasperreports.JasperReportsPdfView
    simpleReport.url=/WEB-INF/reports/DataSourceReport.jasper
    Here you can see that the view with name simpleReport
            is mapped to the JasperReportsPdfView class, causing the
            output of this report to be rendered in PDF format. The url
            property of the view is set to the location of the underlying report file.
    14.7.2.3. About Report Files
    JasperReports has two distinct types of report file: the design
            file, which has a .jrxml extension, and the
            compiled report file, which has a .jasper
            extension. Typically, you use the JasperReports Ant task to compile
            your .jrxml design file into a
            .jasper file before deploying it into your
            application. With the Spring Framework you can map either of these files to your
            report file and the framework will take care of compiling the
            .jrxml file on the fly for you. You should note
            that after a .jrxml file is compiled by the Spring Framework,
            the compiled report is cached for the lifetime of the application. To make
            changes to the file you will need to restart your application.
    14.7.2.4. Using JasperReportsMultiFormatView
    The JasperReportsMultiFormatView allows for
            report format to be specified at runtime. The actual rendering of the
            report is delegated to one of the other JasperReports view classes -
            the JasperReportsMultiFormatView class simply adds
            a wrapper layer that allows for the exact implementation to be
            specified at runtime.
    The JasperReportsMultiFormatView class
            introduces two concepts: the format key and the discriminator key. The
            JasperReportsMultiFormatView class uses the mapping
            key to lookup the actual view implementation class and uses the format
            key to lookup up the mapping key. From a coding perspective you add an
            entry to your model with the formay key as the key and the mapping key
            as the value, for example:
    public ModelAndView handleSimpleReportMulti(HttpServletRequest request,
    HttpServletResponse response) throws Exception {
      String uri = request.getRequestURI();
      String format = uri.substring(uri.lastIndexOf(".") + 1);
      Map model = getModel();
      model.put("format", format);
      return new ModelAndView("simpleReportMulti", model);
    }
    In this example, the mapping key is determined from the
            extension of the request URI and is added to the model under the
            default format key: format. If you wish to use a
            different format key then you can configure this using the
            formatKey property of the
            JasperReportsMultiFormatView class.
    By default the following mapping key mappings are configured in
            JasperReportsMultiFormatView:
    Table 14.3. JasperReportsMultiFormatView Default Mapping Key Mappings
    Mapping KeyView ClasscsvJasperReportsCsvViewhtmlJasperReportsHtmlViewpdfJasperReportsPdfViewxlsJasperReportsXlsView
    So in the example above a request to URI /foo/myReport.pdf
                would be mapped to the JasperReportsPdfView class.
                You can override the mapping key to view class mappings using the
                formatMappings property of
                JasperReportsMultiFormatView.
    14.7.3. Populating the ModelAndView
    In order to render your report correctly in the format you have
          chosen, you must supply Spring with all of the data needed to populate
          your report. For JasperReports this means you must pass in all report
          parameters along with the report datasource. Report parameters are
          simple name/value pairs and can be added be to the
          Map for your model as you would add any name/value
          pair.
    When adding the datasource to the model you have two approaches to
          choose from. The first approach is to add an instance of
          JRDataSource or a Collection type to the
          model Map under any arbitrary key. Spring will then
          locate this object in the model and treat it as the report datasource.
          For example, you may populate your model like so:
    private Map getModel() {
      Map model = new HashMap();
      Collection beanData = getBeanData();
      model.put("myBeanData", beanData);
      return model;
    }
    The second approach is to add the instance of
          JRDataSource or Collection under a
          specific key and then configure this key using the
          reportDataKey property of the view class. In both
          cases Spring will instances of Collection in a
          JRBeanCollectionDataSource instance. For example:
    private Map getModel() {
      Map model = new HashMap();
      Collection beanData = getBeanData();
      Collection someData = getSomeData();
      model.put("myBeanData", beanData);
      model.put("someData", someData);
      return model;
    }
    Here you can see that two Collection
          instances are being added to the model. To ensure that the correct one
          is used, we simply modify our view configuration as appropriate:
    simpleReport.class=org.springframework.web.servlet.view.jasperreports.JasperReportsPdfView
    simpleReport.url=/WEB-INF/reports/DataSourceReport.jasper
    simpleReport.reportDataKey=myBeanData
    Be aware that when using the first approach, Spring will use the
          first instance of JRDataSource or
          Collection that it encounters. If you need to place
          multiple instances of JRDataSource or
          Collection into the model then you need to use the
          second approach.
    14.7.4. Working with Sub-Reports
    JasperReports provides support for embedded sub-reports within
          your master report files. There are a wide variety of mechanisms for
          including sub-reports in your report files. The easiest way is to hard
          code the report path and the SQL query for the sub report into your
          design files. The drawback of this approach is obvious - the values are
          hard-coded into your report files reducing reusability and making it
          harder to modify and update report designs. To overcome this you can
          configure sub-reports declaratively and you can include additional data
          for these sub-reports directly from your controllers.
    14.7.4.1. Configuring Sub-Report Files
    To control which sub-report files are included in a master
            report using Spring, your report file must be configured to accept
            sub-reports from an external source. To do this you declare a
            parameter in your report file like so:
    Then, you define your sub-report to use this sub-report parameter:
       
       
            
       
       
       
                      
    This defines a master report file that
            expects the sub-report to be passed in as an instance of
            net.sf.jasperreports.engine.JasperReports under the
            parameter ProductsSubReport. When configuring your
            Jasper view class, you can instruct Spring to load a report file and
            pass into the JasperReports engine as a sub-report using the
            subReportUrls property:
       
            
       
    Here, the key of the Map
            corresponds to the name of the sub-report parameter in th report
            design file, and the entry is the URL of the report file. Spring will
            load this report file, compiling it if necessary, and will pass into
            the JasperReports engine under the given key.
    14.7.4.2. Configuring Sub-Report Data Sources
    This step is entirely optional when using Spring configure your
            sub-reports. If you wish, you can still configure the data source for
            your sub-reports using static queries. However, if you want Spring to
            convert data returned in your ModelAndView into
            instances of JRDataSource then you need to specify
            which of the parameters in your ModelAndView Spring
            should convert. To do this configure the list of parameter names using
            the subReportDataKeys property of the your chosen
            view class:
    Here, the key you supply MUST
            correspond to both the key used in your ModelAndView
            and the key used in your report design file.
    14.7.5. Configuring Exporter Parameters
    If you have special requirements for exporter configuration -
          perhaps you want a specific page size for your PDF report, then you can
          configure these exporter parameters declaratively in your Spring
          configuration file using the exporterParameters
          property of the view class. The exporterParameters
          property is typed as Map and in your configuration
          the key of an entry should be the fully-qualified name of a static field
          that contains the exporter parameter definition and the value of an
          entry should be the value you want to assign to the parameter. An
          example of this is shown below:
      
      
       
          
            Footer by Spring!
               
             
            
          
       
      
    Here you can see that the JasperReportsHtmlView is
          being configured with an exporter parameter for
          net.sf.jasperreports.engine.export.JRHtmlExporterParameter.HTML_FOOTER
          which will output a footer in the resulting HTML.


    本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u/24141/showart_324503.html
  • 您需要登录后才可以回帖 登录 | 注册

    本版积分规则 发表回复

      

    北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
    未成年举报专区
    中国互联网协会会员  联系我们:huangweiwei@itpub.net
    感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

    清除 Cookies - ChinaUnix - Archiver - WAP - TOP