[Reprinted] Development of Spring custom views and view parsers, spring views

Source: Internet
Author: User

[Reprinted] Development of Spring custom views and view parsers, spring views
Source

Http://www.ibm.com/developerworks/cn/java/j-lo-springview/

Overview

Spring 3.0 contains multiple views and view Resolvers by default, such as JSP and Velocity views. However, in some cases, we need to develop custom views and their Resolvers, to display views in special file formats, we can also use a custom view and parser to process specific views. This article uses an example to describe how to develop a Spring custom view and view parser to display a view with the suffix SWF and provide a simple registration mechanism, register a view Parser for a view with a specified suffix.

Introduction to Spring view and view parser what is Spring view and view parser

Spring MVC (Model View Controller) is an important component of Spring, while Spring View and View parser are components of Spring MVC. Before introducing the Spring view and view parser, let's take a look at the six phases of a Web request in the Spring MVC framework:

Figure 1. Spring MVC processing process

Through the above introduction of Spring MVC, we can find that the view and view parser will appear in the last part of the request processing process. So what is the view and view parser? In short, a View refers to the V (View) in Spring MVC, And the View parser function is to find the corresponding View based on the specified rules.

Introduction to common views and view parsers

In development, views are usually JSP and Velocity. Spring provides multiple view parsers by default. For example, we can use the most common parser InternalResourceViewResolver to find the JSP view (The View class corresponding to InternalResourceView ). Generally, a view parser can only search for one or more specific views. When a view is not supported by Spring or we want to customize the view Search rules, we can use Spring extension to customize the view parser we need. Currently, the view parser must implement the org. springframework. web. servlet. ViewResolver interface, which contains the resolveViewName method. This method searches for and returns the Spring view object through the view name. Table 1 lists common Spring view parsers.

Table 1. List of common Spring view parsers
   

XmlViewResolver
Interface ViewResolver implementation, from the XML configuration file to find the view implementation (default XML configuration file for/WEB-INF/views. xml ).

ResourceBundleViewResolver
The ViewResolver interface is used to find the view from the properties file ..

UrlBasedViewResolver
The implementation of ViewResolver interface is used to return the corresponding view based on the requested URL path. This view must be the implementation of the AbstractUrlBasedView abstract class. It also has some sub-classes, such as InternalResourceView and JstlView.

