前言
第六章 渲染Web视图 主要讲了JSP标签库、Apache Tiles和Thymeleaf模板 。。。的简单应用
第一节介绍了视图解析器。。。 第二节开始创建JSP视图
1.创建JSP视图
Spring提供了两种支持JSP视图的方式:
- InternalResourceViewResolver会将视图名解析为JSP文件。另外,如果在你的JSP页面中使用了JSP标准标签库(JavaServer Pages Stanard Tag Library, JSTL)的话,InternalResourceViewResolver能够将视图名解析为JstlView形式的JSP文件,从而将JSTL本地化和资源bundle变量暴露给JSTL的格式化(formatting)和信息(message)标签。
- Spring提供了两个JSP标签库,一个用于表单到模型的绑定,另一个提供了通用的工具类特性。
有关jstl的配置,在 dispatcher-servlet.xml 上一章已经实现过了 下面使用Spring的JSP库: 【注意:书中commandName 已被淘汰,改用 modelAttribute 即可】
registerForm.jsp:
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="sf" uri="http://www.springframework.org/tags/form" %>
<%@ page session="false" %>
<html>
<head>
<title>Spittr</title>
<link rel="stylesheet" type="text/css" href="<c:url value="/WEB-INF/resources/style.css" />">
</head>
<body>
<h1>Register</h1>
<sf:form method="post" modelAttribute="spitter">
First Name:<sf:input path="firstName" /><br>
Last Name:<sf:input path="lastName" /><br>
UserName:<sf:input path="username" /><br>
Email:<sf:input path="email" type="email"/><br>
Password:<sf:password path="password" /><br>
<input type="submit" value="Register">
</sf:form>
</body>
</html>
虽然用的modelAttribute,但原句 “commandName属性构建针对某个模型对象的上下文信息,在其他标签引起这个对象的属性。因此,在模型中需要有一个key为spitter的对象” ,修改SpitterController:
@RequestMapping(value = "/register",method = RequestMethod.GET)
public String showRegisterForm(Model model){
model.addAttribute(new Spitter());
return "registerForm";
}
为了指导用户矫正错误,使用<sf: errors>,到模型中抽取错误信息: 给了<span>和<div>两种方式来呈现,直接写<div>效果的吧
原本css和jsp分离的,无奈不显示css效果-_-|| 偷个懒,把css样式直接写在registerForm.jsp文件里啦!
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="sf" uri="http://www.springframework.org/tags/form" %>
<%@ page session="false" %>
<html>
<head>
<title>Spittr</title>
<link rel="stylesheet" type="text/css" href="<c:url value="/WEB-INF/resources/style.css" />" >
<style type="text/css">
div.errors{
background-color: red;
border: 2px solid red;
}
label.error {
color: red;
}
input.error{
background-color: chartreuse;
}
</style>
</head>
<body>
<h1>Register</h1>
<sf:form method="POST" modelAttribute="spitter" >
<sf:errors path="*" element="div" cssClass="errors" />
<sf:label path="firstName"
cssErrorClass="error">First Name</sf:label>:
<sf:input path="firstName" cssErrorClass="error" /><br/>
<sf:label path="lastName"
cssErrorClass="error">Last Name</sf:label>:
<sf:input path="lastName" cssErrorClass="error" /><br/>
<sf:label path="email"
cssErrorClass="error">Email</sf:label>:
<sf:input path="email" cssErrorClass="error" /><br/>
<sf:label path="username"
cssErrorClass="error">Username</sf:label>:
<sf:input path="username" cssErrorClass="error" /><br/>
<sf:label path="password"
cssErrorClass="error">Password</sf:label>:
<sf:password path="password" cssErrorClass="error" /><br/>
<input type="submit" value="Register" />
</sf:form>
</body>
</html>
新建一个ValidationMessages.properties文件,放在main/resources目录下:(将错误信息抽取到属性文件,可以按需创建任意数量文件,以满足不同语言的要求)
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.
Spitter类改成:
private Long id;
@NotNull
@Size(min=5, max=16, message="{username.size}")
private String username;
@NotNull
@Size(min=5, max=25, message="{password.size}")
private String password;
@NotNull
@Size(min=2, max=30, message="{firstName.size}")
private String firstName;
@NotNull
@Size(min=2, max=30, message="{lastName.size}")
private String lastName;
@NotNull
@Email
private String email;
好,理论上工作结束了,run一下 不行,验证器没配好,百度一下 springMVC validator的配置 和这个只作了补充 把之前的几个依赖删了,重新引入:
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>1.1.0.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.1.0.Final</version>
</dependency>
<dependency>
<groupId>javax.el</groupId>
<artifactId>el-api</artifactId>
<version>2.2</version>
</dependency>
在dispatcher-servlet.xml中添加配置:
<mvc:annotation-driven />
<bean id="validator"
class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
<property name="providerClass" value="org.hibernate.validator.HibernateValidator"/>
<property name="validationMessageSource" ref="messageSource"/>
</bean>
<bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basenames">
<list>
<value>classpath:ValidationMessages</value>
</list>
</property>
<property name="fileEncodings" value="UTF-8" />
<property name="defaultEncoding" value="UTF-8"/>
<property name="cacheSeconds" value="120" />
</bean>
检查一下spitter类的import:
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.hibernate.validator.constraints.Email;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
检查一下控制器:
@RequestMapping(value = "/register",method = RequestMethod.POST)
public String processRegisterForm(@Validated Spitter spitter, BindingResult result){
if(result.hasErrors()){
return "registerForm";
}
spitterRepository.save(spitter);
return "redirect:/spitter/"+spitter.getUsername();
}
ctrl+shift+alt+s,检查一下项目结构,右边的包有没有全部右键选第一个 或者点第三个+号选第一个,全选库,ok  如果jdk版本报错,检查Project Structure(ctrl+shift+alt+s)的每一项  哈哈好辣眼的样式。。。
2.使用Apache Tiles视图定义布局
配置Tiles视图解析器:需要一个TilesConfigurer bean,它会负责定位和加载Tile定义并协调生成Tiles;除此之外,还需要TilesViewResolver bean将逻辑视图名称解析为Tile定义。 新建/WEB-INF/layout/tiles.xml
<?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">
<put-attribute name="body" value="/WEB-INF/view/home.jsp" />
</definition>
<definition name="registerForm" extends="base">
<put-attribute name="body" value="/WEB-INF/view/registerForm.jsp" />
</definition>
<definition name="profile" extends="base">
<put-attribute name="body" value="/WEB-INF/view/profile.jsp" />
</definition>
<definition name="spittles" extends="base">
<put-attribute name="body" value="/WEB-INF/view/spittles.jsp" />
</definition>
<definition name="spittle" extends="base">
<put-attribute name="body" value="/WEB-INF/view/spittle.jsp" />
</definition>
</tiles-definitions>
改了一下书上的,当初视图的目录起的是view,书上是views= = dispatcher-servlet.xml中定义视图解析器:
<bean id="tilesconfig" class="org.springframework.web.servlet.view.tiles3.TilesConfigurer">
<property name="definitions">
<list>
<value>/WEB-INF/layout/tiles.xml</value>
</list>
</property>
</bean>
<bean id="tilesviewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="order" value="1" />
<property name="viewClass" value="org.springframework.web.servlet.view.tiles3.TilesView" />
</bean>
web.xml:
<listener>
<listener-class>org.apache.tiles.extras.complete.CompleteAutoloadTilesListener</listener-class>
</listener>
/WEB-INF/layout/header.jsp:
<%@ taglib uri="http://www.springframework.org/tags" prefix="s" %>
<a href="<s:url value="/" />"><img
src="<s:url value="/resources" />/images/spitter_logo_50.png"
border="0"/></a>
/WEB-INF/layout/footer.jsp:
Copyright © Craig Walls
/WEB-INF/layout/page.jsp:
<%@ taglib uri="http://www.springframework.org/tags" prefix="s" %>
<%@ taglib uri="http://tiles.apache.org/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>
最后,可以对home.jsp进行简化:
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page session="false" %>
<h1>Welcome to Spitter</h1>
<a href="<c:url value="/spittles" />">Spittles</a> |
<a href="<c:url value="/spitter/register" />">Register</a>
好,紧张run—— 还是不行,查了一下是依赖问题,沃日改了我两天,改好的时候简直快哭了  【经常出现的jdk版本问题,一个是检查Project Structure,一个是检查File - Settings - Java Compiler】 总结一下,主要是引入tiles-extras依赖,会包含org.springframework:xxxxxxx若干库,一开始我都是一股脑加到lib文件夹,造成了不少冲突,最后把它们移除就成功了。。。 期间遇到一个**SLF4J: Failed to load class “org.slf4j.impl.StaticLoggerBinder“**问题,看的这篇插件报错:SLF4J: Failed to load class “org.slf4j.impl.StaticLoggerBinder“.解决方案 最后pom.xml:
<dependency>
<groupId>org.apache.tiles</groupId>
<artifactId>tiles-extras</artifactId>
<version>3.0.8</version>
</dependency>
<dependency>
<groupId>org.apache.tiles</groupId>
<artifactId>tiles-servlet</artifactId>
<version>3.0.8</version>
</dependency>
<dependency>
<groupId>org.apache.tiles</groupId>
<artifactId>tiles-jsp</artifactId>
<version>3.0.8</version>
</dependency>
<dependency>
<groupId>org.apache.tiles</groupId>
<artifactId>tiles-core</artifactId>
<version>3.0.8</version>
</dependency>
<dependency>
<groupId>org.apache.tiles</groupId>
<artifactId>tiles-api</artifactId>
<version>3.0.8</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.25</version>
</dependency>
lib文件夹:  以后加依赖得谨慎谨慎。。。
3.使用Thymeleaf
Thymeleaf模板是原生的,不依赖于标签库,它能在接受原始HTML的地方进行编辑和渲染。因为它没有与Servlet规范耦合,因此Thymeleaf模板能够进入JSP无法涉足的领域。 配置Thymeleaf视图解析器: 添加依赖:
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring4</artifactId>
<version>3.0.9.RELEASE</version>
</dependency>
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf</artifactId>
<version>3.0.9.RELEASE</version>
</dependency>
dispatcher-servlet.xml:
<bean class="org.thymeleaf.spring4.view.ThymeleafViewResolver">
<property name="templateEngine" ref="templateEngine" />
</bean>
<bean id="templateEngine"
class="org.thymeleaf.spring4.SpringTemplateEngine">
<property name="templateResolver" ref="templateResolver" />
</bean>
<bean id="templateResolver"
class="org.thymeleaf.spring4.templateresolver.SpringResourceTemplateResolver">
<property name="prefix" value="/WEB-INF/template/" />
<property name="suffix" value=".html" />
<property name="templateMode" value="HTML5" />
</bean>
在 WEB-INF/ 下新建template文件夹,存放html文件 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>
记得把视图解析器里jsp和tiles的几段注释掉(ctrl+shift+/) 
总结
css和图片都没有显示效果,大概是路径的问题,留爪~
|