16、渲染Web视图(2)(Spring笔记)

2.2.3 Spring 通用的标签库

除了表单绑定标签库之外,Spring还提供了更为通用的JSP标签库。要使用它,必须在页面上对其进行声明:

<%@ taglib uri="http://www.springframework.org/tags" prefix="s" %>
JSP标签 描述
将绑定属性的状态导出到一个名为status的页面作用域属性中,与组合使用获取绑定属性的值
将标签体中的内容进行HTML和/或JS转义
根据指定模型对象(在请求属性中)是否有绑定错误,有条件地渲染内容
为当前页面设置默认的HTML转义值
根据给定的编码获取信息,然后要么进行渲染(默认行为),要么将其设置为页面作用域、请求作用域、会话作用域或应用作用域的变量(通过使用varscope属性实现)
设置嵌入式的path,用于之中
根据给定的编码获取主题信息,然后要么进行渲染(默认行为),要么将其设置为页面作用域、请求作用域、会话作用域或应用作用域的变量(通过使用varscope属性实现)
使用命令对象的属性编辑器转换命令对象中不包含的属性
创建相对于上下文的URL,支持URI模版变量以及HTML/XML/JS转义,可以渲染URL(默认行为),也可以将其设置为页面作用域、请求作用域、会话作用域或应用作用域的变量(通过使用varscope属性实现)
计算符合Spring表达式语言(SpEL)语法的某个表达式的值,然后然后要么进行渲染(默认行为),要么将其设置为页面作用域、请求作用域、会话作用域或应用作用域的变量(通过使用varscope属性实现)

2.2.4 展现国际化信息

在进行国际化中,对于渲染文本来说,是很好的方案:

按照这里的方式,将会根据keyspittr.welcome的信息来渲染文本。因此,如果希望此标签能完成任务,就需要配置一个这样的信息源。Spring有多个信息源的类,它们都实现了MessageSource接口。比较常用的是ResourceBundleMessageSource。它会从一个属性文件中加载信息,这个属性文件的名称是根据基础名称衍生而来的:

@Bean
public MessageSource messageSource(){
    ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
    messageSource.setBasename("message");
    return messageSource;
}

在上面代码中,核心在于设置basename属性,将其设置为message后,ResourceBundleMessageSource就会试图在根路径的属性文件中解析信息,这些属性文件的名称是根据这个基础名衍生得到的(message.properties)。

另外可选方案是使ReloadableResourceBundleMessageSource,使用和工作方式和ResourceBundleMessageSource非常类似,但是它能够重新加载信息属性,而不必重新编译或重启应用。

@Bean
public MessageSource messageSource(){
    ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
    messageSource.setBasename("file:///etc/spittr/message");
    messageSource.setCacheSeconds(10);
    return messageSource;
}

说明:这里basename设置为在应用外部查找,还可以设置为在类路径下(以“classpath:”作为前缀)、文件系统中(以“file:”作为前缀)或Web应用的根路径下(没有前缀)查找属性。

2.2.5 创建URL

是一个很小的标签,其主要任务就是创建URL,然后将其赋值给一个变量或者渲染到响应中。它是JSTL标签的替代者,但是有几项特殊技巧。

按照其最简单的形式,会接受一个相对于Servlet上下文的URL,并在渲染的时候,预先添加上Servlet上下文路径。

">Register

如果应用的Servlet上下文名为spittr,那么响应中将渲染为如下的HTML

Register

还可以使用创建URL,并将其赋值给一个变量供模版在稍后使用:


Register

默认情况,URL是在页面作用域内创建的。但是通过设置scope属性,我们可以让在应用作用域内、会话作用域内或请求作用域内创建URL


如果希望在URL上添加参数的话,那么你可以使用标签。


    
    

上面讲到的功能,在JSTL 中也有,但是如果向要创建带有路径参数的URL,则需要使用了。


    

