1. 程式人生 > >spring檢視解析——自定義解析器例項

spring檢視解析——自定義解析器例項

第一種方式:

在基於SpringMVC的專案中有時需要同時使用多種檢視格式,如jsp,velocity及freemarker等,通過不同的請求路徑配置規則,對映到不同的檢視檔案。下面我提供一種思路,通過檢視模板檔案字尾名的方式來進行處理。例如:

@RequestMapping(value = "/hello") 
public String jspTest(HttpServletRequest request, ModelMap map) { 
    return "demo.jsp"; 

將通過”demo.jsp”的字尾自動使用jsp的檢視解析器。

 

下面描述下詳細思路:

 

一.自定義檢視解析器

複製程式碼
package com.jeedev.common.web.springmvc.view;

import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Set;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import
org.springframework.web.servlet.View; import org.springframework.web.servlet.ViewResolver; /** * 自定義檢視解析(通過配置實現多檢視整合,如jsp,velocity,freemarker,pdf,excel...) * @author huligong * */ public class JeeDevViewResolver implements ViewResolver { private static Log logger = LogFactory.getLog(JeeDevViewResolver.class
); public View resolveViewName(String viewName, Locale locale) throws Exception { for(Map.Entry<Set<String>, ViewResolver> map : viewResolverMap.entrySet()){ Set<String> suffixs = map.getKey(); for(String suffix : suffixs){ if (viewName.endsWith(suffix)){ ViewResolver viewResolver = map.getValue(); if(null != viewResolver){ if (logger.isDebugEnabled()) { logger.debug("found viewResolver '" + viewResolver + "' for viewName '" + viewName+ "'"); } return viewResolver.resolveViewName(viewName, locale); } } } } if(defaultViewResolver != null){ return defaultViewResolver.resolveViewName(viewName, locale); } // to allow for ViewResolver chaining return null; } private Map<Set<String>,ViewResolver> viewResolverMap = new HashMap<Set<String>,ViewResolver>(); private ViewResolver defaultViewResolver = null; public Map<Set<String>, ViewResolver> getViewResolverMap() { return viewResolverMap; } public void setViewResolverMap(Map<Set<String>, ViewResolver> viewResolverMap) { this.viewResolverMap = viewResolverMap; } public ViewResolver getDefaultViewResolver() { return defaultViewResolver; } public void setDefaultViewResolver(ViewResolver defaultViewResolver) { this.defaultViewResolver = defaultViewResolver; } }
複製程式碼

在自定義檢視解析器(其實是檢視中轉器)中,通過對檢視檔案的字尾判斷(而不是請求地址的字尾)而返回給不同的檢視解析器處理。

 

二.檢視對映配置dispather-servlet.xml

 

複製程式碼
<bean id="viewResolver" class="com.jeedev.common.web.springmvc.view.JeeDevViewResolver">
        <property name="defaultViewResolver" ref="beanNameViewResolver"/>
        <property name="viewResolverMap">
            <map>
                <entry>
                    <key>
                        <set>
                            <value>.jsp</value>
                        </set>
                    </key>
                    <ref bean="jspViewResolver"/>
                </entry>
                <entry>
                    <key>
                        <set>
                            <value>.vm</value>
                            <value>.htm</value>
                        </set>
                    </key>
                    <ref bean="velocityViewResolver"/>
                </entry>
                <entry>
                    <key><value>.ftl</value></key>
                    <ref bean="freeMarkerViewResolver"/>
                </entry>
            </map>
        </property>
    </bean>

    
    <bean id="beanNameViewResolver" class="org.springframework.web.servlet.view.BeanNameViewResolver"/>
    
    <bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <!--<property name="suffix" value=".jsp"/>-->
    </bean>
    
    <!--  Velocity ViewResolver Configuration -->
    <bean id="velocityViewResolver" class = "org.springframework.web.servlet.view.velocity.VelocityViewResolver">
         <property name="order" value="0" />
         <property name="contentType" value="text/html;charset=UTF-8" />
         <property name="requestContextAttribute" value="req"/>
    </bean>

    <!-- Velocity Configuration -->     
    <bean id="velocityConfig" class = "org.springframework.web.servlet.view.velocity.VelocityConfigurer">
         <property name="configLocation" value="/WEB-INF/velocity.properties"/>
         <property name="resourceLoaderPath" value="/" />
    </bean>
    
    <!--  FreeMarker ViewResolver Configuration -->
    <bean id="freeMarkerViewResolver" class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">  
        <property name="order" value="0" />
        <property name="viewClass" value="org.springframework.web.servlet.view.freemarker.FreeMarkerView"/>  
    </bean> 
    
    
    <!-- FreeMarker Configuration -->     
    <bean id="freemarkerConfig"  class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">  
       <property name="configLocation" value="/WEB-INF/freemarker.properties"/>
        <property name="templateLoaderPath" value="/WEB-INF/ftl/"/>  
         <property name="freemarkerVariables">
             <map>
                <entry key="xml_escape" value-ref="fmXmlEscape"/>
            </map>
         </property>
    </bean>   
    
    <bean id="fmXmlEscape" class="freemarker.template.utility.XmlEscape"/>
複製程式碼

這裡我配置成所有返回.jsp的檢視模板請求都轉到JSP檢視解析器jspViewResolver中去處理,返回.htm,.vm檢視模板請求都轉到velocity檢視解析器中去處理。

 

三.控制器程式碼示例

 

複製程式碼
package com.jeedev.demo.view;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * 多檢視解析器支援示例
 * @author huligong
 *
 */
@Controller
@RequestMapping(value = "/demo")
public class JeeDevViewResolverTestController {
    private static Log logger = LogFactory.getLog(JeeDevViewResolverTestController.class);
    
    @RequestMapping(value = "/test1")
    public String test1(HttpServletRequest request, ModelMap map) {
        logger.info("使用JSP檢視解析器");
        map.put("name", "hello world");
        return "jspTest.jsp";
    }
    
    @RequestMapping(value = "/test2")
    public String test2(HttpServletRequest request, ModelMap map) {
        logger.info("使用Freemarker檢視解析器");
        map.put("name", "hello world");
        return "hello.ftl";
    }
    
    @RequestMapping(value = "/test3")
    public String test3(HttpServletRequest request, ModelMap map) {
        logger.info("使用Velocity檢視解析器");
        map.put("name", "hello world");
        return "/html/demo.htm";
    }
}
複製程式碼

 

四.測試請求

我在web.xml裡給DispatcherServlet添加了/view/*,所以,只要在請求前加上/view就可以了。

http://localhost:8080/view/demo/test1

http://localhost:8080/view/demo/test2

http://localhost:8080/view/demo/test3

皆驗證通過。


第二種方式

說明一下目錄結構
 
Spring配置檔案

<? xml version="1.0" encoding="UTF-8" ?>
< beans  xmlns ="http://www.springframework.org/schema/beans"
    xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:p
="http://www.springframework.org/schema/p"
    xmlns:context
="http://www.springframework.org/schema/context"
    xsi:schemaLocation
="
    http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.0.xsd"
>
    
< context:component-scan
        
base-package ="com.spring.action"   />
    
<!--   
        org.springframework.web.servlet.view.ResourceBundleViewResolver
        用於多個檢視整合時,ResourceBundleViewResolver是通過解析資原始檔來解析請求輸出檔案的。
        <property name="basename" value="views"></property>,即表示在/WEB-INF/classes路徑下有一個
        views.properties檔案,本例中views.properties的內容為
        welcome.(class)=org.springframework.web.servlet.view.velocity.VelocityView
        welcome.url=welcome.vm
        freemarker.(class)=org.springframework.web.servlet.view.freemarker.FreeMarkerView
        freemarker.url=freemarker.ftl
    
-->
    
< bean  class ="org.springframework.web.servlet.view.ResourceBundleViewResolver" >
        
< property  name ="basename"  value ="views" ></ property >
        
<!--  
            <property name="order" value="0"></property>
        
-->
    
</ bean >
    
    
<!--  jsp檢視解析器  -->
    
< bean  id ="jspViewResolver"  class ="org.springframework.web.servlet.view.InternalResourceViewResolver" >
        
< property  name ="viewClass"  value ="org.springframework.web.servlet.view.JstlView" />
        
< property  name ="prefix"  value ="/" />
        
< property  name ="suffix"  value =".jsp" />
    
</ bean >         
    
    
<!--  velocity檢視解析器  -->
    
< bean  id ="velocityViewResolver"  class ="org.springframework.web.servlet.view.velocity.VelocityViewResolver" >
        
< property  name ="cache"  value ="true" />
        
< property  name ="prefix"  value ="/" />
        
< property  name ="suffix"  value =".vm" />
    
</ bean >
    
    
<!--  velocity環境配置  -->
    
< bean  id ="velocityConfig"  class ="org.springframework.web.servlet.view.velocity.VelocityConfigurer" >
        
<!--  velocity配置檔案路徑  -->
        
< property  name ="configLocation"  value ="/WEB-INF/velocity.properties" />
        
<!--  velocity模板路徑  -->
        
< property  name ="resourceLoaderPath"  value ="/WEB-INF/velocity/" />
    
</ bean >
    
    
<!--  FreeMarker環境配置  -->
    
< bean  id ="freemarkerConfig"  class ="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer" >
        
<!--  freemarker模板位置  -->
        
< property  name ="templateLoaderPath"  value ="/WEB-INF/freemarker/" />
    
</ bean >
    
    
<!--  FreeMarker檢視解析  -->
    
< bean  id ="freeMarkerViewResolver"  class ="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver" >
        
< property  name ="cache"  value ="true" />
        
< property  name ="prefix"  value ="/" />
        
< property  name ="suffix"  value =".ftl" />
    
</ bean >
</ beans > views.properties
#welcome為modelAndView.setViewName( " welcome " ) ; 中的welcome   .(class)固定寫法
welcome.(class) = org.springframework.web.servlet.view.velocity.VelocityView
#welcome.url 路徑 welcome.vm模板名稱
welcome.url
= welcome.vm

#freemarker為modelAndView.setViewName(
" freemarker " ) ; 中的freemarker   .(class)固定寫法
freemarker.(class) = org.springframework.web.servlet.view.freemarker.FreeMarkerView
#freemarker.url 路徑 freemarker.ftl模板名稱
freemarker.url
= freemarker.ftl

第三種方式:自適應匹配,不存在則找下一種,使用orders

[html]  view plain copy 在CODE上檢視程式碼片 派生到我的程式碼片
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"  
  4.     xmlns:mvc="http://www.springframework.org/schema/mvc"  
  5.     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd  
  6.         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd  
  7.         http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">  
  8.   
  9.   
  10.     <context:component-scan base-package="test.**.controller"  
  11.         use-default-filters="false">  
  12.         <context:include-filter type="annotation"  
  13.             expression="org.springframework.stereotype.Controller" />  
  14.     </context:component-scan>  
  15.   
  16.     <mvc:default-servlet-handler />  
  17.     <mvc:resources location="/resources/" mapping="/resources/**" />  
  18.   
  19.     <mvc:annotation-driven>  
  20.         <!-- <mvc:argument-resolvers> <bean class="org.springframework.data.web.PagedResourcesAssemblerArgumentResolver"   
  21.             /> </mvc:argument-resolvers> -->  
  22.         <mvc:message-converters>  
  23.             <bean class="org.springframework.http.converter.StringHttpMessageConverter">  
  24.                 <property name="supportedMediaTypes">  
  25.                     <list>  
  26.                         <value>text/plain;charset=UTF-8</value>  
  27.                         <value>text/html;charset=UTF-8</value>  
  28.                     </list>  
  29.                 </property>  
  30.             </bean>  
  31.             <bean  
  32. 相關推薦

    spring檢視解析——定義解析例項

    第一種方式: 在基於SpringMVC的專案中有時需要同時使用多種檢視格式,如jsp,velocity及freemarker等,通過不同的請求路徑配置規則,對映到不同的檢視檔案。下面我提供一種思路,通過檢視模板檔案字尾名的方式來進行處理。例如: @RequestMapping(valu

    Spring MVC HandlerMethodArgumentResolver 定義引數解析

    Spring MVC Controller預設支援的引數型別有@RequestParam、@PathVariable、@ModelAttribute、@RequestAttribute、@SessionAttribute、@RequestBody、@CookieValue、HttpSes

    Spring boot中定義Json引數解析

    轉載請註明出處。。。 一、介紹 用過springMVC/spring boot的都清楚,在controller層接受引數,常用的都是兩種接受方式,如下 1 /** 2 * 請求路徑 http://127.0.0.1:8080/test 提交型別為application/json 3

    Spring boot中定義Json參數解析

    分享圖片 star 搭建 convert ner 方法註入 DDU handler format 轉載請註明出處。。。 一、介紹 用過springMVC/spring boot的都清楚,在controller層接受參數,常用的都是兩種接受方式,如下 1 /** 2

    Spring Boot前後端分離Instant時間戳定義解析

    在SpringBoot專案中,前後端規定傳遞時間使用時間戳(精度ms). 以上為簡略實體類定義. 在實際使用過程中,發現Incident中的createdTime以及recoveryTime數值不對. 排查故障,前端去除時間戳後三位(即ms數),則時間基本吻合. 因此,可

    29--aspectj-autoproxy解析Spring解析定義標籤

    前兩個小節已經介紹了AOP的一些基礎知識回顧並對靜態代理、JDK動態代理、CGLIB動態代理做了一些簡單的介紹,本節介紹AOP標籤的解析過程。 1.aspectj-autoproxy標籤簡介 使用註解方式應用aop需要在配置檔案中配置<aop:aspect

    32--aspectj-autoproxy解析Spring解析定義標籤

    前面的章節已經介紹了AOP的相關概念和一些知識點,接下來我們就要開始分析SpringAOP的原始碼了,接下來的分析都基於@AspectJ註解。雖然@AspectJ是基於註解的方式實現AOP,但還是要在配置檔案中配置<aop:aspectj-autoprox

    spring 定義解析

    設計配置屬性和JavaBean 編寫XSD檔案 編寫NamespaceHandler和BeanDefinitionParser完成解析工作 編寫spring.handlers和spring.schemas串聯起所有部件 在Bean檔案中應用     會用到N

    AcFunDanmakuParser與DanmakuFlameMaster定義解析

    bilibili刪掉了DanmakuFlameMaster原始碼裡的AcFunDanmakuParser,之前官方(包括目前網上各種教程裡的AcFunDanmakuParser)也已經不適用,而官方給我們的BiliDanmukuParser不支援json,因此我重寫了一個支援json的AcFunDa

    死磕Spring之IoC篇 - 解析定義標籤(XML 檔案)

    > 該系列文章是本人在學習 Spring 的過程中總結下來的,裡面涉及到相關原始碼,可能對讀者不太友好,請結合我的原始碼註釋 [Spring 原始碼分析 GitHub 地址](https://github.com/liu844869663/spring-framework) 進行閱讀 > > Spring 版

    spring boot框架學習8-【幹貨】spring boot的web開發(4)-定義攔截處理權限

    凱哥spring boot spring boot框架 本章節主要內容:通過前面的學習,我們了解並快速完成了spring boot第一個應用。spring boot企業級框架,那麽spring boot怎麽讀取靜態資源?如js文件夾,css文件以及png/jpg圖片呢?怎麽自定義消息轉換器呢?怎麽自定

    【第四十章】Spring Boot 定義攔截

    ram obj pre .config factor ati bean configure 邏輯 1.首先編寫攔截器代碼 package com.sarnath.interceptor; import javax.servlet.http.HttpServlet

    整合spring之後,struts2裏面的定義攔截的invocation.invoke()總是返回input

    put 每次 let 應該 singleton prot 定義 art 多例 這個真的是整死我了,還好看見了一篇博客提示了我, 解決方法:   在spring的bean配置中我沒有設置action的作用域為prototype,也就是多例的,如果不設置則就會是默認的singl

    SpringBoot前後端分離Instant時間戳定義解析

    在SpringBoot專案中,前後端規定傳遞時間使用時間戳(精度ms). @Data public class Incident { @ApiModelProperty(value = "故障ID", example = "1") private Integer id; @ApiMo

    五、定義轉化檢視層之httprequest對像、HttpResponse、JsonRepons

    一、虛擬環境 1 用pychanrm建立--->files-->newproject--->選擇虛擬環境 2 settings-->project建立 3 用命令列建立,詳見https://www.cnblogs.com/liuqingzheng/p

    潤乾報表設計中使用 spring 框架實現定義資料集

    spring是一個開源框架,是為了解決企業應用程式開發複雜性而建立的。在 web 開發環境中經常會與 struts、hibernate聯合起來使用,進行規範的框架結構開發。潤乾中的二次開發也可以與 SSH 框架相結合部署到 web 專案中。本文介紹在設計時沒有啟動 web 服務,在設計器中使用 sp

    Android ViewDragHelper完全解析 定義ViewGroup神器

                         一、概述在自定義ViewGroup中,很多效果都包含使用者手指去拖動其內部的某個View(eg:側滑選單等),針對具體的需要去寫好onInterceptTouchEvent和onTouchEvent這兩個方法是一件很不容易的事,需要自己去處理:多手指的處理、加速度檢測

    Spring Data 官方文件》5.8. 使用定義轉換過載預設對映至5.10. 異常解釋

    “MappingCassandraConverter”檢查是否有任何Spring轉換器可以在這些特殊類試圖對映自身物件之前處理。 為了’hijack’ MappingCassandraConverter’的正常對映策略,或許為了提高效能或其他自定義對映需求,您首先需要建立一個Spring’Converter

    POI解析定義日期格式(標題雖然大眾,但是內容絕非大眾)

    在專案中遇到過一種情況,匯入的時間格式為 yyyy/mm/dd hh:mm:ss,這個很好弄,自定義一下日期格式,並且新增資料有效性。。。。趕著下班,暫時不廢話那麼多了。就是兩種情況:一個是解析自定義日期,還有解釋從別的地方複製過來的日期,雖然也能新增上去,但是後天解析時間資料不對。直接上程式碼,希望有所幫助

    spring boot系統登入實現定義攔截

    在專案中,我們會對使用者請求的url統一處理,此處如果我們不用其他的管理框架,我們可以自定義攔截器,通過控制使用者的請求路徑進而控制使用者的訪問限制 自定義攔截器 /** * 登入攔截器 * @author kexin * @date 2018/11/09 */ public