Spring实战第六章(待完善)
渲染视图
1、视图解析器
在控制器⽅法都没有直接产⽣浏览器中渲染所需的HTML。这些⽅法只是将⼀些数据填充到模型中,然后将模型传递给⼀个⽤来渲染的视图。Spring MVC使得控制器中请求处理的逻辑和视图中的渲染实现解耦。
控制器⽅法和视图的实现会在模型内容上达成⼀致,这是两者的最⼤关联,除此之外,两者应该保持⾜够的距离。
视图解析器的基础:
Spring MVC定义了⼀个名为ViewResolver的接⼝,它⼤致如下所⽰:
当给resolveViewName()⽅法传⼊⼀个视图名和Locale对象时,它会返回⼀个View实例。View是另外⼀个接⼝,如下所⽰:
View接⼝的任务就是接受模型以及Servlet的request和response对象,并将输出结果渲染到response中。我们所需要做的就是编写ViewResolver和View的实现,将要渲染的内容放到response中,进⽽展现到⽤户的浏览器中。
但是:⼀般来讲,我们并不需要关⼼这些接⼝。Spring提供了多个内置的实现,如表6.1所⽰,它们能够适应⼤多数的场景。
Spring⾃带了12个视图解析器,能够将逻辑视图名转换为物理实现。
视图解析器描  述
BeanNameViewResolver将视图解析为Spring应⽤上下⽂中的bean,其中
bean的ID与视图的名字相同
ContentNegotiatingViewResolver 通过考虑客户端需要的内容类型来解析视图,委托给另外⼀个能够产⽣对应内容类型的视图解析器
FreeMarkerViewResolver将视图解析为FreeMarker模板InternalResourceViewResolver将视图解析为Web应⽤的内部资源(⼀般为
JSP)JasperReportsViewResolver将视图解析为JasperReports定义ResourceBundleViewResolver将视图解析为资源bundle(⼀般为属性⽂件)
TilesViewResolver 将视图解析为Apache Tile定义,其中tile ID与视图名称相同。注意有两个不同的TilesViewResolver实现,分别对应于Tiles 2.0和Tiles 3.0
UrlBasedViewResolver直接根据视图的名称解析视图,视图的名称会
匹配⼀个物理视图的定义
VelocityLayoutViewResolver将视图解析为Velocity布局,从不同的Velocity模
板中组合页⾯
VelocityViewResolver将视图解析为Velocity模板
XmlViewResolver将视图解析为特定XML⽂件中的bean定义。类
似于BeanNameViewResolver
XsltViewResolver将视图解析为XSLT转换后的结果
2、创建jsp视图
Spring提供了两种⽀持JSP视图的⽅式:
  1、InternalResourceViewResolver会将视图名解析为JSP⽂件。另外,如果在你的J SP页⾯中使⽤了JSP标准标签库(JavaServer Pages Standard Tag Library,JSTL)的话,InternalResourceViewResolver能够将视图名解析为JstlView形式的JSP⽂件,从⽽将JSTL本地化和资源bundle变量暴露给JSTL的格式化(formatting)和信息(message)标签。
  2、Spring提供了两个JSP标签库,⼀个⽤于表单到模型的绑定,另⼀个提供了通⽤的⼯具类特性。
 不管你使⽤JSTL,还是准备使⽤Spring的JSP标签库,配置解析JSP的视图解析器都是⾮常重要的。尽管Spring还有其他的⼏个视图解析
器都能将视图名映射为JSP⽂件,但就这项任务来讲,InternalResourceViewResolver是最简单和最常⽤的视图解析器
 InternalResourceViewResolver遵循⼀种约定,会在视图名上添加前缀和后缀,进⽽确定⼀个Web应⽤中视图资源的物理路径。
  例如:⼀个简单的场景,假设逻辑视图名为home。通⽤的实践是将JSP⽂件放到Web应⽤的WEB-INF⽬录下,防⽌对它的直接访问。如果将所有的JSP⽂件都放在“/WEB-INF/views/”⽬录下,并且home页的JSP名为home.jsp,那么我们可以确定物理视图的路径就是逻辑视图名home再加上“/WEB-INF/views/”前缀和“.jsp”后缀。
如何配置InternalResourceViewResolver视图解析器:
  1、在Javaconfig中配置⽅式:
@Bean
public ViewResolver viewResolver(){  //配置JSP视图解析器
InternalResourceViewResolver resolver =
new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
resolver.setExposeContextBeansAsAttributes(true);
return resolver;
}
  2、或在xml中配置
