标签:srping in action spring实战4 spring标签库
spring 4.0 原生支持13种视图解析器
从spring3.2版本开始,spring支持上述13种解析器,但是spring 3.1不支持Tiles 3 TilesViewResolver,其它的12种都支持.
视图解析器所在的配置文件
@Configuration
@EnableWebMvc
@ComponentScan("_5BuildingSpringwebapplications")
public class WebConfig extends WebMvcConfigurerAdapter {
@Bean
public ViewResolver viewResolver() {
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();
}
}配置视图解析器核心代码
@Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
resolver.setExposeContextBeansAsAttributes(true);
return resolver;
}对应在xml中配置时,如下示,配置在spring应用上下文中
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="viewClass" value="org.springframework.web.servlet.view.InternalResourceViewResolver" /> <property name="prefix" value="/WEB-INF/views/"/> <property name="suffix" value=".jsp"/> </bean>
下面是示例的逻辑视图名与物理文件的对应关系,注意最后的示例与前两个示例的区别
home resolves to /WEB-INF/views/home.jsp productList resolves to /WEB-INF/views/productList.jsp books/detail resolves to /WEB-INF/views/books/detail.jsp
通常在使用jsp的时候都使用JSTL,但是InternalResourceViewResolver的功能相对比较简单,因此需要将其替换为JstlView,如下示,
在使用jstlview之前,需要在项目里引入jstl相关的jar包
build.gradle配置
compile "javax.servlet:jstl:$jstlVersion"
gradle.properties配置 jstlVersion = 1.2
InternalResourceViewResolver被JstlView替换
@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;
}对应的xml配置
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" /> <property name="prefix" value="/WEB-INF/views/"/> <property name="suffix" value=".jsp"/> </bean>
spring提供两种jsp标签库.
One tag library renders HTML form tags that are bound to a model attribute. The other has a hodgepodge of utility tags that come in handy from time to time.
第一种标签库,即表单绑定的jsp标签库包含14个标签,这些标签与html原生标签是有区别的,spring的标签可以获取model对象的属性值.其中一个标签可以将error信息反馈到结果页面中,即下文中提到的errors.
使用这些Spring标签的方法就是在jsp页面中声明.如下示
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="sf" %>
在上述的声明语句中,prefix="sf"里的"sf"由用户自定义,用于与原生的html标签做区别,比如也可以定义成这样,
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="springformtag" %>
这14个标签如下图示,注意标签前的前缀,这里的前缀是sf,因为之前在spring标签声明时定义了prefix="sf",如果声明时定义的不是sf,在使用时就不能照搬下面的用法了.
很难在一个页面中把上述所有标签的使用都示例出来.下面将结合书中的示例系统说明<sf:form>, <sf:input>, and <sf:password>这三个标签的使用方法.
在第5章中写过一个用户注册页面,当时的写法如下所示
<body> <h1>Register</h1> <form method="POST"> First Name: <input type="text" name="firstName" /><br /> Last Name: <input type="text" name="lastName" /><br /> Username: <input type="text" name="username" /><br /> Password: <input type="password" name="password" /><br /> <input type="submit" value="Register" /> </form> </body>
下面是使用了spring标签的写法
<body> <h1>Register</h1> <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> </body>
<sf:form> 标签与HTML <form> 标签的功能类似,但是它指定了commandName属性,该属性绑定了一个model对象.这要求逻辑视图包含一个同名的model对象,因此需要对原来的控制器做相应的修改
原contrller SpitterController.java中的showRegistrationForm方法
@RequestMapping(value = "/register", method = RequestMethod.GET)
public String showRegistrationForm() {
return "registerForm";
}修改后的代码,可以看到修改后,该方法在返回逻辑视图前在逻辑视图中增加了一个名为spitter的model属性,其实可以不用明确指定对象名,因为jsp页面中的对象名与类名一致,这与spring指定的默认对象名相同(类名首字母小写).因此添加属性的代码可写成model.addAttribute(new Spitter())
@RequestMapping(value = "/register", method = RequestMethod.GET)
public String showRegistrationForm(Model model) {
model.addAttribute("spitter",new Spitter());
return "registerForm";
}回到使用的spring标签的jsp页面中,First Name: <sf:input path="firstName" />表示该输入框绑定的是new Spitter()类的firstName成员变量.注意,该成员变量名JSP页面中不能写错,如果写成First Name: <sf:input path="firstNamexxxx" />,那么运行时会报错.依此类推,
Last Name: <sf:input path="lastName" />表示该输入框对应的是new Spitter()类的lastName成员变量..等等.再次声明,成员变量名在JSP页面中不要写错.
假如在输入框中输入如下内容
那么该表单提交后,将向后台传递一个firstName为11,lastName为22,email为11@22.com,username为1122的Spitter的对象.
在SpitterController.java的processRegistration方法中增加了一行输出可以用来验证对象的成员变量是否是我们在jsp页面的输入
输出结果
注意,如果在域对象spitter的定义中加入了校验,上述的结果是不可能成功的,因为我们在jsp页面中的输入并不满足校验的条件,因此需要将spitter定义中的校验取消掉,如下图示
补充一个第5章中的知识点.回到上述的JSP页面中,可以看到该form表单中并没有写明action属性,如果没有写明的话,提交该表单时将默认返回打开该页面时使用逻辑视图名,但是与打开该页面时视图对应的get方法不同,提交表单时要求逻辑视图对应post方法.下图示
回到校验的话题,如果在上述实验中我们没有取消在域对象spitter定义时给予的校验,那么在校验失败时,如何在jsp页面中向用户展示错误信息呢?
下面先还原在spitter对象定义中给予的检验,如下图示
package _5BuildingSpringwebapplications.domain;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.hibernate.validator.constraints.Email;
public class 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(message = "{email.valid}")
private String email;
public Spitter() {
}
public Spitter(String username, String password, String firstName, String lastName, String email) {
this(null, username, password, firstName, lastName, email);
}
public Spitter(Long id, String username, String password, String firstName, String lastName, String email) {
this.id = id;
this.username = username;
this.password = password;
this.firstName = firstName;
this.lastName = lastName;
this.email = email;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
@Override
public boolean equals(Object that) {
return EqualsBuilder.reflectionEquals(this, that, "firstName", "lastName", "username", "password", "email");
}
@Override
public int hashCode() {
return HashCodeBuilder.reflectionHashCode(this, "firstName", "lastName", "username", "password", "email");
}
}在classpath根目录下新建ValidationMessages.properties
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.registerForm.jsp
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <%@ taglib uri="http://www.springframework.org/tags/form" prefix="sf" %> <%@ page session="false"%> <html> <head> <title>Spittr</title> <link rel="stylesheet" type="text/css" href="<c:url value="/resources/style.css" />"> </head> <body> <h1>Register</h1> <sf:form method="POST" commandName="spitter"> <sf:errors path="*" element="div" cssClass="errors" /> First Name: <sf:input path="firstName" /> <!-- <span id="firstName.errors">size must be between 2 and 30</span> --> <br /> Last Name: <sf:input path="lastName" /> <!-- <span id="lastName.errors">size must be between 2 and 30</span> --> <br /> Email: <sf:input path="email" /> <!-- <span id="email.errors">size must be between 2 and 30</span> --> <br /> Username: <sf:input path="username" /> <!-- <span id="username.errors">size must be between 2 and 30</span> --> <br /> Password: <sf:password path="password" /> <!-- <span id="password.errors">size must be between 2 and 30</span> --> <br /> <input type="submit" value="Register" /> </sf:form> </body> </html>
结果
除了表单绑定的标签库外,spring还提供另一种JSP标签库.该标签库是spring最早包含的标签库.
引用方法,在JSP页面中添加
<%@ taglib uri="http://www.springframework.org/tags" prefix="s" %>
与表单绑定的标签库在引用方法上的区别在于uri上,
通用标签库的uri是
uri="http://www.springframework.org/tags"
而表单绑定的标签库的引用uri是
uri="http://www.springframework.org/tags/form"
标签描述
上图中的某些标签在表单绑定的标签库中已经被淘汰了.<s:bind>比如.
本文出自 “梦里不知身是客” 博客,转载请与作者联系!
标签:srping in action spring实战4 spring标签库
原文地址:http://tenfee.blog.51cto.com/6353835/1874550