springmvc解析器使用总结

转载于:点击打开链接

</pre><span style="font-size:18px;">一、序言</span><p></p><p><span style="white-space:pre"></span><span style="font-size:12px">springmvc中,请求在Controller中处理完成后,通常会将处理结果封装为一个ModelAndView对象,返回到浏览器中进行展示。当ModelAndView对象中不包含具体视图,只包含一个视图逻辑名时,需要利用视图解析器ViewResolver将名称解析为真正的View对象,再经由浏览器渲染展示。</span></p><p></p><p><span style="font-size:18px;">二、常用视图解析器</span></p><p style="text-indent:28px">1、<span style="font-size:12px">AbstractCachingViewResolver<span style="font-family:SimSun,宋体,tahoma,arial,helvetica,sans-serif"><span style="line-height:25.2000007629395px">。视图解析抽象基类,具有缓存功能,可以把其解析过的视图保存起来。解析器解析视图时,先从缓存Map中寻找是否已保存有该视图,有则通过loadView方法直接从缓存中载入视图。而当ModelAndView中返回视图名称未被解析过时,该解析器创建一个新的View对象,并将其保存至一个用于缓存的Map中,然后才将视图返回。通过这种工作方式能够大大提高解析器性能提高。</span></span></span></p><p style="text-indent:28px"><span style="font-size:12px"><span style="font-family:SimSun,宋体,tahoma,arial,helvetica,sans-serif"><span style="line-height:25.2000007629395px"></span></span></span></p><pre name="code" class="java">private Map<String, View> viewMap;

	protected View loadView(String viewName, Locale locale) throws Exception
	{
		if (viewMap != null)
		{
			for (Map.Entry<String, View> entry : viewMap.entrySet())
			{
				if (viewName.startsWith(entry.getKey()))
				{
					return entry.getValue();
				}
			}
		}
		return null;
	}


2、UrlBasedViewResolver。主要提供一种拼接url的方式来解析视图。以指定的前缀prefix、后缀suffix和返回视图名称viewName三者拼接而成。例如,prefix="/WEB-INF/jsp/",suffix=".jsp",viewName="index",则返回视图为:"/WEB-INF/jsp/index.jsp"。

3、InternalResourceViewResolver。内部资源视图解析器继承了UrlBasedViewResolver,同样以url拼接方式解析视图,使用最为广泛。

<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
		p:prefix="/WEB-INF/jsp/" p:suffix=".jsp" />


   4、XmlViewResolver。该解析器继承至AbstractCachingViewResolver,支持缓存。该解析器需要指定一个xml配置文件,该配置文件中定义了视图的bean对象,解析器根据视图名称在xml配置文件中找到具有同样名称或id的bean对象,调用相应class方法解析视图。

<bean class="org.springframework.web.servlet.view.XmlViewResolver">
    <property name="location" value="/WEB-INF/views.xml"/>
    <property name="order" value="1"/>
</bean>

views.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
     http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
    <bean id="internalResource" class="org.springframework.web.servlet.view.InternalResourceView">
       <property name="url" value="/index.jsp"/>
    </bean>
</beans>


当Controller中返回"internalResource"时,解析器在views.xml配置文件中找到相应bean,调用InternalResourceView方法处理该视图。


5、FreeMarkerViewResolver和VolocityViewResolver。这两种视图解析器都继承至UrlBasedViewResolver,使用方法类似。以FreeMarkerViewResolver为例,解析器定义了前、后缀,以及解析顺序,通过url拼接方式指定FreeMarkerView视图。

<bean class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
       <property name="prefix" value="fm_"/>
       <property name="suffix" value=".ftl"/>
       <property name="order" value="1"/>
    </bean>
那么当我们请求的处理器方法返回一个逻辑视图名称viewName的时候,就会被该视图处理器加上前后缀解析为一个url为“fm_viewName.ftl”的FreeMarkerView对象。对于FreeMarkerView我们需要给定一个FreeMarkerConfig的bean对象来定义FreeMarker的配置信息。FreeMarkerConfig是一个接口,Spring已经为我们提供了一个实现,它就是FreeMarkerConfigurer。我们可以通过在SpringMVC的配置文件里面定义该bean对象来定义FreeMarker的配置信息,该配置信息将会在FreeMarkerView进行渲染的时候使用到。对于FreeMarkerConfigurer而言,我们最简单的配置就是配置一个templateLoaderPath,告诉Spring应该到哪里寻找FreeMarker的模板文件。这个templateLoaderPath也支持使用“classpath:”和“file:”前缀。当FreeMarker的模板文件放在多个不同的路径下面的时候,我们可以使用templateLoaderPaths属性来指定多个路径。在这里我们指定模板文件是放在“/WEB-INF/freemarker/template”下面的。

    <bean class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
       <property name="templateLoaderPath" value="/WEB-INF/freemarker/template"/>
    </bean>