InternalResourceViewResolver配置就绪之后,它就会将逻辑视图名解析为JSP⽂件
例⼦:books/detail将会解析为“/WEB-INF/views/books/detail.jsp”
注意:当逻辑视图名中包含斜线时,这个斜线也会带到资源的路径名中。因此,它会对应到prefix属性所引⽤⽬录的⼦⽬录下的JSP⽂件。
2.1解析JSTL视图
  如果这些JSP使⽤JSTL标签来处理格式化和信息的话,那么应该InternalResourceViewResolver将视图解析为JstlView。
  JSTL的格式化标签需要⼀个Locale对象,以便于恰当地格式化地域相关的值,如⽇期和货币。信息标签可以借助Spring的信息资源和Locale,从⽽选择适当的信息渲染到HTML之中。通过解析JstlView,JSTL能够获得Locale对象以及Spring中配置的信息资源。(Locale对象表⽰了特定的地理、政治和⽂化地区。需要Locale来执⾏其任务的操作称为语⾔环境敏感的操作,它使⽤Locale为⽤
户量⾝定制信息。例如,显⽰⼀个数值就是语⾔环境敏感的操作,应该根据⽤户的国家、地区或⽂化的风俗/传统来格式化该数值。)
  如果想让InternalResourceViewResolver将视图解析为JstlView,⽽不是InternalResourceView的话,那么我们只需设置它的viewClass属性即可:
@Bean
public ViewResolver viewResolver(){  //配置JSP视图解析器
InternalResourceViewResolver resolver =
new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
resolver.setViewClass(org.springframework.web.servlet.view.JstlView.class);
resolver.setExposeContextBeansAsAttributes(true);
return resolver;
}
  (配置org.springframework.web.servlet.view.JstlView,是因为要解析成jstlview,但是当导⼊了JSTL的标签jar包,不配也可以解析)
  或者在xml中:
2.2 JSP库
Spring提供了两个JSP标签库,⽤来帮助定义Spring MVC Web的视图。其中⼀个标签库会⽤来渲染HTML表单标签,这些标签可以绑定model中的某个属性。另外⼀个标签库包含了⼀些⼯具类标签,我们随时都可以⾮常便利地使⽤它们。
a、表单绑定到模型上
Spring的表单绑定JSP标签库包含了14个标签,它们中的⼤多数都⽤来渲染HTML中的表单标签。但是,它们与原⽣HTML标签的区别在
于它们会绑定模型中的⼀个对象,能够根据模型中对象的属性填充值。标签库中还包含了⼀个为⽤户展现错误的标签,它会将错误信息渲染到最终的HTML之中。
  使⽤表单绑定库,需要在JSP页⾯中对其进⾏声明:
<%@taglib uri="/tags/form" prefix="sf" %>
<%@taglib uri="/tags/form" prefix="form" %>
⼗四个相关的标签
JSP标签描  述
<sf:checkbox>渲染成⼀个HTML <input>标签,其中type属性设置
为checkbox
<sf:checkboxes>渲染成多个HTML <input>标签,其中type属性设置
为checkbox
<sf:errors>在⼀个HTML <span>中渲染输⼊域的错误
<sf:form>渲染成⼀个HTML <form>标签,并为其内部标签暴露绑定路
径,⽤于数据绑定
<sf:hidden>渲染成⼀个HTML <input>标签,其中type属性设置为hidden
<sf:input>渲染成⼀个HTML <input>标签,其中type属性设置为text
<sf:label>渲染成⼀个HTML <label>标签
<sf:option>渲染成⼀个HTML <option>标签,其selected属性根据所绑定
的值进⾏设置
<sf:options>按照绑定的集合、数组或Map,渲染成⼀个HTML <option>标
签的列表
<sf:password>渲染成⼀个HTML <input>标签,其中type属性设置
为password
<sf:radiobutton>渲染成⼀个HTML <input>标签,其中type属性设置为radio
<sf:radiobuttons>渲染成多个HTML <input>标签,其中type属性设置为radio
<sf:select>渲染为⼀个HTML <select>标签
<sf:textarea>渲染为⼀个HTML <textarea>标签
介绍略
3、Tiles视图定义布局
Spring MVC以视图解析器的形式为Apache Tiles提供了⽀持,这个视图解析器能够将逻辑视图名解析为Tile定义。
3.1配置Tiles视图解析器
在Spring中使⽤Tiles,需要配置⼏个bean。
需要⼀个TilesConfigurer bean,它会负责定位和加载Tile定义并协调⽣成Tiles。除此之外,还需要TilesViewResolver bean将逻辑视图名称解析为Tile定义。
TilesConfigurer bean把其定义在了WebConfig中,
// Tiles
@Bean
public TilesConfigurer tilesConfigurer() {
TilesConfigurer tiles = new TilesConfigurer();
tiles.setDefinitions(new String[] {
"/WEB-INF/l",
"/WEB-INF/views/**/l"
});
tiles.setCheckRefresh(true);
return tiles;
}
当配置TilesConfigurer的时候,所要设置的最重要的属性就是definitions。这个属性接受⼀个String类型的数组,其中每个条⽬都指定⼀个Tile定义的XML⽂件。对于Spittr应⽤来讲,我们让它在“/WEB-INF/layout/”⽬录下查l。其实我们还可以指定多个Tile定义⽂件,甚⾄能够在路径位置上使⽤通配符(例如使⽤了Ant风格的通配符(**)),当然在上例中我们没有使⽤该功能。例如,我们要求TilesConfigurer加载“/WEB-INF/”⽬录下的所有名字为l 的⽂件,那么可以按照如下的⽅式设置definitions属性。
之后配置TilesViewResolver bean(在webConfig之中)
@Bean
public ViewResolver viewResolverTile() {
return new TilesViewResolver();
}
或者把上⾯的bean配置在xml之中
TilesConfigurer会加载Tile定义并与Apache Tiles协作,⽽TilesViewResolver会将逻辑视图名称解析为引⽤Tile定义的视图。
3.2定义Tiles
Apache Tiles提供了⼀个⽂档类型定义(document type definition,DTD),⽤来在XML⽂件中指定Tile的定义。每个定义中需要包含⼀个<definition>元素,这个元素会有⼀个或多个<put-attribute>元素。
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE tiles-definitions PUBLIC
"-//Apache Software Foundation//DTD Tiles Configuration 3.0//EN"
"/dtds/tiles-config_3_0.dtd">
<tiles-definitions>
<definition name="base" template="/WEB-INF/layout/page.jsp">        定义bese Tiles
  <put-attribute name="header" value="/WEB-INF/layout/header.jsp"/>  扩展属性
  <put-attribute name="footer" value="/WEB-INF/layout/footer.jsp"/>
