spring(6) 渲染web视图

【0】README

1)本文部分文字描述转自:“Spring In Action(中/英文版)”,旨在review  “spring(6) 渲染web视图” 的相关知识;

【1】 理解视图解析

【1.1】视图解析的基础知识以及spring 提供的其他视图解析器

1)spring mvc 定义了一个名为 ViewResolver的接口,如下

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

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

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

代码分析:View接口的任务就是接受模型以及 servlet的request 和 response对象,并将输出结果渲染到 response;

3)spring自带了13个视图解析器

对上表的分析(Analysis):

A1)InternalResourceViewResolver: 用于 JSP, TilesViewResolver用于Apache Tiles 视图, FreeMarkerViewResolver and VelocityViewResolver 分别用于 FreeMaker 和 Velocity模板视图;

A2)Thymeleaf: 是一种用来替代JSP 的新兴技术,spring提供了与 Thymeleaf 的原生模板协作的视图解析器;这种模板之所以得到这样的称呼是因为它更像最终产生的HTML,而不是驱动它们的java 代码;


【2】创建JSP视图

1)spring提供了两种支持 JSP 的视图(type)

type1)InternalResourceViewResolver 会将视图名解析为 jsp 文件;如果在jsp页面中使用了 JSP 标准标签库(java server page standard tag library)的话,InternalResourceViewResolver 能够将视图名解析为 JstlView 形式的jsp 文件,从而将JSTL 本地化和资源 bundle变量暴露给
JSTL 的格式化和信息标签;

type2)spring提供了两个JSP 标签库: 一个用于表单到模型的绑定,另一个提供了通用的工具类特性;

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

1)看个荔枝:

@Configuration
@EnableWebMvc
@ComponentScan(basePackages={"com.spring.chapter5.spittr.web",
   "com.spring.chapter5.spittr.data"})
public class WebConfig extends WebMvcConfigurerAdapter {

  @Bean
  public ViewResolver viewResolver() { // highlight line.
    InternalResourceViewResolver resolver = new InternalResourceViewResolver();
    resolver.setPrefix("/WEB-INF/views/");
    resolver.setSuffix(".jsp");
    resolver.setExposeContextBeansAsAttributes(true);
    return resolver;
  }

  @Override
  public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
    configurer.enable();
  }
} 

【2.1.1】解析JSTL 视图(jsp standard tag lib-java标准库标签)

1)intro: InternalResourceViewResolver 最终会将逻辑视图名解析为 InternalResourceView 实例,这个实例会引用jsp文件;

2)如果想让InternalResourceViewResolver  将视图解析为 JstlView,而不是 InternalResourceView 实例的话,只需要设置它的 viewClass属性即可:

@Bean
 public ViewResolver viewResolver() {
  InternalResourceViewResolver resolver = new InternalResourceViewResolver();
  resolver.setPrefix("/WEB-INF/views/");
  resolver.setSuffix(".jsp");
  resolver.setViewClass(org.springframework.web.servlet.view.JstlView.class);
  return resolver;
 }

3)同样,在xml中的配置为:

<bean id="viewResolver"
    class="org.springframework.web.servlet.view. InternalResourceViewResolver"
    p:prefix="/WEB-INF/views/"
    p:suffix=".jsp"
    p:viewClass="org.springframework.web.servlet.view.JstlView" /> <span style="font-family: verdana, Arial, Helvetica, sans-serif; font-size: 14px; background-color: rgb(255, 255, 255);"> </span>

【2.2】使用 spring 的 jsp库

1)标签库的作用: 能够避免在脚本块中直接编写 java 代码;(干货——标签库的作用)

2)spring提供了两个JSP 标签库:一个用于表单到模型的绑定,另一个提供了通用的工具类特性;

【2.2.1】将表单绑定到模型上

1)intro:spring 的表单绑定jsp 标签库包含了14个标签,他们中的大多数都用用来渲染HTML 中的表单标签;

