关于 spring 视图解析器

 

1.视图解析器顺序,order order 越小,优先级越高

2.多个视图解析器,会按顺序解析视图,解析不成功会交给下一个解析器,所以最好把jsp解析器放在最后

3.多个InternalResourceViewResolver 会报404错误,原因:此处我们使用了InternalResourceViewResolver,其有一个buildView方法,该方法一定会创建一个View;所以呢View永远不为null(即使该jsp不存在);问题就是出在这;因为我们使用这个的时候默认是使用servlet forward转发的,此时并不知道该jsp是否存在。

viewNames属性,来指定一个是否可以处理的规则。 也可以:

罪魁祸首 就是spring实现checkResource()该方法时返回true,这样相当于view总是存在,从而导致其余视图解析器无法得到解析机会。 

  1. public class IcomJstlView extends JstlView {  
  2.   
  3.     public boolean checkResource(Locale locale) throws Exception {  
  4.         File file = new File(this.getServletContext().getRealPath("/")+getUrl());  
  5.         return file.exists();//判断该jsp页面是否存在  
  6.     }  
  7. }  

覆盖该方法,应该就可以了。 

Java代码  

  1. public class IcomJstlView extends JstlView {  
  2.   
  3.     public boolean checkResource(Locale locale) throws Exception {  
  4.         File file = new File(this.getServletContext().getRealPath("/")+getUrl());  
  5.         return file.exists();//判断该jsp页面是否存在  
  6.     }  
  7. }  

 

 

多种解析器

<!--启动springmvc注解spring3.0以后值需要这一句,不需要下面2个
-->
 <mvc:annotation-driven>
 </mvc:annotation-driven>
 <!-- 注模式下方法映射的处理类<beanclass="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"></bean>-->
 <!-- 注解模式下类的映射处理类<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"></bean>-->

 <!-- 自动扫描的包名-->
 <context:component-scanbase-package="com.zms2015.ssh2.controller"></context:component-scan>
  
    <!—freemark配置 -->
       <bean class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer"> 
           <propertyname="templateLoaderPath" value="/WEB-INF/view/"/>    <!—freemark模板路径 -->
           <propertyname="defaultEncoding" value="UTF-8" /> 
             <property name="freemarkerSettings">
     <props>
      <propkey="template_update_delay">10</prop>
      <propkey="locale">zh_CN</prop>
      <propkey="datetime_format">yyyy-MM-dd</prop>
      <propkey="date_format">yyyy-MM-dd</prop>
      <propkey="number_format">#.##</prop>
     </props>
         </property> 
     </bean>  
     <!—freemark解析器 -->
     <beanclass="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver"> 
              <property name="suffix" value=".ftl"/>
     <property name="contentType"value="text/html;charset=UTF-8" />
     <propertyname="requestContextAttribute" value="rc" />
     <propertyname="exposeRequestAttributes" value="true" />
     <propertyname="exposeSessionAttributes" value="true" />
     <propertyname="exposeSpringMacroHelpers" value="true" />
               <property name="order" value="1"/>
   </bean>  
 
       <!-- jsp的解析器 -->
       <beanclass="org.springframework.web.servlet.view.InternalResourceViewResolver">
              <!--JSP如果使用了jstl 需要加viewclass -->
     <property name="viewClass"value="org.springframework.web.servlet.view.JstlView"  />
           <propertyname="prefix" value="/WEB-INF/page/"/> 
            <propertyname="suffix" value=".jsp"/> 
            <propertyname="order" value="2" />
   </bean>  
 

 <!-- 支持多视图的解析器  需要一个views.properties配置返回的视图名和转换器不搞这个
  <beanclass="org.springframework.web.servlet.view.ResourceBundleViewResolver"> 
          配置文件名 path: views.properties  
   <property name="basename"value="views" /> 
   <property name="order" value="3" />
  </bean> 
  -->
  
  
 <!-- 文件上传解析器id
必须为multipartResolver-->
 <bean id="multipartResolver"
  class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
  <property name="defaultEncoding"value="utf-8"></property>
  <property name="maxUploadSize"value="10485760" />
 </bean>

 

 <!-- json转换器换成了gson, 3.x是用jackson