接下来我们定义如下一个Controller:

@Controller
@RequestMapping("/mytest")
public class MyController {

    @RequestMapping("freemarker")
    public ModelAndView freemarker() {
       ModelAndView mav = new ModelAndView();
       mav.addObject("hello", "andy");
       mav.setViewName("freemarker");
       return mav;
    }

}


由上面的定义我们可以看到这个Controller的处理器方法freemarker返回的逻辑视图名称是“freemarker”。那么如果我们需要把该freemarker视图交给FreeMarkerViewResolver来解析的话,我们就需要根据上面的定义,在模板路径下定义视图对应的模板,即在“/WEB-INF/freemarker/template”目录下建立fm_freemarker.ftl模板文件。这里我们定义其内容如下:
<html>
    <head>
       <title>FreeMarker</title>
    </head>
    <body>
       <b>Hello World</b>
       <font color="red">Hello World!</font>
       ${hello}
    </body>
</html>
经过上面的定义当我们访问/mytest/freemarker.do的时候就会返回一个逻辑视图名称为“freemarker”的ModelAndView对象,根据定义好的视图解析的顺序,首先进行视图解析的是FreeMarkerViewResolver,这个时候FreeMarkerViewResolver会试着解析该视图,根据它自身的定义,它会先解析到该视图的URL为fm_freemarker.ftl,然后它会看是否能够实例化该视图对象,即在定义好的模板路径下是否有该模板存在,如果有则返回该模板对应的FreeMarkerView。在这里的话/WEB-INF/freemarker/template目录下是存在模板文件fm_freemarker.ftl的,所以会返回一个url为fm_freemarker.ftl的FreeMarkerView对象。接着FreeMarkerView就可以利用该模板文件进行视图的渲染了。所以访问结果应该如下所示:
Hello World! Hello World! andy


6、其他。包括BeanNameViewResolver、ResourceBundleViewResolver。


三、视图解析链



在SpringMVC中可以同时定义多个ViewResolver视图解析器,然后它们会组成一个ViewResolver链。当Controller处理器方法返回一个逻辑视图名称后,ViewResolver链将根据其中ViewResolver的优先级来进行处理。所有的ViewResolver都实现了Ordered接口,在Spring中实现了这个接口的类都是可以排序的。在ViewResolver中是通过order属性来指定顺序的,默认都是最大值。所以我们可以通过指定ViewResolver的order属性来实现ViewResolver的优先级,order属性是Integer类型,order越小,对应的ViewResolver将有越高的解析视图的权利,所以第一个进行解析的将是ViewResolver链中order值最小的那个。当一个ViewResolver在进行视图解析后返回的View对象是null的话就表示该ViewResolver不能解析该视图,这个时候如果还存在其他order值比它大的ViewResolver就会调用剩余的ViewResolver中的order值最小的那个来解析该视图,依此类推。当ViewResolver在进行视图解析后返回的是一个非空的View对象的时候,就表示该ViewResolver能够解析该视图,那么视图解析这一步就完成了,后续的ViewResolver将不会再用来解析该视图。当定义的所有ViewResolver都不能解析该视图的时候,Spring就会抛出一个异常。
       基于Spring支持的这种ViewResolver链模式,我们就可以在SpringMVC应用中同时定义多个ViewResolver,给定不同的order值,这样我们就可以对特定的视图特定处理,以此来支持同一应用中有多种视图类型。注意:像InternalResourceViewResolver这种能解析所有的视图,即永远能返回一个非空View对象的ViewResolver一定要把它放在ViewResolver链的最后面。

    <bean class="org.springframework.web.servlet.view.XmlViewResolver">
       <property name="location" value="/WEB-INF/views.xml"/>
       <property name="order" value="1"/>
    </bean>

    <bean
       class="org.springframework.web.servlet.view.UrlBasedViewResolver">
       <property name="prefix" value="/WEB-INF/" />
       <property name="suffix" value=".jsp" />
       <property name="viewClass" value="org.springframework.web.servlet.view.InternalResourceView"/>
    </bean>


四、全局异常解析

程序出现代码异常,或事务性异常时,需要通过异常解析器将捕捉到的异常信息以用户易懂的方式在浏览器上显示。自定义解析器通常继承至SimpleMappingExceptionResolver类。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值