2)为了使用表单标签库,需要在jsp 页面上对其声明;

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

3)在注册JSP 中使用这些标签后,会得到如下程序:<sf:form method="POST" commandName="spitter">

  First Name: <sf:input path="firstName" /><br />
  Last Name: <sf:input path="lastName" /><br />
  Email: <sf:input path="email" /><br />
  Username: <sf:input path="username" /><br />
  Password: <sf:password path="password" /><br />
  <input type="submit" value="Register" />
 </sf:form> 

代码分析(Analysis): <sf:form>标签 会渲染为一个 HTML<form> 标签,通过 commandName 属性构建针对某个模型对象的上下文信息;这就需要我们必须要有一个key==spitter的对象;

4)我们可以指定email 域:

Email: <sf:input path="email" type="email" /><br/> 

4.1)得到的 HTML 如下所示:

Email:
    <input id="email" name="email" type="email" value="jack"/><br/> 

5)为了矫正用户输入错误,需要使用 标签 <sf:errors>

【2.2.2】展现错误

1)将 <sf:errors> 用到 registerForm.jsp 中的代码片段中;

<sf:form method="POST" commandName="spitter">
    First Name: <sf:input path="firstName" />
    <sf:errors path="firstName" /><br/>
    ...
</sf:form> 

代码分析(Analysis): 这里path 属性设置为 firstName,即指定了要显示 Spitter 模型对象中哪个属性的的错误;

看个荔枝)如果用户提交字母”J“的话,那么如下的HTML 片段就是针对 firstName 输入域所显示的内容:

First Name: <input id="firstName"
                    name="firstName" type="text" value="J"/>
<span id="firstName.errors">size must be between 2 and 30</span> 

2)进一步修改错误的样式,使其更加突出显示;设置 cssClass属性:

<sf:form method="POST" commandName="spitter">
    First Name: <sf:input path="firstName" />
  <sf:errors path="firstName" cssClass="error" />
  <br />
...
</sf:form>

2.1)再定义一个css样式:

span.error {
    color: red;
} 

3)problem+solution:

3.1)problem:在输入域的旁边展现错误信息是一种很好的方式,但是会带来布局问题;

3.2)solution:将所有的错误信息都 在同一个地方进行显示;我们可以移除每个输入域上的 <sf:errors> 元素,并将其放到表单的顶部,如下所示:

<sf:form method="POST" commandName="spitter" >
    <sf:errors path="*" element="div" cssClass="errors" />
        ...
</sf:form> 

对以上代码分析(Analysis):这里的paht被设置为了 “*”,这是一个通配符选择器;会告诉 <sf: errors> 展现所有属性的所有错误;

4)通过为每个输入域设置 cssErrorClass 属性,显示需要修正的输入域;

<sf:form method="POST" commandName="spitter">
  <sf:label path="firstName" cssErrorClass="error">First Name</sf:label>:
    <sf:input path="firstName" cssErrorClass="error" />
      <br />
    ...
</sf:form> 

对以上代码的分析(Analysis):

A1)<sf:label> 标签:使用path 来指定它属于模型对象中的 哪个属性;在本例中,将其设置为 firstName,它会绑定 spitter对象的 firstName属性;

A2)如果校验错误的话,渲染得到 的<label>元素中,class属性将会被设置为 error:

<label for="firstName" class="error">First Name</label> 

A3)还可以设置一些css 属性

label.error {
    color: red;
}
input.error {

} 

5)如何让错误信息更加易读。可以在校验注解上设置 message属性,使其引用对用户更为友好的信息,这些信息定义在属性文件中;并将该属性文件放在根目录下;

// ValidationMessages.properties 文件内容如下(放置在根类路径下,即 project/src/ 目录下):

firstName.size=First name must be between {min} and {max} characters long.
lastName.size=Last name must be between {min} and {max} characters long.
username.size=Username must be between {min} and {max} characters long.
password.size=Password must be between {min} and {max} characters long.
email.valid=The email address must be valid. 