href属性中的占位符匹配中所指定的参数时,这个参数将会插入到占位符的位置中。如果参数无法匹配href中的任何占位符,那么这个参数(此处是username)将会作为查询参数

标签还可以解决URL的转移需求,如过希望将渲染得到的URL内容展现在Web页面上(而不是作为超链接),可以这样:


    
    

所渲染的结果如下:

/spitter/spittles?max=60&count=20

当然如果想在JS中使用URL则需要设置javascriptEscape属性:


    
    

使用如下:


渲染结果为:


2.2.6 转义内容

标签是一个通用的转义标签。它会渲染标签中内嵌的内容,并且在必要的时候进行转义。如想在页面展现一个HTML代码片段:


Hello

它将会渲染成如下内容:

Hello

在浏览器中显示的时候就会自动转义为:

Hello

当然还可以设置javascriptEscape属性对JS进行转义,但是此标签不能将内容设置为变量。

三、使用 Apache Tiles 视图定义布局

如果我们想为应用中的所有页面定义一个通用的头部和底部。最原始的方式就是查找每个JSP,并为其添加头部和底部的HTML。但是这种方式的扩展性并不好。更好的方式是使用布局引擎,如Apache Tiles,定义适用于所有页面的通用页面布局。

3.1 配合Tiles视图解析器

为了在Spring中使用Tiles,需要配置几个bean。需要一个TilesConfigurer bean,它会负责定位和加载Tile定义并协调生成Tiles。除此之外,还需要TilesViewResolver bean将逻辑视图名称解析为Tile定义。

这两个组件又有两种形式:针对Apache Tiles 2(位于org.springframework.web.servlet.view.tiles2)和Apache Tiles 3(位于org.springframework.web.servlet.view.tiles3)分别都有这么两个组件。

首先,配置TilesConfigurer来解析Tile定义。

@Bean
public TilesConfigurer tilesConfigurer(){
    TilesConfigurer tiles = new TilesConfigurer();
    tiles.setDefinitions(new String[] {"/WEB-INF/layout/tiles.xml"});
    tiles.setCheckRefresh(true);
    return tiles;
}

说明:配置TilesConfigurer的时候,所要设置的最重要的属性就是definitions。接受一个String类型的数组,其中每个条目都指定一个Tile定义的XML文件。这里让它在"/WEB-INF/layout/"下查找tiles.xml文件。如果我们想让其加载"/WEB-INF/"目录下的所有名为tiles.xml的文件则可以这样配置路径:/WEB-INF/**/tiles.xml

接下来,让我们配置TilesViewResolver,可以看到,这是一个很基本的bean定义,没有什么要设置的属性:

@Bean
public ViewResolver viewResolver(){
  return new TilesViewResolver();
}

当然也可以使用XML的方式进行配置:


    
        
            /WEB-INF/layout/tiles.xml
            /WEB-INF/**/tiles.xml
        
    



说明:TilesConfigurer会加载Tile定义并与Apache Tiles协作,而TilesViewResolver会将逻辑视图名称解析为引用Tile定义的视图。

3.1.1 定义Tiles

下面看如何定义Tiles文件:




  
  
    
    
    
  

  
    
  

  
    
  

  
    
  

  
    
  

  
    
  

说明:每个元素都定义了一个Tile,最终引用的是一个JSP模版。可以看到base Tile中设置了基本的模版,及顶部和底部。而后面的Tile都是用来扩展base Tile的,后面的Tile都将作为body插入到整个页面,和顶部、底部一起组成一个完整的页面。我们看base Tile所引用的page.jsp模版:

<%@ taglib uri="http://www.springframework.org/tags" prefix="s" %>
<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="t" %>
<%@ page session="false" %>

  
    Spittr
    " >
  
  
    
    

说明:从上面可以看到三个页面是如何组成一个完整的页面的,其实扩展的Tile会继承base Tile的相关属性,如home Tile实际上包含了如下定义:


  
  
  

为了完整的了解home Tile,如下展现了home.jsp:

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page session="false" %>

