SpringMVC同時支援多檢視(JSP,Velocity,Freemarker等)的一種思路實現
阿新 • • 發佈:2019-01-09
第一種方式:
在基於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) throwsException { 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就可以了。
皆驗證通過。
第二種方式
<?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
<?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:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">
<context:component-scan base-package="test.**.controller"
use-default-filters="false">
<context:include-filter type="annotation"
expression="org.springframework.stereotype.Controller" />
</context:component-scan>
<mvc:default-servlet-handler />
<mvc:resources location="/resources/" mapping="/resources/**" />
<mvc:annotation-driven>
<!-- <mvc:argument-resolvers> <bean class="org.springframework.data.web.PagedResourcesAssemblerArgumentResolver"
/> </mvc:argument-resolvers> -->
<mvc:message-converters>
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>text/plain;charset=UTF-8</value>
<value>text/html;charset=UTF-8</value>
</list>
</property>
</bean>
<bean
class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>text/html;charset=UTF-8</value>
<value>application/json;charset=UTF-8</value>
</list>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver" />
<!-- FreeMarker檢視解析 如返回student。。在這裡配置字尾名ftl和檢視解析器。。-->
<bean id="freemarkerConfig"
class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
<property name="templateLoaderPath">
<value>/WEB-INF/ftl/</value>
</property>
<property name="defaultEncoding" value="UTF-8" />
<property name="freemarkerVariables">
<map>
<entry key="xml_escape" value-ref="fmXmlEscape" />
</map>
</property>
<property name="freemarkerSettings">
<props>
<!--<prop key="template_update_delay">3600</prop> -->
<prop key="tag_syntax">auto_detect</prop>
<!-- 設定標籤型別 兩種:[] 和 <> 。[] 這種標記解析要快些 -->
<prop key="default_encoding">UTF-8</prop>
<prop key="output_encoding">UTF-8</prop>
<prop key="locale">zh_CN</prop>
<prop key="date_format">yyyy-MM-dd</prop>
<prop key="time_format">HH:mm:ss</prop>
<prop key="datetime_format">yyyy-MM-dd HH:mm:ss</prop>
<prop key="number_format">#.##</prop>
<!-- 設定數字格式 以免出現 000.00 -->
<prop key="classic_compatible">true</prop>
<!-- 可以滿足一般需要。預設情況變數為null則替換為空字串,如果需要自定義,寫上${empty!"EmptyValue of fbysss"}的形式即可 -->
<prop key="template_exception_handler">html_debug</prop>
<!-- ignore,debug,html_debug,rethrow -->
</props>
</property>
</bean>
<bean id="fmXmlEscape" class="freemarker.template.utility.XmlEscape" />
<bean id="viewResolver"
class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
<property name="viewClass"
value="org.springframework.web.servlet.view.freemarker.FreeMarkerView"></property>
<property name="suffix" value=".ftl" />
<property name="contentType" value="text/html;charset=utf-8" />
<property name="exposeRequestAttributes" value="true" />
<property name="exposeSessionAttributes" value="true" />
<property name="exposeSpringMacroHelpers" value="true" />
<property name="order" value="0" />
</bean>
<!-- -->
<!-- Velocity -->
<bean id="velocityConfig"
class="org.springframework.web.servlet.view.velocity.VelocityConfigurer">
<property name="configLocation" value="/WEB-INF/classes/velocity.properties" />
<property name="resourceLoaderPath" value="/WEB-INF/vm/" />
</bean>
<bean id="velocityViewResolver"
class="org.springframework.web.servlet.view.velocity.VelocityViewResolver">
<property name="order" value="1" />
<property name="contentType" value="text/html;charset=UTF-8" />
<property name="requestContextAttribute" value="req" />
<property name="suffix" value=".vm"/>
</bean>
<!-- -->
<bean id="beanNameViewResolver"
class="org.springframework.web.servlet.view.BeanNameViewResolver">
<property name="order" value="6"/>
</bean>
<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" />
<property name="order" value="10"/>
</bean>
<!-- <bean id="viewResolver"
class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="defaultContentType" value="application/json" />
<property name="mediaTypes">
<map>
<entry key="html" value="text/html" />
<entry key="json" value="application/json" />
<entry key="xml" value="application/xml" />
<entry key="excel" value="application/excel" />
<entry key="pdf" value="application/pdf" />
</map>
</property>
<property name="viewResolvers">
<list>
<bean
class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
<property name="viewClass"
value="org.springframework.web.servlet.view.freemarker.FreeMarkerView"></property>
<property name="suffix" value=".ftl" />
<property name="contentType" value="text/html;charset=utf-8" />
<property name="exposeRequestAttributes" value="true" />
<property name="exposeSessionAttributes" value="true" />
<property name="exposeSpringMacroHelpers" value="true" />
</bean>
<bean
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>
</list>
</property>
<property name="defaultViews">
<list>
<bean
class="org.springframework.web.servlet.view.json.MappingJackson2JsonView">
<property name="prettyPrint" value="true" />
<property name="contentType" value="text/plain" />
</bean>
</list>
</property>
</bean>
-->
<!--定義異常處理頁面 -->
<bean id="exceptionResolver"
class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="exceptionMappings">
<props>
<prop key="java.lang.Exception">outException</prop>
</props>
</property>
</bean>
</beans>