【2.2.3】spring 通用的标签库

1)要使用spring通用的标签库,在页面上对其进行声明;

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

2)spring的jsp 标签库提供了多个便利的标签;

【2.2.4】展现国际化消息

1)考虑首页info:

<h1>Welcome to Spittr!</h1>  

1.1)考虑将其国际化,<s:message>标签就是一个很好地方案;

<h1><s:message code="spittr.welcome" /></h1> 

对以上代码的分析(Analysis):该标签将会工具  key=spittr.welcome 的信息源来渲染文本;

1.2)spring有多个信息源类,都实现了 MessageSource接口,最为常见的是ResourceBundleMessageSource.

1.3)intro to ResourceBundleMessageSource:它会从属性文件中加载信息,该属性文件的名称根据基础名称(base name)衍生而来的。如下的 @Bean 方法配置了 ResourceBundleMessageSource:

@Bean
 public MessageSource messageSource() {
  ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
  messageSource.setBasename("messages"); // 核心在于设置basename属性值.
  return messageSource;
 } 

对以上代码的分析(Analysis):将basename属性值设置为 messages后,SourceBundleMessageSource就会视图在根路径的属性文件中解析信息,这些属性文件的名称是根据这个基础名称衍生得到的;

1.4)还可以使用ReloadableResourceBundleMessageSource,它能够重新加载信息属性,而不必重新编译或重启应用,其配置如下:

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

对以上代码的分析(Analysis):

A1)关键区别在于 basename 属性设置为在应用的外部查找(而不是像 ResourceBundleMessageSource 在类路径下查找);

A2)basename的属性可以设置在类路径下,文件系统中或web 应用的根路径下查找属性;

2)创建属性文件

2.1)创建默认的属性文件,名为 messages.properties:它要么位于根路径下(使用ResourceBundleMessageSource),要么位于pathname属性指定的路径下 (使用ReloadableResourceBundleMessageSource);

2.2)对于 spittr.welcome 信息来讲,需要如下条目:

spittr.welcome=Welcome to Spittr!

2.3)problem+solution:

2.3.1)problem:如果你不再创建其他信息文件的话,我们所做的事情就是将jsp中硬编码的信息抽取到了属性文件中,仍然是硬编码;

2.3.2)solution:如果想要设置西班牙语的话,需要创建另外一个 名为 message_es.properties 的属性文件

spittr.welcome=Bienvenidos a Spittr!

【2.2.5】创建URL

1)intro:<s:url>的主要任务就是创建 URL,然后将其赋值给一个变量或渲染到相应中, 它是 JSTL 中 <c:url> 标签的替代者;(干货——<s:url> 是 JSTL 中 <c:url> 标签的替代者)

2)看几个荔枝:

2.1)<a href="<s:url href="/spitter/register" />">Register</a>,如果应用的servlet上下文名为 spittr,则 <s:url> 将会渲染为:

<a href="/spittr/spitter/register">Register</a> 

2.2)将<s:url> 进行赋值,并使用:

<s:url href="/spitter/register" var="registerUrl" />
<a href="${registerUrl}">Register</a> 

2.3)default case, URL是在页面作用域内创建的。但通过设置scope 属性,可以让 <s:url> 在应用作用域内,会话作用域内或请求作用域内创建URL:(干货——default case,URL是在页面作用域内创建的)

<s:url href="/spitter/register" var="registerUrl" scope="request" /> 

2.4)如果希望添加参数的话,使用 <s:param>标签;

<s:url href="/spittles" var="spittlesUrl">
    <s:param name="max" value="60" />
    <s:param name="count" value="20" />
</s:url> 

3)各种需求组团袭来

3.1)假设我们要为特定用户的基本信息页面创建一个URL,<s:param> 标签可以承担此任; (干货——这里用到了占位符{username})