InternalResourceViewResolver
A subclass of UrlBasedViewResolver, which is usually used to search for views such as JSP (class InternalResourceView) and JSTL (class JstlView and InternalResourceView subclass.

VelocityViewResolver/FreeMarkerViewResolver
The subclass of UrlBasedViewResolver is used to support the Velocity (class VelocityView) and FreeMark views (class FreeMarkerView ).

ContentNegotiatingViewResolver
The ViewResolver interface is used to find the view based on the request file suffix or the accept field in the request header.

InternalResourceViewResolver is the most commonly used in most projects. This parser can return files with the specified suffix under the specified directory. It supports JSP, JSTL, and other view technologies, however, when using this view parser, you must set the correct priority, because the view parser returns a view even if the correct file is not found, instead of returning null, in this way, the parser with a lower priority than the view parser will not be executed.

In Web development, our front-end display can be JSP, Excel, Velocity, etc. In Spring, different front-end display technologies have their corresponding Java view classes, as mentioned in Table 1, InternalResourceView can represent the JSP view, while FreeMarkerView represents the FreeMarker view. Currently, Spring supports multiple technical development views, including JSP, JSTL, Excel, and Velocity. In most projects, users do not need to customize their own views. In the following sections, we will introduce how to define the development view and view parser.

Example scenario

In most projects, we do not need to develop custom view parsers and views. However, in some cases, for example, the view format in our project is not supported by Spring, or we want to use our own view and view parser to process the view more flexibly. Now we can develop our own view parser and view.

In this example, we provide three views: JSP files, SWF files (flash files), and a custom suffix (. to more easily support the SWF view and custom file suffix view, we developed a custom view object, you want to use this view object to support SWF files and. config file. In addition, two view parsers are developed to implement this example.

Develop the Spring View

In Spring, all view classes must implement the org. springframework. web. servlet. view. view, 2 shows that Spring also provides multiple abstract classes that implement the View interface, so we do not need to directly implement the interface View, but can implement the abstract class provided by Spring. In this example, the custom view class inherits the abstract class org. springframework. web. servlet. view. AbstractUrlBasedView. by inheriting the abstract class, the complexity of custom development can be reduced.

Figure 2. Spring view interface inheritance system diagram

To simplify program development and be compatible with more views, the custom View class developed in this example is a general view class that can directly write the content of the request file to the Request Response (HTTP Response) and set it to the HTTP content-type configured for this view class. However, this view class can only be used to process the request file resources that can be directly displayed by the browser, such as text files and SWF files, but it does not support JSP and other files to be compiled and processed. In this example, we use the custom View class GenericFileView to display SWF and. config text files. Listing 1 provides common view code.

Listing 1. common view code
Public class GenericFileView extends acturlbasedview {// default content type private final static String CONTENT_TYPE = "text/plain"; // http response conent private String responseContent; public GenericFileView () {super (); setContentType (CONTENT_TYPE) ;}@ Override public void setContentType (String contentType) {super. setContentType (contentType) ;}@ Override protected void renderMergedOutputModel (Map <String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception {// set content type response. setContentType (getContentType (); // write response content response. getWriter (). write (this. responseContent); response. getWriter (). close ();}/*** set http response content * @ param responseContent */public void setResponseContent (String responseContent) {this. responseContent = responseContent ;}}
As mentioned above, the view class in this example inherits the abstract class AbstractUrlBasedView. Therefore, our custom General View class does not require much code, the Code mainly sets the file content type and the response content to the Request Response object.
Develop a Spring view parser

With the View class, we also need to find the view parser of the View class. All view parsers must implement the org. springframework. web. servlet. viewResolver, but like the implementation of the view, Spring also provides an abstract class. We can also save development work by implementing the abstract class.

In this example, we developed the custom view parser GenericFileViewResolver, which implements the abstract class org. springframework. web. servlet. view. abstractCachingViewResolver, as shown in figure 3, the view parser in common Spring inherits the abstract class.

Figure 3. abstract class AbstractCachingViewResolver Inheritance System

Besides inheriting the abstract class AbstractCachingViewResolver, the view parser in this example implements the org. springframework. core. Ordered interface, which is used to set the call priority of the view parser. This is because a project usually has multiple view Resolvers, so we need to set the priority of each parser to be called, especially when it is mixed with InternalResourceViewResolver, the call priority must be defined correctly. As we mentioned earlier, InternalResourceViewResolver will always return a view, and no null will be returned even if no proper view is found, as a result, the view parser will not be called later.

The core method of the view parser is loadView, as shown in Listing 2. In this method, find the requested file based on the file path of the request and generate a new view, and write the file stream to the view object. Listing 2 is a custom view parser code snippet

List 2. Custom view parser code snippet
@ Override protected View loadView (String viewName, Locale locale) throws Exception {if (location = null) {throw new Exception ("No location specified for GenericFileViewResolver. ");} String requestedFilePath = location + viewName; Resource resource = null; try {logger. finest (requestedFilePath); resource = getApplicationContext (). getResource (requestedFilePath);} catch (Exception e) {// return null to be processed by the next resolver logger. finest ("No file found for file:" + requestedFilePath); return null;} logger. fine ("Requested file found:" + requestedFilePath + ", viewName:" + viewName); // obtain the view object GenericFileView = this based on the view name. getApplicationContext (). getBean (this. viewName, GenericFileView. class); view. setUrl (requestedFilePath); // write the view content view. setResponseContent (inputStreamTOString (resource. getInputStream (), "ISO-8859-1"); return view ;}

Note that when the request file cannot be found, null must be returned so that other low-priority view parsers registered in the Spring container can be called.

Develop a composite view parser

As this example needs to support SWF and custom suffix files, we expect to be able to call different view Resolvers based on different request suffix names. In fact, Spring has provided a similar view parser-ContentNegotiatingViewResolver, which can search for the view based on the requested file suffix or the requested Accept header. ContentNegotiatingViewResolver is not responsible for the view search itself. It only proxies the view search work to the registered view parser. Listing 3 shows the configuration file segment of ContentNegotiatingViewResolver.

Listing 3. ContentNegotiatingViewResolver
<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">   <property name="mediaTypes">     <map>       <entry key="atom" value="application/atom+xml"/>       <entry key="html" value="text/html"/>       <entry key="json" value="application/json"/>     </map>   </property>   <property name="viewResolvers">     <list>       <bean class="org.springframework.web.servlet.view.BeanNameViewResolver"/>       <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">         <property name="prefix" value="/WEB-INF/jsp/"/>         <property name="suffix" value=".jsp"/>       </bean>     </list>   </property>   <property name="defaultViews">     <list>       <bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView" />     </list>   </property>  </bean>

From listing 3, we can see that when using ContentNegotiatingViewResolver, you generally need to configure three parts:

For more information about how to use ContentNegotiatingViewResolver, see the official Spring documentation.

The composite view parser developed in this example is similar to ContentNegotiatingViewResolver. Although ContentNegotiatingViewResolver can also be used in this example to implement the same function, ContentNegotiatingViewResolver is more complex, all view parsers registered to ContentNegotiatingViewResolver are called once, all the queried views are saved as candidate views, and then filtered based on the conditions, filter out the most suitable view. In this example, the composite view parser is much more simple and practical. You only need to register the file suffix and the corresponding view parser. When you find the corresponding view Parser for the request, the view parser is called directly without calling all the view Resolvers it registers. Listing 4 lists the configuration file fragments for parsing the composite view in the Spring configuration file.

Listing 4. Configuration snippet of the composite view parser
<bean id="viewResolver"          class="com.sample.web.viewresolver.MultipleViewResolver" p:order="0">         <property name="resolvers">             <map>                           <entry key="config">                     <bean class="com.sample.web.viewresolver.GenericFileViewResolver"                          p:location="/WEB-INF/config/" p:cache="false">                         <property name="viewName" value="configFileView"/>                     </bean>                 </entry>                          <entry key="swf">                     <bean class="com.sample.web.viewresolver.GenericFileViewResolver"                          p:location="/WEB-INF/swf/" p:cache="false">                         <property name="viewName" value="swfFileView"/>                     </bean>                 </entry>                             </map>         </property>     </bean>

In the configuration file, we have registered a view Parser for different file extensions and configured the View class for this view parser. Similar to ContentNegotiatingViewResolver, MultipleViewResolver, a composite view parser in this example, also proxies the view search work to the registered view parser. In fact, MultipleViewResolver is also a common view parser, however, in the core method loadView (such as listing 5), first obtain the suffix of the Request view, then obtain the registered view parser Based on the suffix, and finally, then use the obtained view parser to find the view.

Listing 5. MultipleViewResolver code snippet
@ Override protected View loadView (String viewName, Locale locale) throws Exception {String fileExtension = StringUtils. getFilenameExtension (viewName); // return null. if no suffix exists, the next resolver can process if (fileExtension = null) {return null;} // obtain resolver ViewResolver resolver = resolvers through the suffix. get (fileExtension); // return null to invoke next resolver if no resolver found return resolver = null? Null: resolver. resolveViewName (viewName, locale );}

After the custom view and view parsing are ready, we can develop controllers in Spring MVC to process Web requests.

Development Controller

In this example, we will demonstrate how to use a custom view parser to process SWF and. the config File Access Request also provides the ability to process JSP file access requests. Therefore, this example provides a simple controller SampleController that can process three request paths, return the corresponding view, as shown in Listing 6.

Listing 6. Sample Controller code snippet
@Controller  public class SampleController {  @RequestMapping("/jsp/sample")  public String getSampleJsp() {  return "SampleJsp";  }   @RequestMapping("/config/sample.config")  public String getSampleConfig() {  return "SampleConfig.config";  }    @RequestMapping("/swf/sample.swf")  public String getSampleSwf() {  return "SampleSwf.swf";  }   }

Based on the above Code, the Controller returns the view SampleJsp for the request/jsp/sample, which is the request/config/sample. config returns the view SampleConfig. and return the view SampleSwf.swf for the request/swf/sample.swf.

Configure view parser

After developing the controller, We can configure the view and corresponding parser. In development, we usually divide the Spring configuration file into at least two parts. In this example, we created two Spring configuration files: spring-root.xml and spring-web.xml, 4. The spring-root.xml is used to store non-web management-related configurations, and the spring-web.xml stores all web-related configurations. Since this example is relatively simple, there is no specific configuration content in the spring-root.xml file.

Figure 4. Structure of the sample project file

Listing 6 shows that we use an Annotation (Annotation) to define the controller, so we need to configure the root directory of Spring scan in the spring-web.xml, as shown in listing 7.

Listing 7 setting the Spring annotation scan path
<context:component-scan base-package="com.sample.web.controller"/>

The composite view parser is configured in Listing 4. In addition, we also need to define the parser jspViewResolver to find the JSP file. Note that the attribute value of order is 1, which is greater than the attribute value of the composite view parser, in this way, we can first use the custom composite view parser to find the view. When no suitable proxy view parser or view is found, jspViewResolver is called for view search.

Listing 8. configuring InternalResourceViewResolver
<!-- View Resolver for JSP files -->  <bean id="jspViewResolver"          class="org.springframework.web.servlet.view.InternalResourceViewResolver"          p:order="1">         <property name="prefix" value="/WEB-INF/jsp/"/>         <property name="suffix" value=".jsp"/>  </bean>

In Listing 4, we also define the view corresponding to the registered view parser. Therefore, in the configuration file, we also need to declare the relevant view, as shown in listing 9.

Listing 9. configuring a custom View
<bean id="configFileView" class="com.sample.web.view.GenericFileView"          p:contentType="text/plain" p:url="" scope="prototype"/>  <bean id="swfFileView" class="com.sample.web.view.GenericFileView"          p:contentType="application/x-shockwave-flash" p:url="" scope="prototype"/>

ConfigFileView is used to represent a text file view. This example corresponds to a text file with a suffix of. config. swfFileView is used to represent a flash file view. In this example, it is a flash file with a suffix of. SWF.

Sample run

Now, the development of this example has been completed. The example controller only supports three request paths, but in fact, we can use @ RequestMapping (value = "/path/{fileName}") to allow the Controller to process more common requests.

Before running the sample, you need to prepare the Web server and Spring runtime environment. This example has been tested in Tomcat 7.0 and Spring 3.0.5. You can download the source code and deploy it in your own environment.

When we enter the request address http: // localhost: 8080/SpringSample/swf/sample.swf, the Controller will find the View File SampleSwf.swf by using our custom view parser, the file content is displayed in the browser as application/x-shockwave-flash, as shown in Figure 5.

Figure 5. Request to access the SWF File

Process the suffix of the custom file. the process of config is similar to that of SWF files. The difference is that the file media type of the view is text/plain. Therefore, we will see a text display in the browser, as shown in 6.

Figure 6. Request to access the. config file

In addition, this example also supports access to JSP files. In this example, when there is a JSP access request, the custom view parser will be called, however, because we have not registered an empty suffix or. jsp requests, so the custom view parser will return a null value. Next, Spring will call our registered jspViewResolver (InternalResourceViewResolver) to continue view search, and finally return the requested JSP file, as shown in 7.

Figure 7. Summary of requests to access JSP files

This article introduces the concepts of Spring view and view parser, and briefly introduces the view and view parser provided by Spring, the following example shows how to develop a custom view and view parser.

Download

SpringSample.zip

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.