15、渲染Web视图(1)(Spring笔记)

一、理解视图解析

在之前的讲解中,我们使用名为InternalResourceViewResolver的视图解析器。在它的配置中,为了得到视图的名字,会使用“/WEB-INF/views/”前缀和“.jsp”后缀,从而确定来渲染模型的JSP文件的物理位置。现在回过头来看看视图解析的基础知识以及Spring提供的其他视图解析器。

Spring MVC定义了一个名为ViewResolver的接口:

public interface ViewResolver{
    View resolveViewName(String viewName, Locale locale) throw Exception;
}

此方法传入一个视图名和Locale对象时,它会返回一个View实例。View是另外一个接口:

public interface View{
    String getContentType();
    void render(Map model, HttpServletRequest request, HttpServletResponse response) throw Exception;
}

说明:View接口的任务就是接受模型以及Servletrequestresponse对象,并将输出结果渲染到response中。看起来非常简单,我们只需要编写上述两个接口的实现即可,有时候也需要这样做,但是一般来讲,并不需要,Spring提供了多个内置的实现。

Spring自带了十三个视图解析器,能够将逻辑视图名转换为物理实现。

视图解析器 描述
BeanNameViewResolver 将视图解析为Spring应用上下文中的bean,其中beanID与视图的名字相同
ContentNegotiatingViewResovler 通过考虑客户端需要的内容类型来解析视图,委托给另外一个能够产生对应内容类型的视图解析器
FreeMarkerViewResolver 将视图解析为FreeMarker模版
InternalResourceViewResolver 将视图解析为Web应用的内部资源(一般为JSP
JasperReportsViewResolver 将视图解析为JasperReports定义
ResourceBundleViewResolver 将视图解析为资源bundle(一般为属性文件)
TilesViewResolver 将视图解析为Apache Tile定义,其中tile ID与视图名称相同,注意有两个不同的TilesViewResolver实现,分别对应于Tiles 2.0Tiles 3.0
UrlBasedViewResolver 直接根据视图的名称解析视图,视图的名称会匹配一个物理视图的定义
VelocityLayoutViewResolver 将视图解析为Velocity布局,从不同的Velocity模版中组合页面
VelocityViewResolver 将视图解析为Velocity模版
XmlViewResolver 将视图解析为特定的XML文件中的bean定义,类似于BeanNameViewResolver
XsltViewResolver 将视图解析为XSLT转换后的结果

说明:Spring 4Spring 3.2支持表中所有的视图解析器。Spring 3.1支持除了Tiles 3 TilesViewResolver之外的所有视图解析器。这里InternalResourceViewResolver一般会用于JSPTilesViewResolver用于Apache Tiles视图,而FreeMarkerViewResolverVelocityViewResolver分别对应FreeMarkerVelocity模版视图。

二、创建JSP视图

Spring提供了两种支持JSP视图的方式:

  • InternalResourceViewResolver会将视图名解析为JSP文件。另外,如果在JSP页面中使用了JSTL,此解析器会将视图名解析为JstlView形式的JSP文件,从而将JSTL本地化好资源bundle变量暴露给JSTL的格式化和信息标签。

  • Spring提供了两个JSP标签库,一个用于表单到模型的绑定,另一个提供了通用的工具类特性。

2.1 配置适用于JSP的视图解析器

有一些视图解析器,如ResourceBundleViewResovler会直接将逻辑视图名映射为特定的View接口实现,而InternalResourceViewResolver所采取的方式并不那么直接。它遵循一种约定,会在视图名上添加前缀和后缀,进而确定一个Web应用中视图资源的物理路径(前面一节已经说明,这里不再细说)。

在之前的13讲中的WebConfig配置类中是这样配置视图解析器的:

@Bean
public ViewResolver viewResolver() {
  //配置JSP视图解析器
  InternalResourceViewResolver resolver = new InternalResourceViewResolver();
  resolver.setPrefix("/WEB-INF/views/");
  resolver.setSuffix(".jsp");
  return resolver;
}

说明:当然我们也可以使用XML进行配置:


说明:解析器配置好之后,它就会将逻辑视图名解析为JSP文件,如下所示:

  • home将会解析为“/WEB-INF/views/home.jsp”
  • productList将会解析为“/WEB-INF/views/productList.jsp”
  • books/detail将会解析为“/WEB-INF/views/books/detail.jsp”

2.1.1 解析JSTL视图

上述对视图解析器的配置都很基础。如果一些JSP使用JSTL标签来处理格式化和信息的话,那么我们会希望InternalResourceViewResolver将视图解析为JstlViewJSTL的格式化标签需要一个Locale对象,以便于恰当地格式化地域相关的值,如日期和货币。信息标签可以借助Spring的信息资源和Locale,从而选择适当的信息渲染到HTML中。

如果想让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);
  return resolver;
}

同样,我们也可以使用XML完成这一项内容:


2.2 使用 Spring 的 JSP 库

当为JSP添加功能时,标签库是一种很强大的方式,能够避免在脚本块中直接编写Java代码。Spring提供了两个JSP标签库,用来帮助定义Spring MVC Web的视图。其中一个标签库会用来渲染HTML表单标签,这些标签可以绑定model中的某个属性。另外一个标签库包含了一些工具类标签。

2.2.1 将表单绑定到模型上

Spring的表单绑定JSP标签库包含了十四个标签,它们中的大多数都用来渲染HTML中的表单标签。但是,它们与原生的HTML标签的区别在于它们会绑定模型中的一个对象,能够根据模型中对象的属性填充值。还包含了一个为用户展现错误的标签,它会将错误信息渲染到最终的HTML之中。

为了使用表单绑定,需要在JSP页面中对其进行声明:

<%@ talib uri="http://www.springframework.org/tags/form" prefix="sf" %>

借助Spring表单绑定标签库中所包含的标签,能够将模型对象绑定到渲染后的HTML

JSP标签 描述
渲染成一个HTML 标签,其中type属性设置为checkbox
渲染成多个HTML 标签,其中type属性设置为checkbox
渲染成一个HTML 中渲染输入域的错误
渲染成一个HTML
标签,并为其内部标签暴露绑定路径,用于数据绑定
渲染成一个HTML 标签,其中type属性设置为hidden
渲染成一个HTML 标签,其中type属性设置为text
渲染成一个HTML 标签
渲染成一个HTML 标签,其中selected属性根据所绑定的值进行设置
按照绑定的集合、数组或Map,渲染成一个HTML 标签的列表
渲染成一个HTML 标签,其中type属性设置为password
渲染成一个HTML 标签,其中type属性设置为radio
渲染成多个HTML 标签,其中type属性设置为radio
渲染成一个HTML
渲染成一个HTML