<s:url href="/spitter/{username}" var="spitterUrl">
    <s:param name="username" value="jbauer" />
</s:url> 

3.2)解决URL 的转义需求:希望将渲染得到的URL 内容展现在 web 页面上(而不是作为超链接),这就要求 <s:url> 进行HTML 转义,将 htmlEscape属性设置为 true;

<s:url value="/spittles" htmlEscape="true">
    <s:param name="max" value="60" />
    <s:param name="count" value="20" />
</s:url>
所渲染得到的结果为:
/spitter/spittles?max=60&count=20 

3.3)解决在 javascript中使用URL的话,应该将 javascriptEscape 属性设置为 true;

<s:url value="/spittles" var="spittlesJSUrl" javaScriptEscape="true">
    <s:param name="max" value="60" />
    <s:param name="count" value="20" />
</s:url>
<script>
    var spittlesUrl = "${spittlesJSUrl}"
</script>

渲染得到的结果为:
<script>
    var spittlesUrl = "\/spitter\/spittles?max=60&count=20"
</script> 

【2.2.6】转义内容(<s:escapeBody> 标签)

1)intro:<s:escapeBody> 标签是一个转义标签;

2)任务来啦:

2.1)任务一:需要将  "<" and ">" 字符替换为 &lt, &gt;<s:escapeBody> 可以做到这一点;

<s:escapeBody htmlEscape="true">
    <h1>Hello</h1>
</s:escapeBody>
所渲染得到的结果为:
&lt;h1&gt;Hello&lt;/h1&gt; 

2.2)通过设置 javaScriptEscape属性,<s:escapeBody> 标签还支持 JavaScript 转义:

<s:escapeBody javaScriptEscape="true">
    <h1>Hello</h1>
</s:escapeBody> 

【3】使用 Apache Tiles视图定义布局

1)intro:为了更好的定义视图布局,引入了布局引擎,如Apache Tiles;(干货——引入了布局引擎);

【3.1】配置 Tiles 视图解析器

1)intro:为了在spring 中使用 Tiles,需要配置几个 bean

1.1)需要一个 TilesConfigurer bean:负责定位和加载 Tile 定义并协调生成 Tiles;

1.2)还需要TilesViewResolver bean: 将逻辑视图名称解析为 Tile定义;

2)设置的具体操作:

2.1)需要一个 TilesConfigurer bean:负责定位和加载 Tile 定义并协调生成 Tiles;

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

对以上代码的分析(Analysis):

A1)所要设置的最重要的属性是 definitions:这个属性接收一个 string 类型的 数组,其中每个条目都指定一个 Tile定义的 xml 文件;

A2)我们可以在数组中指定多个文件,并使用通配符;

tiles.setDefinitions(new String[] {
    "/WEB-INF/**/tiles.xml"
}); 

对以上代码的分析(Analysis): 

A1)我们要求 TilesConfigurer  加载 /WEB-INF/ 目录下的所有名字为 tiles.xml 的文件;

A2)上述代码使用了 Ant 风格的通配符(**);

2.2)还需要TilesViewResolver bean: 将逻辑视图名称解析为 Tile定义;

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

通过XML 配置的代码如下:

<bean id="tilesConfigurer"
 class="org.springframework.web.servlet.view.tiles3.TilesConfigurer">
 <property name="definitions">
  <list>
   <value>/WEB-INF/layout/tiles.xml.xml</value>
   <value>/WEB-INF/views/**/tiles.xml</value>
  </list>
 </property>
</bean>
<bean id="viewResolver"
 class="org.springframework.web.servlet.view.tiles3.TilesViewResolver" /> 

Conclusion)

C1)TilesConfigurer 会加载 Tile定义并与 Apache Tiles协作;

C2)而 TilesViewResolver 会将逻辑视图名称解析为引用 Tile 定义的视图。它是通过查找与 逻辑视图名称相匹配的Tile 定义实现该功能的;

【3.1.1】 定义Tiles

