天天看点

springMVC4(13)视图解析器分类详解

。下一步,视图对象往往会对模型进一步渲染,再由视图解析器进一步解析并向前端发出响应。在下面,我们详细介绍视图和视图解析器的各种分类。

在view接口中,定义了一个核心方法是:

它的作用主要是渲染模型数据,整合web资源,并以特定形式响应给客户,这些形式可以是复杂jsp页面,也可以是简单的json、xml字符串。

针对不同的响应形式,spring为我们设计了不同的view实现类:

springMVC4(13)视图解析器分类详解

针对不同的视图对象,我们使用不同的视图解析器来完成实例化工作。我们可以在spring上下文配置多个视图解析器,并通过order属性来指定他们之间的解析优先级顺序,order 越小,对应的 viewresolver 将有越高的解析视图的权利。当一个 viewresolver 在进行视图解析后返回的 view 对象是 null 的话就表示该 viewresolver 不能解析该视图,这时候就交给优先级更低的进行解析,直到解析工作完成,如果所有视图解析器都不能完成将解析,则会抛出异常。

类似于视图,spring也为我们提供了众多的视图解析器实现类:

springMVC4(13)视图解析器分类详解

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

它继承了abstractcachingviewresolver ,通过prefix、suffix**拼接 url** 的方式来解析视图,支持返回的视图名称中包含 redirect: 、forward等前缀进行重定向或转发。使用 urlbasedviewresolver 的时候必须指定属性 viewclass ,表示解析成哪种视图,一般使用较多的就是 internalresourceview ,利用它来展现 jsp ,但是当我们使用 jstl 的时候我们必须使用 jstlview 。下面是一段 urlbasedviewresolver 的实例定义:

它是 urlbasedviewresolver 的子类,所以 urlbasedviewresolver 支持的特性它都支持. internalresourceviewresolver 会把返回的视图名称都解析为 internalresourceview 对象, internalresourceview 会把 controller 处理器方法返回的模型属性都存放到对应的 request 属性中,然后通过 requestdispatcher 在服务器端把请求 forword 重定向到目标 url 。下面是一个配置实例:

如果我们需要使用jstlview,则需指定vlewclass属性为jstlview。

在前面的测试实例中,我们一直在使用这种视图解析器,所以不再举例。

根据它的名字,我们将视图在spring容器中注册为bean,bean的id即为视图名。在我们控制层返回视图时,beannameviewresolver会自动根据我们的试图名找到对应的视图bean进行解析,下面我们看一个实例:

配置好视图和视图解析器后,我们可以在控制层通过如下方法访问视图:

我们在游览器访问view1即会跳转到对应的hello.jsp视图。

它继承自 abstractcachingviewresolver 抽象类,所以它也是支持视图缓存的。 xmlviewresolver 需要给定一个 xml 配置文件来定义视图的 bean 对象。在该文件中定义的每一个视图的 bean 对象都给定一个名字,然后 xmlviewresolver 将根据 controller 处理器方法返回的逻辑视图名称到 xmlviewresolver 指定的配置文件中寻找对应名称的视图 bean 用于处理视图。该配置文件默认是 /web-inf/views.xml 文件,如果不使用默认值的时候可以在 xmlviewresolver 的 location 属性中指定它的位置。

这里需要明确的是,使用xmlviewresolver最终不一定需要输出xml视图

以下是使用 xmlviewresolver 的一个示例:

使用 location 属性指定其配置文件所在的位置, order 属性指定当有多个 viewresolver 的时候其处理视图的优先级。

在下面的代码中我们就配置了一个名为 hello 的 internalresourceview ,其 url 属性为“ /index.jsp ”。

类似于beannameviewresolver的实例,我们访问view2,xmlviewresolver会到/web-inf/views.xml中寻找相应id的视图完成解析。

它继承自 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 使用的属性配置文件的内容类似于这样:

对应与上述配置,spring会将其解析成如下bean定义:

接下来讲讲 spring 通过 properties 文件生成 bean 的规则。它会把 properties 文件中定义的属性名称按最后一个点“ . ”进行分割,把点前面的内容当做是 bean 名称,点后面的内容当做是 bean 的属性。这其中有几个特别的属性, spring 把它们用小括号包起来了,这些特殊的属性一般是对应的 attribute ,但不是 bean 对象所有的 attribute 都可以这样用。其中 (class) 是一个,除了 (class) 之外,还有 (scope) 、 (parent) 、 (abstract) 、 (lazy-init) 。而除了这些特殊的属性之外的其他属性, spring 会把它们当做 bean 对象的一般属性进行处理,就是 bean 对象对应的 property 。所以根据上面的属性配置文件将生成如下两个 bean 对象:

从 resourcebundleviewresolver 使用的配置文件我们可以看出,它和 xmlviewresolver 一样可以解析多种不同类型的 view ,因为它们的 view 是通过配置的方式指定的,这也就意味着我们可以指定 a 视图是 internalresourceview , b 视图是 jstlview 。

除了以上的视图解析器,常用的还有下面两个模板视图解析器:freemarkerviewresolver 、 volocityviewresolver,在后面的文章会专门提到。