zoukankan      html  css  js  c++  java
  • 笔记29 视图解析 ——InternalResourceViewResolver

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

    首先将会介绍 InternalResourceViewResolver,这个视图解析器一般会用来 解析JSP视图。

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

    • InternalResourceViewResolver会将视图名解析为JSP文 件。另外,如果在你的JSP页面中使用了JSP标准标签库 (JavaServer Pages Standard Tag Library,JSTL)的 话,InternalResourceViewResolver能够将视图名解析为 JstlView形式的JSP文件,从而将JSTL本地化和资源bundle变量暴 露给JSTL的格式化(formatting)和信息(message)标签。
    • Spring提供了两个JSP标签库,一个用于表单到模型的绑定,另一 个提供了通用的工具类特性。

    考虑一个简单的场景,假设逻辑视图名为home。通用的 实践是将JSP文件放到Web应用的WEB-INF目录下,防止对它的直接 访问。如果我们将所有的JSP文件都放在“/WEB-INF/views/”目录下, 并且home页的JSP名为home.jsp,那么我们可以确定物理视图的路径 就是逻辑视图名home再加上“/WEB-INF/views/”前缀和“.jsp”后缀。如下图所示:

    当使用@Bean注解的时候,我们可以按照如下的方式配 置Internal-ResourceView Resolver,使其在解析视图时,遵 循上述的约定。

    1     @Bean // 配置JSP视图解析器
    2     public ViewResolver viewResolver() {
    3         InternalResourceViewResolver resolver = new InternalResourceViewResolver();
    4         resolver.setPrefix("/WEB-INF/views/");
    5         resolver.setSuffix(".jsp");
    6         resolver.setExposeContextBeansAsAttributes(true);
    7         return resolver;
    8     }

    2.  解析JSTL视图

    如果在JSP中使用JSTL标签来处理格式化和信息的话,那么就会让InternalResourceViewResolver将视图解析为JstlView。 JSTL的格式化标签需要一个Locale对象,以便于恰当地格式化地域 相关的值,如日期和货币。信息标签可以借助Spring的信息资源和 Locale,从而选择适当的信息渲染到HTML之中。通过解析 JstlView,JSTL能够获得Locale对象以及Spring中配置的信息资 源。 

    如果想让InternalResourceViewResolver将视图解析 为JstlView,而不是InternalResourceView的话,那么我们只需设置它的viewClass属性即可:

    1     @Bean // 配置JSP视图解析器
    2     public ViewResolver viewResolver() {
    3         InternalResourceViewResolver resolver = new InternalResourceViewResolver();
    4         resolver.setPrefix("/WEB-INF/views/");
    5         resolver.setSuffix(".jsp");
    6         resolver.setViewClass(org.springframework.web.servlet.view.JstlView.class);
    7         resolver.setExposeContextBeansAsAttributes(true);
    8         return resolver;
    9     }

    3.  Spring的JSP库 

    Spring提供了两个JSP标签库,用来帮助定义 Spring MVC Web的视图。其中一个标签库会用来渲染HTML表单标 签,这些标签可以绑定model中的某个属性。另外一个标签库包含了 一些工具类标签

    3.1  将表单绑定到模型上

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

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

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

    需要注意,将前缀指定为“sf”,但通常也可能使用“form”前缀。 在声明完表单绑定标签库之后,就可以使用14个相关的标签了。如下图所示:

    重写registerForm.jsp,程序如下:

     1 <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
     2 <%@ taglib uri="http://www.springframework.org/tags/form" prefix="sf"%>
     3 <%
     4 String path = request.getContextPath();
     5 String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
     6 %>
     7 
     8 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
     9 <html>
    10   <head>
    11     <base href="<%=basePath%>">
    12     
    13     <title>注册</title>
    14     
    15     <meta http-equiv="pragma" content="no-cache">
    16     <meta http-equiv="cache-control" content="no-cache">
    17     <meta http-equiv="expires" content="0">    
    18     <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    19     <meta http-equiv="description" content="This is my page">
    20     <!--
    21     <link rel="stylesheet" type="text/css" href="styles.css">
    22     -->
    23 
    24   </head>
    25   
    26   <body>
    27         <sf:form method="POST" modelAttribute="spitter">
    28             First Name:<sf:input path="firstName"/>
    29             Last Name:<sf:input path="lastName"/>
    30             Email:<sf:input path="email"/>
    31             UserName:<sf:input path="username"/>
    32             Password:<sf:password path="password"/>
    33             <input type="submit" value="注册">
    34         </sf:form>
    35   </body>
    36 </html>

    <sf:form>会渲染会一个HTML <form>标签,但它也会通过 commandName属性构建针对某个模型对象的上下文信息。在其他的 表单绑定标签中,会引用这个模型对象的属性。 

    将commandName属性设置为spitter。因 此,在模型中必须要有一个key为spitter的对象,否则的话,表单 不能正常渲染(会出现JSP错误)。这意味着需要修改一 下SpitterController,以确保模型中存在以spitter为key的 Spitter对象:

    1     @RequestMapping(value = "/register", method = RequestMethod.GET) // 处理对“/spitter/register”的GET请求
    2     public String showRegistrationForm(Model model) {
    3         model.addAttribute(new Spitter());
    4         return "registerForm";
    5     }

    修改后的showRegistrationForm()方法中,新增了一 个Spitter实例到模型中。

    3.2  展现错误

    相对于标准的HTML标签,使用Spring的表单绑定标签能够带来一定 的功能提升,在校验失败后,表单中会预先填充之前输入的值。但 是,这依然没有告诉用户错在什么地方。为了指导用户矫正错误,需要使用<sf:errors>。 

    如果存在校验错误的话,请求中会包含错误的详细信息,这些信息是 与模型数据放到一起的。我们所需要做的就是到模型中将这些数据抽 取出来,并展现给用户。<sf:errors>能够让这项任务变得很简 单。 

    1 <sf:errors path="firstName">
    2             <span id="firstName.errors">必须大于2个字符</span>
    3         </sf:errors>

    将<sf:errors>用到First Name输入域的场景,它的path属性设置成了firstName,也就是指定了要显示Spitter 模型对象中哪个属性的错误。如果firstName属性没有错误的话, 那么<sf:errors>不会渲染任何内容。但如果有校验错误的话,那 么它将会在一个HTML <span>标签中显示错误信息。 

    4.  Spring通用的标签库

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

    1 <%@ taglib uri="http://www.springframework.org/tags" prefix="s" %>

    标签库声明之后,我们就可以使用下表中的十个JSP标签了。

     

    4.1  展现国际化信息

    对于渲染文本来说,是很好的方案,文本能够位于一个或多个属性文 件中。借助<s:message>,我们可以将硬编码的欢迎信息替换为如 下的形式:

    按照这里的方式,<s:message>将会根据key为spittr.welcome 的信息源来渲染文本。因此,如果我们希望<s:message>能够正常 完成任务的话,就需要配置一个这样的信息源。 

    Spring有多个信息源的类,它们都实现了MessageSource接口。在 这些类中,更为常见和有用的 是ResourceBundleMessageSource。它会从一个属性文件中加 载信息,这个属性文件的名称是根据基础名称(base name)衍生而来 的。如下的@Bean方法配置了 ResourceBundleMessageSource:

    1     @Bean
    2     public MessageSource messageSource() {
    3         ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
    4         messageSource.setBasename("message");
    5         return messageSource;
    6     }

    在这个bean声明中,核心在于设置basename属性。你可以将其设置 为任意的值,在这里,我将其设置为message。将其设置 为message后,ResourceBundle-MessageSource就会试图在根 路径的属性文件中解析信息,这些属性文件的名称是根据这个基础名 称衍生得到的。

    另外的可选方案是使 用ReloadableResourceBundleMessageSource,它的工作方 式与ResourceBundleMessageSource非常类似,但是它能够重 新加载信息属性,而不必重新编译或重启应用。如下是配 置ReloadableResourceBundle-MessageSource的样例:

    1     @Bean
    2     public MessageSource messageSource2() {
    3         ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
    4         messageSource.setBasename("file:///etc/spittr/message");
    5         messageSource.setCacheSeconds(10);
    6         return messageSource;
    7     }

    这里的关键区别在于basename属性设置为在应用的外部查找(而不 是像ResourceBundleMessageSource那样在类路径下查 找)。basename属性可以设置为在类路径下(以“classpath:”作 为前缀)、文件系统中(以“file:”作为前缀)或Web应用的根路径 下(没有前缀)查找属性。在这里,我将其配置为在服务器文件系统 的“/etc/spittr”目录下的属性文件中查找信息,并且基础的文件名 为“message”。

    这两个bean放在WebConfig.java中

    创建属性文件:message.properties 位置:src下,类的根目录

    1 spittr.welcome=Welcome to Spittr! 

    4.2  创建URL 

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

    按照其最简单的形式,<s:url>会接受一个相对于Servlet上下文的 URL,并在渲染的时候,预先添加上Servlet上下文路径。例如,考虑 如下<s:url>的基本用法:

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

    这样,在创建URL的时候,就不必再担心Servlet上下文路径是什 么了,<s:url>将会负责这件事。 

    另外,还可以使用<s:url>创建URL,并将其赋值给一个变量供 模板在稍后使用:

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

    如果希望在URL上添加参数的话,那么可以使用<s:param>标 签。比如,如下的<s:url>使用两个内嵌的<s:param>标签,来设 置“/spittles”的max和count参数:

    重点:创建带有路径 (path)参数的URL

    当href属性中的占位符匹配<s:param>中所指定的参数时,这个参 数将会插入到占位符的位置中。如果<s:param>参数无法匹配href 中的任何占位符,那么这个参数将会作为查询参数。 

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

  • 相关阅读:
    Python函数式编程(一):高级函数
    Python高级特性:列表生成式
    Python高级特性:迭代
    Python高级特性:切片
    Python学习笔记
    关于相机拍照获取图片onActivityResult返回data 为null的问题
    191019
    状语和状语从句
    191018
    191017
  • 原文地址:https://www.cnblogs.com/lyj-gyq/p/8963885.html
Copyright © 2011-2022 走看看