1)intro:Apache Tiles 提供了一个文档类型定义(document type definition, DTD),用来在 XML文件中指定Tile的定义。每个定义中需要包含一个 <definition> 元素,这个元素会有一个或多个 <put-attribute>元素;

2)看个荔枝:如下的xml 文档为 Spittr 应用定义了几个 Tile:

<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE tiles-definitions PUBLIC
       "-//Apache Software Foundation//DTD Tiles Configuration 3.0//EN"
       "http://tiles.apache.org/dtds/tiles-config_3_0.dtd">
<tiles-definitions>

  <definition name="base" template="/WEB-INF/layout/page.jsp">
    <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">  // hightlight line: 这里用到了继承,碉堡了.
    <put-attribute name="body" value="/WEB-INF/views/home.jsp" />
  </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> 

对以上代码的分析(Analysis):

A1)每个 <definition> 元素都定义了一个 Tile,它最终引用的是一个 JSP 模板;

A2)某个 Tile 可能还引用其他的JSP模板,对于base Tile 来讲,引用的是一个头部 jsp 模板 和 一个底部 jsp 模板;

3)base Tile 所引用的page.jap 模板如下面程序清单所示:

<%@ taglib uri="http://www.springframework.org/tags" prefix="s" %>
<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="t" %>
 <%@ taglib prefix="tiles" uri="http://tiles.apache.org/tags-tiles" %>
<%@ 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> 

对以上代码的分析(Analysis):重点在于 使用 Tile标签库中的 <t:insertAttribute> jsp 标签来插入其他的模板;插入了 header, body,  footer 的模板;

【4】 使用Thymeleaf 模板

1)problem+solution:

1.1)problem:jsp最明显的问题:在于它看起来像 HTML 或 XML,但它其实并不是。大多数的jsp 模板都采用了HTML 的形式,但 又掺杂了各种jsp 标签库的标签,使其变得很是混乱;

1.2)solution:Thymelead模板:能在接收原始HTML 的地方进行编辑和渲染。因为它没有和 servlet规范耦合,因此 Thymeleaf 模板能够进入jsp 所无法涉足的领域;

【4.1】配置 Thymeleaf 视图解析器

1)intro:为了要在spring中 使用 Thymeleaf,我们要配置三个启用 Thymeleaf 与 spring集成的bean;

1.1)ThymeleafViewResolver:将逻辑视图名解析为 Thymeleaf 模板视图;

1.2)SpringTemplateEngine:处理模板并渲染结果;

1.3)TemplateResolver: 加载 Thymeleaf模板;

2)如下是声明这些bean 的 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/templates/");
  templateResolver.setSuffix(".html");
  templateResolver.setTemplateMode("HTML5");
  return templateResolver;
 } 

2.1)通过XML 声明这些bean 的java配置

<bean id="viewResolver" class="org.thymeleaf.spring3.view.ThymeleafViewResolver"
 p:templateEngine-ref="templateEngine" />
<bean id="templateEngine" class="org.thymeleaf.spring3.SpringTemplateEngine"
 p:templateResolver-ref="templateResolver" />
<bean id="templateResolver"
 class="org.thymeleaf.templateresolver.ServletContextTemplateResolver"
 p:prefix="/WEB-INF/templates/" p:suffix=".html" p:templateMode="HTML5" />

Conclusion)不管采用何种配置,Thymeleaf都可以将响应中的模板渲染到 spring mvc 控制器所处理的请求中;

3)ThymeleafViewResolver

3.1)intro:ThymeleafViewResolver 是 spring mvc 中 ViewResolver的一个实现类;

3.2)需要注意的是:ThymeleafViewResolver bean 中注入了一个对  SpringTemplateEngine bean 的引用;

3.2)SpringTemplateEngine 会在spring中启用 Thymeleaf引擎,用来解析模板,并基于这些模板渲染结果;