Welcome to Spittr

">Spittles ">Register

四、使用Thymeleaf

JSP规范与Servlet规范紧密耦合,这意味着它只能用在基于ServletWeb应用之中。JSP模版不能作为通用的模版(如格式化Email),也不能用于非ServletWeb应用。

4.1 配置Thymeleaf视图解析器

为了要在Spring中使用Thymeleaf,需要配置三个启用ThymeleafSpring集成的bean

  • ThymeleafViewResolver:将逻辑试图名称为解析为Thymeleaf模版视图;
  • SpringTemplateEngine:处理模版并渲染结果;
  • TemplateResolver:加载Thymeleaf模版。

如下为声明这些beanJava配置(在WebConfig.java中):

@Bean
public ViewResolver viewResolver(SpringTemplateEngine templateEngine) {
  ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
  viewResolver.setTemplateEngine(templateEngine);
  return viewResolver;
}
@Bean
public TemplateEngine templateEngine(TemplateResolver templateResolver) {
  SpringTemplateEngine templateEngine = new SpringTemplateEngine();
  templateEngine.setTemplateResolver(templateResolver);
  return templateEngine;
}

@Bean
public TemplateResolver templateResolver() {
  TemplateResolver templateResolver = new ServletContextTemplateResolver();
  templateResolver.setPrefix("/WEB-INF/views/");
  templateResolver.setSuffix(".html");
  templateResolver.setTemplateMode("HTML5");
  return templateResolver;
}

当然也可以使用XML方式进行配置:


        



说明:ThymeleafViewResolverSpring MVCViewResolver的一个实现,会将一个逻辑视图名解析为一个Thymeleaf模版。在ThymeleafViewResolver bean中注入了一个对SpringTemplateEngine bean的引用。SpringTemplateEngine会在Spring中启用Thymeleaf引擎,用来解析模版,并基于这些模版渲染结果。可以看到,我们为其注入了一个TemplateResolver bean的引用。TemplateResolver会最终定位和查找模版。

4.2 定义Thymeleaf模版

Thymeleaf在很大程度上就是HTML文件,与JSP不同,它没有什么特殊的标签或标签库。它通过自定义的命名空间,为标准HTML标签集合添加Thymeleaf属性。


  
    Spitter
    
  
  
    
    

Welcome to Spitter

Spittles | Register

说明:th:href属性的特殊之处在于它的值中可以包含Thymeleaf表达式,用来计算动态的值。Thymeleaf的价值在于它与纯HTML模版非常接近。唯一的区别就是使用了th:href属性。这意味着Thymeleaf模版与JSP不同,它能够按照原始的方式进行编辑甚至渲染,而不必经过任何类型的处理器。

4.2.1 借助Thymeleaf实现表单绑定

下面直接通过表单页面registerForm.html进行说明:

  • Input is incorrect
:
:
:
:
:

说明:这里我们使用的是Thymeleaf的方言。th:class属性会渲染为一个class属性,它的值是根据给定的表达式计算得到的。如果有有错误,class在渲染时的值为error,如果这个域没有错误,将不会渲染class属性。th:field属性用来引用后端对象的相关域(如spitterfirstName属性),其中星号表示为所有表单对象(此处为spitter)定义后端对象。使用th:if属性来检查是否有校验错误,如果有,会渲染

,否则不渲染。
  • 标签上的th:each属性将会通知Thymeleaf为每项错误都渲染一个
  • ,在每次迭代中会将当前错误设置到一个名为err的变量中。

    “${}”“*{}”有什么区别:前者是变量表达式。一般来讲,会是OGNL表达式,在使用Spring时是SpEL表达式。在${spitter}例子中,会解析keyspittermodel属性。而后者是选择表达式。变量表达式是基于整个SpEL上下文计算的,而选择表达式是基于一个选中对象计算的。本例中选择的是Spitter对象。

  • 你可能感兴趣的:(16、渲染Web视图(2)(Spring笔记))