-->
 <bean id="jsonConverter"
  class="org.springframework.http.converter.json.GsonHttpMessageConverter">
  <property name="supportedMediaTypes"value="application/json" />
 </bean>

 <!--<beanclass="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
  <property name="messageConverters"> <list><ref bean="jsonConverter" /> </list>
  </property> </bean> -->

 <!-- 拦截器-->
 <!-- <mvc:interceptors> <beanclass="com.core.mvc.MyInteceptor" /> </mvc:interceptors>-->

 <!--对静态资源文件的访问(二选一) -->
 <!-- 方案一-->
 <!-- <mvc:default-servlet-handler/> -->
 <!-- 方案二-->
 <mvc:resources mapping="/images/**"location="/images/"
  cache-period="31556926" />
 <mvc:resources mapping="/js/**" location="/js/"
  cache-period="31556926" />
 <mvc:resources mapping="/css/**" location="/css/"
  cache-period="31556926" />
 <mvc:resources location="/upload/"mapping="/upload/**" />

</beans> 

 

关于多个InternalResourceViewResolver视图解析器,会报404错误

假设我有两个jsp:

Java代码  

1. WEB-INF/html/a.jsp  

2. WEB-INF/report/b.jsp  

 

且我配置了视图解析器:

Java代码  

1. <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" p:order="1">  

2.     <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>  

3.     <property name="contentType" value="text/html"/>  

4.     <property name="prefix" value="/WEB-INF/html/"/>  

5.     <property name="suffix" value=".jsp"/>  

6. </bean>  

7.   

8. <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" p:order="2">  

9.     <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>  

10.     <property name="contentType" value="text/html"/>  

11.     <property name="prefix" value="/WEB-INF/report/"/>  

12.     <property name="suffix" value=".jsp"/>  

13. </bean>  

 

 

然后呢,我分别返回视图名为a和b;为什么a能找到,而b的时候是404;我配置了两个视图解析器,第一个找不到的话,第二个能找到啊?遇到过这个问题的朋友基本上会有类似的问题;

 

2、分析

此处我们使用了InternalResourceViewResolver,其有一个buildView方法,该方法一定会创建一个View;所以呢View永远不为null(即使该jsp不存在);问题就是出在这;因为我们使用这个的时候默认是使用servlet forward转发的,此时并不知道该jsp是否存在。

 

3、解决方案:

3.1、最简单的办法是使用其viewNames属性,来指定一个是否可以处理的规则;

Java代码  

1. <property name="viewNames" value="html*"/>  

2. <property name="viewNames" value="report*"/>  

 如上两个的意思是对html或report开头的视图名进行处理,比如返回的视图名为html/a 那么会交给viewNames为html*的那个解析器处理;支持的规则可以查看javadoc。

 

 

3.2、内容协商,根据请求时的MediaType来决定使用哪个View;比如根据不同的MediaType决定是JSON/XML/HTML展示时;可以搜索ContentNegotiatingViewResolver了解;

 

以上的方式对于请求的MediaType一样,且视图名没有规则时一点用没有。

 

3.3、如果仅有几个不同的视图需要特殊处理;可以考虑直接返回View对象进行处理;而直接不走ViewResolver;

 

3.4、如果以上都不满足;那只能自己实现自己相应的ViewResolver,可以覆盖两个方法进行处理:

3.4.1、覆盖UrlBasedViewResolver子类的canHandle;来决定哪些视图名不需要当前ViewResolver进行处理;自己可以得到prefix + suffix进行判断具体的视图页面是否存在,当然这个可能会存在性能问题;考虑做缓存。

 

时间: 2024-08-31 11:52:49

关于 spring 视图解析器的相关文章

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

Spring 视图和视图解析器简介 什么是 Spring 视图和视图解析器 Spring MVC(Model View Controller)是 Spring 中一个重要的组成部分,而 Spring 视图和视图解析器则是 Spring MVC 中的组成部分.在介绍 Spring 视图和视图解析器前,我们先了解下在 Spring MVC 框架中,一个 Web 请求所需经历 的六个阶段: 请求会首先被 Spring MVC 的前端请求分发器(Dispatcher)拦截.该拦截器是一个 Servlet

Spring 视图和视图解析器简介