3.4)TemplateResolver会最终定位和查找模板,它也使用了prefix 和 suffix 属性。前缀和后缀将会与 逻辑视图名组合使用,进而定位 Thymeleaf 引擎,它的templateMode属性被设置为 HTML5,这表明我们预期要解析的模板会渲染成 HTML5 输出;

【4.2】定义 Thymeleaf 模板

1)intro: Thymeleaf之所以能够发挥作用,是因为它通过自定义的命名空间,为标准的HTML 标签集合添加 Thymeleaf属性;

2)使用 Thymeleaf模板的 home.html源码

<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Spittr</title>
    <link rel="stylesheet" type="text/css" th:href="@{/resources/style.css}"></link>
</head>
<body>
    <h1>Welcome to Spittr</h1>
    <a th:href="@{/spittles}">Spittles</a> |
    <a th:href="@{/spitter/register}">Register</a>
</body>
</html> 

【4.2.1】借助Thymeleaf实现表单绑定

1)review 表单绑定

1.1) 下面展现了在 registration.jsp 中的firname 输入域:

<sf:label path="firstName"
    cssErrorClass="error">First Name</sf:label>:
<sf:input path="firstName" cssErrorClass="error" /><br/>

2)考虑如下的 Thymeleaf模板片段,它会渲染first name输入域:

<label th:class="${#fields.hasErrors(‘firstName‘)}? ‘error‘">
    First Name</label>:
<input type="text" th:field="*{firstName}"
    th:class="${#fields.hasErrors(‘firstName‘)}? ‘error‘" /><br/>

对以上代码分析(Analysis):

A1)不再使用jsp 标签中的 cssClassName 属性,而是在标准的HTML 标签中上使用 th:class 属性;th:class 属性会渲染成为一个 class属性;

A2)<input> 标签使用了 th:field 属性,用来引用后端对象的 firstname域;

3)以下代码暂时了完整的注册表单模板

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<form method="POST" th:object="${spitter}"><div class="errors" th:if="${#fields.hasErrors(‘*‘)}">
<ul>
<li th:each="err : ${#fields.errors(‘*‘)}" th:text="${err}">Input
is incorrect</li>
</ul>
Listing 6.7 Registration page, using Thymeleaf to bind a form to a
command object Display errors 192 CHAPTER 6 Rendering web views
</div>
<label th:class="${#fields.hasErrors(‘firstName‘)}? ‘error‘">
First Name</label>: <input type="text" th:field="*{firstName}"
th:class="${#fields.hasErrors(‘firstName‘)}? ‘error‘" /><br /> <label
th:class="${#fields.hasErrors(‘lastName‘)}? ‘error‘"> Last
Name</label>: <input type="text" th:field="*{lastName}"
th:class="${#fields.hasErrors(‘lastName‘)}? ‘error‘" /><br /> <label
th:class="${#fields.hasErrors(‘email‘)}? ‘error‘"> Email</label>: <input
type="text" th:field="*{email}"
th:class="${#fields.hasErrors(‘email‘)}? ‘error‘" /><br /> <label
th:class="${#fields.hasErrors(‘username‘)}? ‘error‘">
Username</label>: <input type="text" th:field="*{username}"
th:class="${#fields.hasErrors(‘username‘)}? ‘error‘" /><br /> <label
th:class="${#fields.hasErrors(‘password‘)}? ‘error‘">
Password</label>: <input type="password" th:field="*{password}"
th:class="${#fields.hasErrors(‘password‘)}? ‘error‘" /><br /> <input
type="submit" value="Register" />
</form>
</body>
</html>
时间: 2024-10-15 11:58:06

spring(6) 渲染web视图的相关文章

Spring Boot? 使用Thymeleaf模板引擎渲染web视图