</definition>
<definition name="home" extends="base">                  扩展base Tiles
<put-attribute name="body" value="/WEB-INF/views/home.jsp"/>springmvc常用标签
</definition>
<definition name="registerForm" extends="base">
<put-attribute name="body" value="/WEB-INF/views/registerForm.jsp"/>
</definition>
<definition name="profile" extends="base">
<put-attribute name="body" value="/WEB-INF/views/profile.jsp"/>
</definition>
<definition name="spittles" extends="base">
<put-attribute name="body" value="/WEB-INF/views/spittles.jsp"/>
</definition>
<definition name="spittle" extends="base">
<put-attribute name="body" value="/WEB-INF/views/spittle.jsp"/>
</definition>
</tiles-definitions>
每个<definition>元素都定义了⼀个Tile,它最终引⽤的是⼀个JSP模板。在名为base的Tile中,模板引⽤的是“/WEB-INF/layout/page.jsp”。某个Tile可能还会引⽤其他的JSP模板,使这些JSP模板嵌⼊到主模板中。对于base Tile来讲,它引⽤的是⼀个头部JSP模板和⼀个底部JSP模板。
base Tile所引⽤的page.jsp模板如下⾯程序清单所⽰。主布局模板:引⽤其他模板来创建视图
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ taglib uri="/tags" prefix="s" %>
<%@ taglib uri="/tags-tiles" prefix="t" %>
<%@ page session="false" %>
<html>
<head>
<title>Spittr</title>
<link rel="stylesheet"
type="text/css"
href="<s:url value="/resources/style.css" />" >
</head>
<body>
<div id="header">
<t:insertAttribute name="header"/>
</div>
<div id="content">
<t:insertAttribute name="body"/>
</div>
<div id="footer">
<t:insertAttribute name="footer"/>
</div>
</body>
</html>
(注意:在写<%@ taglib uri="/tags-tiles" prefix="t" %>可能会报错,
需要在maven中写⼊:
<dependency>
  <groupId>org.apache.tiles</groupId>
  <artifactId>tiles-jsp</artifactId>
  <version>3.0.7</version>
</dependency>
使⽤Tile标签库中的<t:insert Attribute> JSP标签来插⼊其他的模板。在这⾥,⽤它来插⼊名为header、body和footer的模板。
在这⾥,base Tile不会期望单独使⽤。它会作为基础定义(这是其名字的来历),供其他的Tile定义扩展。在程序清单6.2的其余内容中,我们可以看到其他的Tile定义都是扩展⾃base Tile。它意味着它们会继承其header和footer属性的设置(当然,Tile定义中也可以覆盖掉这些属性),但是每⼀个都设置了body属性,⽤来指定每个Tile特有的JSP模板。
现在,我们关注⼀下home Tile,它扩展了base。因为它扩展了base,因此它会继承base中的模板和所有的属性。尽管home Tile定义相对来说很简单,但是它实际上包含了如下的定义:

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。