精华内容
参与话题
问答
  • SpringMVC中的视图和视图解析器

    万次阅读 2016-11-12 22:56:04
    对于控制器的目标方法,无论其返回值是String、View、... Spring MVC 借助视图解析器(ViewResolver)得到最终的视图对象(View),最终的视图可以是JSP也可是Excell、 JFreeChart等各种表现形式的视图。SpringMVC的

      对于控制器的目标方法,无论其返回值是String、View、ModelMap或是ModelAndView,SpringMVC都会在内部将它们封装为一个ModelAndView对象进行返回。
       Spring MVC 借助视图解析器(ViewResolver)得到最终的视图对象(View),最终的视图可以是JSP也可是Excell、
    JFreeChart等各种表现形式的视图。

    SpringMVC的视图解析流程

      SpringMVC的视图解析流程为:
      
    1、调用目标方法,SpringMVC将目标方法返回的String、View、ModelMap或是ModelAndView都转换为一个ModelAndView对象;

    2、然后通过视图解析器(ViewResolver)对ModelAndView对象中的View对象进行解析,将该逻辑视图View对象解析为一个物理视图View对象;

    3、最后调用物理视图View对象的render()方法进行视图渲染,得到响应结果。

    视图(View)

      视图的作用是渲染模型数据,将模型里的数据以某种形式呈现给客户。
      为了实现视图模型和具体实现技术的解耦,Spring在org.springframework.web.servlet包中定义了一个高度抽象的View接口。
      视图对象由视图解析器负责实例化。由于视图是无状态的,所以他们不会有线程安全的问题。所谓视图是无状态的,是指对于每一个请求,都会创建一个View对象。
      JSP是最常见的视图技术。
      
      常用的视图实现类:
      image_1b1ce221b11hn6kv3pv1jj4kcm9.png-351.2kB

    视图解析器(ViewResolver)

      视图解析器的作用是将逻辑视图转为物理视图,所有的视图解析器都必须实现ViewResolver接口。
       SpringMVC为逻辑视图名的解析提供了不同的策略,可以在Spring WEB上下文中配置一种或多种解析策略,并指定他们之间的先后顺序。每一种映射策略对应一个具体的视图解析器实现类。程序员可以选择一种视图解析器或混用多种视图解析器。可以通过order属性指定解析器的优先顺序,order越小优先级越高,SpringMVC会按视图解析器顺序的优先顺序对逻辑视图名进行解析,直到解析成功并返回视图对象,否则抛出ServletException异常。
      
       常用的视图解析器实现类:
       image_1b1ce6cmvcq619dl1fv19i3fg29.png-264.4kB
      
       以下是通过InternalResourceViewResolver作为视图解析器解析,将逻辑视图解析为JSP视图的实例:

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

      若项目中使用了JSTL,则SpringMVC会自动把视图由InternalResourceView转为JstlView。
      

    使用mvc:view-controller不经控制器直接跳转到页面

      若希望直接响应通过SpringMVC渲染的页面,可以使用mvc:view-controller标签实现:

      <!-- 配置直接转发的页面 -->      
    <!-- 可以直接相应转发的页面, 而无需再经过 Handler 的方法.  -->  
        <mvc:view-controller path="/success" view-name="success"/>  

      那么现在可以直接在某一页面中通过请求路径”success”访问到/WEB-INF/views/success.jsp页面(因为我们上面配置了视图解析器将逻辑视图解析为前缀为/WEB-INF/views/,后缀为.jsp的物理视图)。但是,这种情况下通过控制器就无法映射到请求了,需要再进行如下配置:

        <!-- 在实际开发中通常都需配置 mvc:annotation-driven 标签,  之前的页面才不会因为配置了直接转发页面而受到影响 -->  
        <mvc:annotation-driven></mvc:annotation-driven>  

    关于重定向

      一般情况下,控制器方法返回字符串类型的值会被当成逻辑视图名处理,但如果返回的字符串中带forward:或redirect:前缀时,SpringMVC会对它们进行特殊处理:将forward: 和redirect: 当成指示符,其后的字符串作为URL 来处理。示例如下:
      
    index.jsp:

    <a href="${pageContext.request.contextPath }/springmvc/testRedirect">Test Redirect</a>

    controller:

    @Controller
    @RequestMapping("/springmvc")
    public class SpringMVCTest {
    
        @RequestMapping("/testRedirect")
        public String testRedirect() {
            System.out.println("testRedirect");
            return "redirect:/index.jsp";
        }
    }

    即可重定向到index.jsp。也可在redirect:/后添加控制器方法的映射路径,重定向到该目标方法。

    展开全文
  • spring MVC视图解析器

    万次阅读 2017-11-20 22:31:32
    在这篇博客中介绍一下SpringMVC视图解析器。当我们对SpringMVC控制的资源发起请求时,这些请求都会被SpringMVC的DispatcherServlet处理,接着spring会分析看哪一个HandlerMapping定义的所有请求映射中存在对该请求的...

    在这篇博客中介绍一下SpringMVC视图解析器。当我们对SpringMVC控制的资源发起请求时,这些请求都会被SpringMVC的DispatcherServlet处理,接着spring会分析看哪一个HandlerMapping定义的所有请求映射中存在对该请求的最合理的映射。然后通过该HandlerMapping取得其对应的Handler,接着再通过相应的HandlerAdapter处理该Handler。HandlerAdapter在对Handler进行处理之后会返回一个ModelAndView对象。在获得了ModelAndView对象之后,Spring就需要把该View渲染给用户,即返回给浏览器。在这个渲染的过程中,发挥作用的就是ViewResolver和View。当Handler返回的ModelAndView中不包含真正的视图,只返回一个逻辑视图名称的时候,ViewResolver就会把该逻辑视图名称解析为真正的视图View对象。View是真正进行视图渲染,把结果返回给浏览器的。

    ViewResolver和View介绍

    SpringMVC用于处理视图最重要的两个接口是ViewResolver和View。ViewResolver的主要作用是把一个逻辑上的视图名称解析为一个真正的视图,SpringMVC中用于把View对象呈现给客户端的是View对象本身,而ViewResolver只是把逻辑视图名称解析为对象的View对象。View接口的主要作用是用于处理视图,然后返回给客户端。

    Spring为我们提供了非常多的视图解析器,下面将列举一些视图解析器。

    AbstractCachingViewResolver:这是一个抽象类,这种视图解析器会把它曾经解析过的视图保存起来,然后每次要解析视图的时候先从缓存里面找,如果找到了对应的视图就直接返回,如果没有就创建一个新的视图对象,然后把它放到一个用于缓存的map中,接着再把新建的视图返回。使用这种视图缓存的方式可以把解析视图的性能问题降到最低。

    UrlBasedViewResolver:它是对ViewResolver的一种简单实现,而且继承了AbstractCachingViewResolver,主要就是提供的一种拼接URL的方式来解析视图,它可以让我们通过prefix属性指定一个指定的前缀,通过suffix属性指定一个指定的后缀,然后把返回的逻辑视图名称加上指定的前缀和后缀就是指定的视图URL了。如prefix=/WEB-INF/jsps/,suffix=.jsp,返回的视图名称viewName=test/indx,则UrlBasedViewResolver解析出来的视图URL就是/WEB-INF/jsps/test/index.jsp。默认的prefix和suffix都是空串。URLBasedViewResolver支持返回的视图名称中包含redirect:前缀,这样就可以支持URL在客户端的跳转,如当返回的视图名称是”redirect:test.do”的时候,URLBasedViewResolver发现返回的视图名称包含”redirect:”前缀,于是把返回的视图名称前缀”redirect:”去掉,取后面的test.do组成一个RedirectView,RedirectView中将把请求返回的模型属性组合成查询参数的形式组合到redirect的URL后面,然后调用HttpServletResponse对象的sendRedirect方法进行重定向。同样URLBasedViewResolver还支持forword:前缀,对于视图名称中包含forword:前缀的视图名称将会被封装成一个InternalResourceView对象,然后在服务器端利用RequestDispatcher的forword方式跳转到指定的地址。使用UrlBasedViewResolver的时候必须指定属性viewClass,表示解析成哪种视图,一般使用较多的就是InternalResourceView,利用它来展现jsp,但是当我们使用JSTL的时候我们必须使用JstlView。下面是一段UrlBasedViewResolver的定义,根据该定义,当返回的逻辑视图名称是test的时候,UrlBasedViewResolver将把逻辑视图名称加上定义好的前缀和后缀,即“/WEB-INF/test.jsp”,然后新建一个viewClass属性指定的视图类型予以返回,即返回一个url为“/WEB-INF/test.jsp”的InternalResourceView对象。


    Xml代码  
    [html] view plain copy
    1. <bean    
    2.    class="org.springframework.web.servlet.view.UrlBasedViewResolver">    
    3.    <property name="prefix" value="/WEB-INF/" />    
    4.    <property name="suffix" value=".jsp" />    
    5.    <property name="viewClass" value="org.springframework.web.servlet.view.InternalResourceView"/>    
    6. </bean>    

    InternalResourceViewResolver:它是URLBasedViewResolver的子类,所以URLBasedViewResolver支持的特性它都支持。在实际应用中InternalResourceViewResolver也是使用的最广泛的一个视图解析器。那么InternalResourceViewResolver有什么自己独有的特性呢?单从字面意思来看,我们可以把InternalResourceViewResolver解释为内部资源视图解析器,这就是InternalResourceViewResolver的一个特性。InternalResourceViewResolver会把返回的视图名称都解析为InternalResourceView对象,InternalResourceView会把Controller处理器方法返回的模型属性都存放到对应的request属性中,然后通过RequestDispatcher在服务器端把请求forword重定向到目标URL。比如在InternalResourceViewResolver中定义了prefix=/WEB-INF/,suffix=.jsp,然后请求的Controller处理器方法返回的视图名称为test,那么这个时候InternalResourceViewResolver就会把test解析为一个InternalResourceView对象,先把返回的模型属性都存放到对应的HttpServletRequest属性中,然后利用RequestDispatcher在服务器端把请求forword到/WEB-INF/test.jsp。这就是InternalResourceViewResolver一个非常重要的特性,我们都知道存放在/WEB-INF/下面的内容是不能直接通过request请求的方式请求到的,为了安全性考虑,我们通常会把jsp文件放在WEB-INF目录下,而InternalResourceView在服务器端跳转的方式可以很好的解决这个问题。下面是一个InternalResourceViewResolver的定义,根据该定义当返回的逻辑视图名称是test的时候,InternalResourceViewResolver会给它加上定义好的前缀和后缀,组成“/WEB-INF/test.jsp”的形式,然后把它当做一个InternalResourceView的url新建一个InternalResourceView对象返回。


    Xml代码  
    [html] view plain copy
    1. <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">    
    2.    <property name="prefix" value="/WEB-INF/"/>    
    3.    <property name="suffix" value=".jsp"></property>    
    4. </bean>   

    XmlViewResolver:它继承自AbstractCachingViewResolver抽象类,所以它也是支持视图缓存的。XmlViewResolver需要给定一个xml配置文件,该文件将使用和Spring的bean工厂配置文件一样的DTD定义,所以其实该文件就是用来定义视图的bean对象的。在该文件中定义的每一个视图的bean对象都给定一个名字,然后XmlViewResolver将根据Controller处理器方法返回的逻辑视图名称到XmlViewResolver指定的配置文件中寻找对应名称的视图bean用于处理视图。该配置文件默认是/WEB-INF/views.xml文件,如果不使用默认值的时候可以在XmlViewResolver的location属性中指定它的位置。XmlViewResolver还实现了Ordered接口,因此我们可以通过其order属性来指定在ViewResolver链中它所处的位置,order的值越小优先级越高。以下是使用XmlViewResolver的一个示例:

    (1)在SpringMVC的配置文件中加入XmlViewResolver的bean定义。使用location属性指定其配置文件所在的位置,order属性指定当有多个ViewResolver的时候其处理视图的优先级。关于ViewResolver链的问题将在后续内容中讲到。

    Xml代码  收藏代码
    1. <bean class="org.springframework.web.servlet.view.XmlViewResolver">  
    2.    <property name="location" value="/WEB-INF/views.xml"/>  
    3.    <property name="order" value="1"/>  
    4. </bean>  

     

    (2)在XmlViewResolver对应的配置文件中配置好所需要的视图定义。在下面的代码中我们就配置了一个名为internalResource的InternalResourceView,其url属性为“/index.jsp”。


    Xml代码  
    [html] view plain copy
    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"    
    4.     xsi:schemaLocation="http://www.springframework.org/schema/beans    
    5.      http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">    
    6.     <bean id="internalResource" class="org.springframework.web.servlet.view.InternalResourceView">    
    7.        <property name="url" value="/index.jsp"/>    
    8.     </bean>    
    9. </beans>    

     

    (3)定义一个返回的逻辑视图名称为在XmlViewResolver配置文件中定义的视图名称——internalResource。

    Java代码  
    [java] view plain copy
    1. @RequestMapping("/xmlViewResolver")    
    2. public String testXmlViewResolver() {    
    3.    return "internalResource";    
    4. }    


    (4)这样当我们访问到上面定义好的testXmlViewResolver处理器方法的时候返回的逻辑视图名称为“internalResource”,这时候Spring就会到定义好的views.xml中寻找id或name为“internalResource”的bean对象予以返回,这里Spring找到的是一个url为“/index.jsp”的InternalResourceView对象。

    BeanNameViewResolver:这个视图解析器跟XmlViewResolver有点类似,也是通过把返回的逻辑视图名称去匹配定义好的视图bean对象。不同点有二,一是BeanNameViewResolver要求视图bean对象都定义在Spring的application context中,而XmlViewResolver是在指定的配置文件中寻找视图bean对象,二是BeanNameViewResolver不会进行视图缓存。看一个例子,在SpringMVC的配置文件中定义了一个BeanNameViewResolver视图解析器和一个id为test的InternalResourceview bean对象。

    Xml代码  
    [html] view plain copy
    1. <bean class="org.springframework.web.servlet.view.BeanNameViewResolver">    
    2.    <property name="order" value="1"/>    
    3. </bean>    
    4.     
    5. <bean id="test" class="org.springframework.web.servlet.view.InternalResourceView">    
    6.    <property name="url" value="/index.jsp"/>    
    7. </bean>    


    这样当返回的逻辑视图名称是 test的时候,就会解析为上面定义好id为test的InternalResourceView。

    ResourceBundleViewResolver:它和XmlViewResolver一样,也是继承自AbstractCachingViewResolver,但是它缓存的不是视图,这个会在后面有说到。和XmlViewResolver一样它也需要有一个配置文件来定义逻辑视图名称和真正的View对象的对应关系,不同的是ResourceBundleViewResolver的配置文件是一个属性文件,而且必须是放在classpath路径下面的,默认情况下这个配置文件是在classpath根目录下的views.properties文件,如果不使用默认值的话,则可以通过属性baseName或baseNames来指定。baseName只是指定一个基名称,Spring会在指定的classpath根目录下寻找以指定的baseName开始的属性文件进行View解析,如指定的baseName是base,那么base.properties、baseabc.properties等等以base开始的属性文件都会被Spring当做ResourceBundleViewResolver解析视图的资源文件。ResourceBundleViewResolver使用的属性配置文件的内容类似于这样:

    Properties代码  
    [html] view plain copy
    1. resourceBundle.(class)=org.springframework.web.servlet.view.InternalResourceView    
    2. resourceBundle.url=/index.jsp    
    3. test.(class)=org.springframework.web.servlet.view.InternalResourceView    
    4. test.url=/test.jsp    

     

    在这个配置文件中我们定义了两个InternalResourceView对象,一个的名称是resourceBundle,对应URL是/index.jsp,另一个名称是test,对应的URL是/test.jsp。从这个定义来看我们可以知道resourceBundle是对应的视图名称,使用resourceBundle.(class)来指定它对应的视图类型,resourceBundle.url指定这个视图的url属性。会思考的读者看到这里可能会有这样一个问题:为什么resourceBundle的class属性要用小括号包起来,而它的url属性就不需要呢?这就需要从ResourceBundleViewResolver进行视图解析的方法来说了。ResourceBundleViewResolver还是通过bean工厂来获得对应视图名称的视图bean对象来解析视图的。那么这些bean从哪里来呢?就是从我们定义的properties属性文件中来。在ResourceBundleViewResolver第一次进行视图解析的时候会先new一个BeanFactory对象,然后把properties文件中定义好的属性按照它自身的规则生成一个个的bean对象注册到该BeanFactory中,之后会把该BeanFactory对象保存起来,所以ResourceBundleViewResolver缓存的是BeanFactory,而不是直接的缓存从BeanFactory中取出的视图bean。然后会从bean工厂中取出名称为逻辑视图名称的视图bean进行返回。接下来就讲讲Spring通过properties文件生成bean的规则。它会把properties文件中定义的属性名称按最后一个点“.”进行分割,把点前面的内容当做是bean名称,点后面的内容当做是bean的属性。这其中有几个特别的属性,Spring把它们用小括号包起来了,这些特殊的属性一般是对应的attribute,但不是bean对象所有的attribute都可以这样用。其中(class)是一个,除了(class)之外,还有(scope)、(parent)、(abstract)、(lazy-init)。而除了这些特殊的属性之外的其他属性,Spring会把它们当做bean对象的一般属性进行处理,就是bean对象对应的property。所以根据上面的属性配置文件将生成如下两个bean对象:

    Xml代码  
    [html] view plain copy
    1. <bean id="resourceBundle" class="org.springframework.web.servlet.view.InternalResourceView">    
    2.    <property name="url" value="/index.jsp"/>    
    3. </bean>    
    4.     
    5. <bean id="test" class="org.springframework.web.servlet.view.InternalResourceView">    
    6.    <property name="url" value="/test.jsp"/>    
    7. </bean>    

     

    从ResourceBundleViewResolver使用的配置文件我们可以看出,它和XmlViewResolver一样可以解析多种不同类型的View,因为它们的View是通过配置的方式指定的,这也就意味着我们可以指定A视图是InternalResourceView,B视图是JstlView。

    来看下面这个一个例子,我在SpringMVC的配置文件中定义了一个ResourceBundleViewResolver对象,指定其baseName为views,然后order为1。

    Xml代码  
    [html] view plain copy
    1. <bean class="org.springframework.web.servlet.view.ResourceBundleViewResolver">    
    2.    <property name="basename" value="views"/>    
    3.    <property name="order" value="1"/>    
    4. </bean>   

     

    我在classpath的根目录下有两个属性文件,一个是views.properties,一个是views_abc.properties,它们的内容分别如下:

    views.properties

    Properties代码  
    [html] view plain copy
    1. resourceBundle.(class)=org.springframework.web.servlet.view.InternalResourceView    
    2. resourceBundle.url=/index.jsp    
    3. test.(class)=org.springframework.web.servlet.view.InternalResourceView    
    4. test.url=/test.jsp    


    views_abc.properties

    Properties代码  
    [html] view plain copy
    1. abc.(class)=org.springframework.web.servlet.view.InternalResourceView    
    2. abc.url=/abc.jsp   

     

    定义了如下这样一个Controller,它有三个处理器方法。

    Java代码  
    [java] view plain copy
    1. @Controller    
    2. @RequestMapping("/mytest")    
    3. public class MyController {    
    4.     @RequestMapping("resourceBundle")    
    5.     public String resourceBundle() {    
    6.        return "resourceBundle";    
    7.     }    
    8.     
    9.     @RequestMapping("testResourceBundle")    
    10.     public String testResourceBundle() {    
    11.        return "test";    
    12.     }    
    13.     
    14.     @RequestMapping("abc")    
    15.     public String abc() {    
    16.        return "abc";    
    17.     }    
    18.     
    19. }    

     

    那么当我们请求/mytest/resourceBundle.do的时候,ResourceBundleViewResolver会首先尝试着来解析该视图,这里Controller处理器方法返回的逻辑视图名称是resourceBundle,ResourceBundleViewResolver按照上面提到的解析方法进行解析,这个时候它发现它是可以解析的,然后就返回了一个url为/index.jsp的InternalResourceView对象。同样,请求/mytest/testResourceBundle.do返回的逻辑视图test和/mytest/abc.do返回的逻辑视图abc它都可以解析。当我们把basename指定为包的形式,如“com.tiantian.views”,的时候Spring会按照点“.”划分为目录的形式,到classpath相应目录下去寻找basename开始的配置文件,如上面我们指定basename为“com.tiantian.views”,那么spring就会到classpath下的com/tiantian目录下寻找文件名以views开始的properties文件作为解析视图的配置文件。

    FreeMarkerViewResolver、VolocityViewResolver:这两个视图解析器都是UrlBasedViewResolver的子类。FreeMarkerViewResolver会把Controller处理方法返回的逻辑视图解析为FreeMarkerView,而VolocityViewResolver会把返回的逻辑视图解析为VolocityView。因为这两个视图解析器类似,所以这里我就只挑FreeMarkerViewResolver来做一个简单的讲解。FreeMarkerViewResolver和VilocityViewResolver都继承了UrlBasedViewResolver。

    对于FreeMarkerViewResolver而言,它会按照UrlBasedViewResolver拼接URL的方式进行视图路径的解析。但是使用FreeMarkerViewResolver的时候不需要我们指定其viewClass,因为FreeMarkerViewResolver中已经把viewClass定死为FreeMarkerView了。

    我们先在SpringMVC的配置文件里面定义一个FreeMarkerViewResolver视图解析器,并定义其解析视图的order顺序为1。

    Xml代码  
    [html] view plain copy
    1. <bean class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">    
    2.    <property name="prefix" value="fm_"/>    
    3.    <property name="suffix" value=".ftl"/>    
    4.    <property name="order" value="1"/>    
    5. </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”下面的。

    Xml代码  
    [html] view plain copy
    1. <bean class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">    
    2.    <property name="templateLoaderPath" value="/WEB-INF/freemarker/template"/>    
    3. </bean>  
     

     

    接下来我们定义如下一个Controller:

    Java代码  
    [java] view plain copy
    1. @Controller    
    2. @RequestMapping("/mytest")    
    3. public class MyController {    
    4.     
    5.     @RequestMapping("freemarker")    
    6.     public ModelAndView freemarker() {    
    7.        ModelAndView mav = new ModelAndView();    
    8.        mav.addObject("hello""andy");    
    9.        mav.setViewName("freemarker");    
    10.        return mav;    
    11.     }    
    12.     
    13. }   

     

    由上面的定义我们可以看到这个Controller的处理器方法freemarker返回的逻辑视图名称是“freemarker”。那么如果我们需要把该freemarker视图交给FreeMarkerViewResolver来解析的话,我们就需要根据上面的定义,在模板路径下定义视图对应的模板,即在“/WEB-INF/freemarker/template”目录下建立fm_freemarker.ftl模板文件。这里我们定义其内容如下:

    html代码  
    [html] view plain copy
    1. <html>    
    2.     <head>    
    3.        <title>FreeMarker</title>    
    4.     </head>    
    5.     <body>    
    6.        <b>Hello World</b>    
    7.        <font color="red">Hello World!</font>    
    8.        ${hello}    
    9.     </body>    
    10. </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就可以利用该模板文件进行视图的渲染了。所以访问结果应该如下所示:


     

     

    视图解析器链

           在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链的最后面。

     

    Xml代码  
    [html] view plain copy
    1. <bean class="org.springframework.web.servlet.view.XmlViewResolver">    
    2.    <property name="location" value="/WEB-INF/views.xml"/>    
    3.    <property name="order" value="1"/>    
    4. </bean>    
    5.     
    6. <bean    
    7.    class="org.springframework.web.servlet.view.UrlBasedViewResolver">    
    8.    <property name="prefix" value="/WEB-INF/" />    
    9.    <property name="suffix" value=".jsp" />    
    10.    <property name="viewClass" value="org.springframework.web.servlet.view.InternalResourceView"/>    
    11. </bean>  
    展开全文
  • 什么是视图解析器

    2020-07-12 18:25:04
    SpringMVC中的视图解析器的主要作用就是将逻辑视图转换成用户可以看到的物理视图。 当用户对SpringMVC应用程序发起请求时,这些请求都会被SpringMVC的DispatcherServlet处理,通过处理器找到最为合适的...

    SpringMVC中的视图解析器的主要作用就是将逻辑视图转换成用户可以看到的物理视图。

    当用户对SpringMVC应用程序发起请求时,这些请求都会被SpringMVC的DispatcherServlet处理,通过处理器找到最为合适的HandlerMapping定义的请求映射中最为合适的映射,然后通过HandlerMapping找到相对应的Handler,然后再通过相对应的HandlerAdapter处理该Handler。返回结果是一个ModelAndView对象,当该ModelAndView对象中不包含真正的视图,而是一个逻辑视图路径的时候,ViewResolver就会把该逻辑视图路径解析为真正的View视图对象,然后通过View的渲染,将最终结果返回给用户。

    SpringMVC中处理视图最终要的两个接口就是ViewResolver和View,ViewResolver的作用是将逻辑视图解析成物理视图,View的主要作用是调用其render()方法将物理视图进行渲染。

    一般来说,对于SpringMVC控制器中的方法,无论是返回String、View或者是ModelAndView,SpringMVC在内部都会将返回结果封装成ModelAndView对象,然后返回给用户。

    视图解析器需要配置在SpringMVC的配置文件中,如下:

    <!-- 对转向页面的路径解析。prefix:前缀, suffix:后缀 --> 
      <bean id="viewResolver" 
        class="org.springframework.web.servlet.view.InternalResourceViewResolver"> 
        <property name="prefix" value="/page"></property> 
        <property name="suffix" value=".jsp"></property> 
      </bean> 
    

    SpringMVC视图解析器解析流程:

    1、将SpringMVC控制器中的返回结果封装成一个ModelAndView对象。

    2、通过SpringMVC中的视图解析器,使用ViewResolver对控制器返回的ModelAndView对象进行解析,将逻辑视图转换成物理视图。

    3、调用View中的render()方法对物理视图进行渲染。

    展开全文
  • 视图解析器的作用

    千次阅读 2018-08-08 16:43:23
    视图解析器是写在springmvc的配置文件中,在xml中如果没有显式配置该配置文件的名称,那么你的spirngmvc配置文件名称就是&lt;serlvet-name&gt;-servlet.xml, 并且文件自动存放在WEB-INF下;如果显示配置了...

    视图解析器是写在springmvc的配置文件中,在xml中如果没有显式配置该配置文件的名称,那么你的spirngmvc配置文件名称就是<serlvet-name>-servlet.xml,

    并且文件自动存放在WEB-INF下;如果显示配置了,如在xml中<servlet>配置了<param-value>/config/springmvc-config.xml</param-value>,

    那么你的配置文件将存放于/WebContent/config/下,配置文件名称为springmvc-config.xml。

    一般地视图解析器配置如下:

    <bean id="viewResolver"
    class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/jsp/" />
    <property name="suffix" value=".jsp" />
    </bean>

    假如Controller类中返回值为hello,那么根据视图解析器可得将要跳转的页面路径为:/WebContent/jsp/hello.jsp

    这里有一点需要注意:

    视图解析器的作用是只对Controller类中每个函数返回值那里的String类型前后加路径,而不对@RequestMapping处加路径,对@RequestMapping处无影响!

    展开全文
  • 【SSM-SpringMVC】视图解析器

    千次阅读 2019-06-04 20:08:48
    如果想访问一个在webapp下的还有包的目录 ...直接变成“demo” 都需要视图解析器 在spring-servlert.xml中添加视图解析 <bean id="viewResolver" class="org.springframework.web.servlet.vie...
  • 视图解析器 在springmvc中,请求处理执行完成后,最终返回一个ModelAndView对象,即使返回的是Model或者String等类型的处理方法,springm内部也会将他们装配成一个ModelAndView对象,springmvc借助视图解析器...
  • springmvc中的视图解析器详细配置

    千次阅读 2019-01-24 15:06:14
    视图解析器  springmvc中View Resolver负责将处理结果生成View视图,处理器执行完业务逻辑后将带有逻辑视图的ModelAndView返回给前端控制器,前端控制器再将ModelAndView发送给视图解析器视图解析器(View ...
  • SpringMVC中的视图解析器的主要作用就是将逻辑视图转换成用户可以看到的物理视图。 当用户对SpringMVC应用程序发起请求时,这些请求都会被SpringMVC的DispatcherServlet处理,通过处理器找到最为合适的...
  • 视图解析器

    千次阅读 2018-08-20 10:13:23
    ·SpringMVC 使用ViewResource 进行视图解析,在浏览器中渲染模型  ·ViewResolver 能够解析JSP、Velocity 模版和XSLT 等多种视图 ·处理视图最重要的两个接口:  ·ViewResolver接口在视图...常见的视图解析器...
  • 1. 视图解析器定义 把一个逻辑上的视图名称解析为一个真正的视图名称解析成一个真正的视图,即将逻辑视图的名称解析为具体的 View 对象, 让View对象去处理视图,并将带有返回数据的视图反馈给客户端。 视图解析器...
  • springBoot配置视图解析器

    千次阅读 2020-03-17 15:57:29
    1.直接写一个配置类继承WebMvcConfigurerAdapter即可 具体代码如下: package com.boot.zhiyi.config; import org.springframework.context.annotation.Configuration; import org.springframework.core.Ordered; ...
  • 今天springboot尝试配置视图解析器的时候,如图: ![在这里插入图片描述](https://img-blog.csdnimg.cn/20190411205709241.png) ![在这里插入图片描述](https://img-blog.csdnimg.cn/20190411205722368.png) ![在...
  • 因项目要求,需要同时支持html和jsp页面,所以在springboot的基础上配置视图解析器。 重点在于,抛开原来的resources目录结构层,这层只放application.properties文件和logback-spring.xml文件 将html和jsp统一...
  • Springboot视图解析器配置 #spring.thymeleaf.cache = true #启用模板缓存。 #spring.thymeleaf.check-template = true #在呈现模板之前检查模板是否存在。 #spring.thymeleaf.check-template-location = true #...
  • 1、问题排查 在整合SpringBoot与Httl... 通过断点调试,访问url时,能进入到我们自定义的接口方法,所以此处可以断定该404错误是由视图解析器无法渲染返回的view所造成的。 继续往下调式,当到了DispatcherServle...
  • 这两天自己写项目,到视图解析器怎么配置都不管用,按网上说的加spring.mvc.view.prefix也不好使,后来发现并不是通用的,被坑了一把: 以下是在application.properties里的配置(只要是yml或是properties里就行) #...
  • springboot视图解析器

    万次阅读 2017-12-08 10:58:02
    启动@SpringBootApplication public class ApplicationRun { public static void main(String[] args) { SpringApplication.run(ApplicationRun.class, args); } }配置类@Configuration @EnableWebMvc pub
  • 1.启动 package com.wang; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; //主入口@SpringBootApplication:标注这个类是一个...
  • spring boot中配置jsp视图解析器

    千次阅读 2018-06-11 22:03:09
    启动@SpringBootApplication public class ApplicationRun { public static void main(String[] args) { SpringApplication.run(ApplicationRun.class, args); } }1234567配置类@Configuration @Enable...
  • SpringBoot的自动装配装配了视图解析器了吗? SpringBoot使用JSP SpringBoot中使用Thymeleaf SpringBoot中使用Freemark SpringBoot的自动装配装配了视图解析器了吗? 我们可以看到SpringBoot自动装配的...

空空如也

1 2 3 4 5 ... 20
收藏数 169,327
精华内容 67,730
关键字:

视图解析器