什么是 Spring 视图和视图解析器? Spring MVC(Model View Controller)是 Spring 中一个重要的组成部分,而 Spring 视图和视图解析器则是 Spring MVC 中的组成部分.在介绍 Spring 视图和视图解析器前,我们先了解下在 Spring MVC 框架中,一个 Web 请求所需经历的六个阶段: 请求会首先被 Spring MVC 的前端请求分发器(Dispatcher)拦截.该拦截器是一个 Servlet, 需要在 web.xml 中配置,

Spring 3.0默认多种视图和视图解析器概述

本文将通过一个示例来介绍如何开发 Spring 自定义视图和视图解析器,来显示后缀名为 SWF 的视图,并提供一个简单的注册机制,为特定后缀名的视图注册相应的视图解析器. 什么是 Spring 视图和视图解析器 Spring MVC(Model View Controller)是 Spring 中一个重要的组成部分,而 Spring 视图和视图解析器则是 Spring MVC 中的组成部分.在介绍 Spring 视图和视图解析器前,我们先了解下在 Spring MVC 框架中,一个 Web 请求

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

本文将通过一个示例来介绍如何开发 Spring 自定义视图和视图解析器,来显示后缀名为 SWF 的视图,并提供一个简单的注册机制,为特定后缀名的视图注册相应的视图解析器. 什么是 Spring 视图和视图解析器 Spring MVC(Model View Controller)是 Spring 中一个重要的组成部分,而 Spring 视图和视图解析器则是 Spring MVC 中的组成部分.在介绍 Spring 视图和视图解析器前,我们先了解下在 Spring MVC 框架中,一个 Web 请求

SpringMVC中ModelAndView对象与“视图解析器”

spring MVC这个环境中,Spring MVC会依据controller(或者你叫它handler)中处理方法的返回值,进行解析,解析之后提供一个视图,作为响应. 标注了@Controller的处理器,实际上本质是一个POJO,你标注了@Controller,我就高看你一眼.但你的形态就是一个java代码文件. 你作为一个java的土土的文件,你里面处理方法的返回值,也就是return语句,返回了一个东西.这个东西可以是String 也可以是 ModelAndView对象.这就是标注了@C

Spring MVC视图解析器:Spring MVC XmlViewResolver示例

在Spring MVC中,使用XmlViewResolver基于XML文件中的视图bean来解析"视图名称".默认地,XmlViewResolver将从/WEB-INF/views.xml中加载视图bean,不过,这个位置可以通过"location"属性覆盖: <beans ...> <bean class="org.springframework.web.servlet.view.XmlViewResolver"> &l

Spring MVC 中自定义视图 @Component 及 配置 多个视图解析器 Excel视图

首先我们建立一个自己的View实现View接口.要注意在类上面加上@Component的注解,因为看BeanNameViewResolver的源码知道,是直接从ioc容器里面拿的根据名字拿的视图,所以我们得把我们自己写的视图放到容器里面. HelloView.java package com.hust.springmvc.views; import java.util.Date; import java.util.Map; import javax.servlet.http.HttpServle

spring mvc-Spring MVC集成velocity视图解析器问题

问题描述 Spring MVC集成velocity视图解析器问题 小弟最近学习搭建Spring MVC框架的web应用,工具是Myeclipse10,在配置velocity的视图解析器时遇见1奇怪问题,烦请高手解答.问题简述:项目搭建完毕启动访问url后,最初是报 找不到layout.vm这个文件而出错,在项目里面新建该文件后,后台无报错了,但是无论Action返回视图a或b,最终都会显示layout里面的内容,从而达不到页面跳转的目的.下面附上几张项目配置的图片供参考.项目文件结构:web.x

Spring MVC视图解析器:配置多个视图解析器的优先级

问题 在Spring MVC应用程序中,我们经常需要应用一些视图解析器策略来解析视图名称.例如,联合使用三个视图解析器:InternalResourceViewResolver.ResourceBundleViewResolver和XmlViewResolver. 但是,如果返回了一个视图的名称,那么,使用哪一个视图解析器策略? 解决方法 如果应用了多个视图解析器策略,那么就必须通过"order"属性来声明优先级,order值越低,则优先级越高.例如: 1 2 3 4 5 6 7 8