静态资源访问 在我们开发Web应用的时候,需要引用大量的js.css.图片等静态资源. 默认配置 Spring Boot默认提供静态资源目录位置需置于classpath下,目录名需符合如下规则: /static /public /resources /META-INF/resources 举例:我们可以在src/main/resources/目录下创建static,在该位置放置一个图片文件.启动程序后,尝试访问http://localhost:8080/D.jpg.如能显示图片,配置成功. 渲染

SpringBoot:2.SpringBoot整合Thymeleaf模板引擎渲染web视图

在Web开发过程中,Spring Boot可以通过@RestController来返回json数据,那如何渲染Web页面?Spring Boot提供了多种默认渲染html的模板引擎,主要有以下几种: Thymeleaf FreeMarker Velocity Groovy Mustache Spring Boot 推荐使用这些模板引擎来代替 Jsp,Thymeleaf 只是其中一种,下面我们来简单聊聊Thymeleaf及实践一下如何整合Spring Boot和Thymeleaf. 1.Thyme

Spring Boot? 使用freemarker模板引擎渲染web视图

效果图 代码 package com.wls.integrateplugs.hello.controller; /** * Created by wls on 2017/8/24. */ import java.util.Locale; import java.util.UUID; import javax.servlet.http.HttpSession; import com.sun.org.apache.regexp.internal.RE; import org.springframew

第6章—渲染web视图—使用Apache Tiles视图定义布局

使用Apache Tiles视图定义布局 Tiles是一个免费的开源模板Java应用程序的框架.基于复合模式简化的用户界面的构建.对于复杂的网站仍是最简单.最优雅的方式与任何MVC技术一起工作.Struts2对Tiles提供了支持,如今Tiles发展已有13个年头,成为Apache的一个独立项目,我们可以单独使用Tiles来构建用户界面布局. Tiles项目:http://tiles.apache.org/index.html Tiles的配置DTD定义:http://tiles.apache.

使用JSP渲染Web视图

Pom文件引入以下依赖 注意,创建SpringBoot整合JSP,一定要为war类型,否则会找不到页面 不要把jsp页面存放在Resources目录下,resources目录是给springboot打jar包读取配置文件用的,产生的jsp会被别人访问到,这是存放资源目录的文件 1.创建War类型的springboot项目 1)引入Springbootweb核心组件 <dependency> <groupId>org.springframework.boot</groupId&

Spring Boot入门第二天:一个基于Spring Boot的Web应用,使用了Spring Data JPA和Freemarker。

今天打算从数据库中取数据,并展示到视图中.不多说,先上图: 第一步:添加依赖.打开pom.xml文件,添加必要的依赖,完整代码如下: <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance&q

构建一个基于 Spring 的 RESTful Web Service

本文详细介绍了基于Spring创建一个“hello world” RESTful web service工程的步骤. 目标 构建一个service,接收如下HTTP GET请求: http://localhost:8080/greeting 并返回如下JSON格式的问候语: {"id":1,"content":"Hello, World!"} 你也可以通过指定查询字符串中的可选参数name来定制问候语: http://localhost:8080

Spring Boot开发Web应用之Thymeleaf篇

前言 Web开发是我们平时开发中至关重要的,这里就来介绍一下Spring Boot对Web开发的支持. 正文 Spring Boot提供了spring-boot-starter-web为Web开发予以支持,spring-boot-starter-web为我们提供了嵌入的Tomcat以及Spring MVC的依赖. 项目结构推荐 一个好的项目结构会让你开发少一些问题,特别是Spring Boot中启动类要放在root package下面,我的web工程项目结构如下: root package结构:

基于Spring框架的Web应用开发笔记 - incomplete

Motivation 最近的工作涉及Web框架搭建,在了解公司原有采用框架基础上对Web开发技术栈做了一次升级,在次做记录. Audience J2EE Web Application Developer, Spring user, Scope 快速应用开发.Web层+安全.持久层 Progress 2015/6/14 init Outline 1 用Spring Boot快速开发应用 2 Spring的Web框架和Security横切面 3 Spring Data:通用数据持久化解决方案 Co