分享

开发Spring自定义视图和视图解析器

 千水流水门 2013-04-28
摘要:开发复合视图解析器 由于本例需要支持 SWF 及自定义后缀名的文件,所以我们期望能够根据不同请求的后缀名来调用不同的视图解析器。实际上,Spring 已经提供了类似的视图解析器-ContentNegotiatingViewResolver,它
开发复合视图解析器

由于本例需要支持 SWF 及自定义后缀名的文件,所以我们期望能够根据不同请求的后缀名来调用不同的视图解析器。实际上,Spring 已经提供了类似的视图解析器-ContentNegotiatingViewResolver,它可以根据请求的文件后缀名或请求的 Accept 头来查找视图。ContentNegotiatingViewResolver 本身并不负责查找视图,它只是将视图查找工作代理给所注册的视图解析器,清单 3 给出了 ContentNegotiatingViewResolver 的配置文件片段。

清单 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> 

从清单 3 可以发现,在使用 ContentNegotiatingViewResolver 时,一般需要配置三个部分:

  1. 注册所支持的媒体类型,也就是文件后缀名及其对应的文件内容类型。
  2. 视图解析器,也就是 ContentNegotiatingViewResolver 在查找视图时,实际所代理使用的视图解析器。
  3. 默认视图,当视图解析器没有查找到合适的视图时,将使用该默认视图。

关于 ContentNegotiatingViewResolver 的具体使用,读者可以参见 Spring 官方文档。

本例开发的复合视图解析器和 ContentNegotiatingViewResolver 类似,虽然本例也可以使用 ContentNegotiatingViewResolver 来实现相同的功能,但 ContentNegotiatingViewResolver 较为复杂,它在查找视图时,会将所有注册到 ContentNegotiatingViewResolver 下的视图解析器全部调用一遍,然后将所有查找到的视图保存为候选视图,最后再根据筛选条件,筛选出一个最为合适的视图。而本例中的复合视图解析器则简单实用的多,只需要注册文件后缀名和对应的视图解析器即可,当为请求找到相应的视图解析器时,便直接调用该视图解析器,而不需调用其所注册的所有视图解析器,清单 4 给出了在 Spring 配置文件中对该复合视图解析的配置文件片段。

清单 4. 复合视图解析器配置片段

				 
 <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> 

在配置文件中,我们为不同的文件后缀名注册了相应的视图解析器,并为该视图解析器配置了所对应查找的视图类。同 ContentNegotiatingViewResolver 类似,本例中的复合视图解析器 MultipleViewResolver 也是将具体的视图查找工作代理给所注册的视图解析器,实际上,MultipleViewResolver 也是一个普通的视图解析器,不过在核心方法 loadView(如清单 5)中,首先获得请求视图的后缀名,然后根据后缀名获得所注册的视图解析器,最后,再使用获得的视图解析器查找视图。

清单 5 .MultipleViewResolver 代码片段

				 
 @Override 
 protected View loadView(String viewName, Locale locale) throws Exception { 
 String fileExtension = StringUtils.getFilenameExtension(viewName); 
 // 返回 null 如果没有后缀名,以便下一个 resolver 处理
 if (fileExtension == null) { 
 return null; 
 } 
 // 通过后缀名获取 resolver 
 ViewResolver resolver = resolvers.get(fileExtension); 
 //return null to invoke next resolver if no resolver found 
 return resolver == null ? null : resolver.resolveViewName(viewName, 
 locale); 

 } 

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多