Web 应用的功能通常不局限于给用户推送内容,大多数应用允许用户填充表单并将数据提交回应用中,通过这种方式与用户进行交互。使用表单分为展现表及和处理用户通过表单提交的数据。
关于注册的一个小例子
控制器:
SpitterController.java用来处理展示表单、处理用户提交的数据并且展示用户注册信息功能。
package XiyouLinux.controller;
import XiyouLinux.data.Spitter;
import XiyouLinux.data.SpitterRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.Errors;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
import javax.validation.Valid;
@Controller
@RequestMapping("/")
public class SpitterController {
private SpitterRepository spitterRepository;
// 注入SpitterRepository
@Autowired
public SpitterController(SpitterRepository spitterRepository) {
this.spitterRepository = spitterRepository;
}
//处理表单
@RequestMapping(value = "/register", method = RequestMethod.POST)
public String processRegistration(@ModelAttribute("command") @Valid Spitter spitter, Errors errors) {
if(errors.hasErrors()){
return "registerForm";
}
// 保存Spitter
spitterRepository.save(spitter);
// 重定向到新的页面
return "redirect:/" + spitter.getUsername();
}
//展示表单
@RequestMapping(value = "/register", method = RequestMethod.GET)
public ModelAndView student() {
return new ModelAndView("registerForm", "command", new Spitter());
}
//展现某个用户的注册信息
@RequestMapping(value = "/{username}", method = RequestMethod.GET)
public String showSpitterProfile(@PathVariable("username") String username, Model model) {
Spitter spitter = spitterRepository.findByUsername(username);
model.addAttribute(spitter);
return "profile";
}
}
用来渲染的JSP
registerForm.jsp展示表单和响应的错误信息,modelAttribute表明该表单和model里对象对应;<form:label>、<form:password>及<form:input>等标签的中的path表明其和model里的对象的属性对应。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<%@ taglib prefix="sf" uri="http://www.springframework.org/tags/form" %>
<jsp:useBean id="command" class="XiyouLinux.data.Spitter" scope="request"></jsp:useBean>
<html>
<head>
<title>Register</title>
<style type="text/css">
span.error {
color: red;
}
label.error {
color: red;
}
input.error {
background-color: #ffcccc;
}
div.errors {
background-color: #ffcccc;
border: 1px;
}
</style>
</head>
<body>
<h2>Register</h2>
<form:form method="POST" action="/register" modelAttribute="command">
<form:errors path="firstname" element="div" cssClass="errors" />
<form:errors path="lastname" element="div" cssClass="errors" />
<form:errors path="username" element="div" cssClass="errors" />
<form:errors path="password" element="div" cssClass="errors" />
<table>
<tr>
<td><form:label path="firstname" cssErrorClass="error">First name</form:label></td>
<td><form:input path="firstname" cssErrorClass="error"/></td>
</tr>
<tr>
<td><form:label path="lastname" cssErrorClass="error">Last name</form:label></td>
<td><form:input path="lastname" cssErrorClass="error"/></td>
</tr>
<tr>
<td><form:label path="username" cssErrorClass="error">Username</form:label></td>
<td><form:input path="username" cssErrorClass="error"/></td>
</tr>
<tr>
<td><form:label path="password" cssErrorClass="error">Password</form:label></td>
<td><form:password path="password" cssErrorClass="error"/></td>
</tr>
<tr>
<td colspan="2">
<input type="submit" value="register"/>
</td>
</tr>
</table>
</form:form>
</body>
</html>
profile.jsp用来展示某个用户的注册信息,” ${ } “可以用来取的model中属性对应的值。
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Your Profile</title>
</head>
<body>
<h1>Your profile</h1>
Username: <c:out value="${spitter.username}" /> <br/>
Firstname:<c:out value="${spitter.firstname}" /> <br/>
Lastname:<c:out value="${spitter.lastname}" /> <br/>
</body>
</html>
关于Spring的配置
configuration.java
package XiyouLinux.configuration;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.validation.Validator;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
import org.springframework.validation.beanvalidation.MethodValidationPostProcessor;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;
@Configuration
@ComponentScan(basePackages = "XiyouLinux")
public class configuration extends WebMvcConfigurationSupport{
//视图解析器
@Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setPrefix("/WEB-INF/views/");
viewResolver.setSuffix(".jsp");
viewResolver.setViewClass(JstlView.class);
return viewResolver;
}
@Bean
public LocalValidatorFactoryBean localValidatorFactoryBean()
{
LocalValidatorFactoryBean localValidatorFactoryBean = new LocalValidatorFactoryBean();
localValidatorFactoryBean.setValidationMessageSource(ResourceBundleMessageSource());
return localValidatorFactoryBean;
}
@Bean
public ResourceBundleMessageSource ResourceBundleMessageSource()
{
ResourceBundleMessageSource resourceBundleMessageSource = new ResourceBundleMessageSource();
resourceBundleMessageSource.setBasename("ValidationMessages");
resourceBundleMessageSource.setCacheSeconds(60);
resourceBundleMessageSource.setDefaultEncoding("UTF-8");
return resourceBundleMessageSource;
}
//处理静态资源
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer)
{
configurer.enable();
}
}
Initializer.java
package XiyouLinux.configuration;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class Initializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] { configuration.class };
}
@Override
protected Class<?>[] getServletConfigClasses() {
return null;
}
@Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
}
pom.xml要添加相应的依赖
<?xml version="1.0" encoding="UTF-8"?>
<!-- $Id: pom.xml 642118 2008-03-28 08:04:16Z reinhard $ -->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<packaging>war</packaging>
<name>register</name>
<groupId>XiyouLinux.org</groupId>
<artifactId>register</artifactId>
<version>1.0-SNAPSHOT</version>
<build>
<plugins>
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>maven-jetty-plugin</artifactId>
<version>6.1.7</version>
<configuration>
<connectors>
<connector implementation="org.mortbay.jetty.nio.SelectChannelConnector">
<port>8888</port>
<maxIdleTime>30000</maxIdleTime>
</connector>
</connectors>
<webAppSourceDirectory>${project.build.directory}/${pom.artifactId}-${pom.version}</webAppSourceDirectory>
<contextPath>/</contextPath>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>zhi
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.1</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.7</version>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.9.Final</version>
</dependency>
</dependencies>
</project>
所需要的model
Spitter.java用户类,并且定义了校验信息。
package XiyouLinux.data;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
public class Spitter {
@NotNull
@Size(min = 5, max = 16, message = "{firstname.size}")
private String firstname;
@NotNull
@Size(min = 5, max = 25, message = "{lastname.size}")
private String lastname;
@NotNull
@Size(min = 2, max = 30, message = "{username.size}")
private String username;
@NotNull
@Size(min = 2, max = 30, message = "{password.size}")
private String password;
public Spitter(){
}
public Spitter(String firstname,String lastname,String username,String password){
this.firstname = firstname;
this.lastname = lastname;
this.username = username;
this.password = password;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}
public void setLastname(String lastname) {
this.lastname = lastname;
}
public void setPassword(String password) {
this.password = password;
}
public void setUsername(String username) {
this.username = username;
}
public String getFirstname() {
return firstname;
}
public String getLastname() {
return lastname;
}
public String getUsername() {
return username;
}
public String getPassword() {
return password;
}
}
SpitterRepository.java
package XiyouLinux.data;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import java.utSpitterRepositoryil.ArrayList;
@Component("spitterRepository")
public class SpitterRepository {
private ArrayList<Spitter> spitterRepository = new ArrayList<Spitter>();
public SpitterRepository(){}
public ArrayList<Spitter> getSpitterRepository() {
return spitterRepository;
}
public void save(Spitter spitter){
spitterRepository.add(spitter);
}
public Spitter findByUsername(String username){
for(int i =0;i<spitterRepository.size();i++){
if(spitterRepository.get(i).getUsername().equals(username))
return spitterRepository.get(i);
}
return new Spitter();
}
}
校验表单时遇到的一些小问题
- 校验表单首先要在pom.xml中添加如下依赖
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.9.Final</version>
</dependency>
- 然后在Spring配置文件中定义如下两个Bean
@Bean
public LocalValidatorFactoryBean localValidatorFactoryBean()
{
LocalValidatorFactoryBean localValidatorFactoryBean = new LocalValidatorFactoryBean();
localValidatorFactoryBean.setValidationMessageSource(ResourceBundleMessageSource());
return localValidatorFactoryBean;
}
@Bean
public ResourceBundleMessageSource ResourceBundleMessageSource()
{
ResourceBundleMessageSource resourceBundleMessageSource = new ResourceBundleMessageSource();
resourceBundleMessageSource.setBasename("ValidationMessages");
resourceBundleMessageSource.setCacheSeconds(60);
resourceBundleMessageSource.setDefaultEncoding("UTF-8");
return resourceBundleMessageSource;
}
- 接着在用户类中定义要校验的字段,如:
@NotNull
@Size(min = 5, max = 16, message = "{firstname.size}")
private String firstname;
@NotNull表示非空,@Size表示长度要在5~16间,如果验证不通过就将错误信息收集到Error中。
- 可以在ValidationMessages.properties定义了校验失败相应的错误信息,配置中文件名要与上面定义ResourceBundleMessageSource()中文件名称相对应。
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.
- 控制器处理时,要加上@Vaild注解,检测是否有错误产生,采取不同的操作。
@RequestMapping(value = "/register", method = RequestMethod.POST)
public String processRegistration(@ModelAttribute("command") @Valid Spitter spitter, Errors errors) {
if(errors.hasErrors()){
return "registerForm";
}
// 保存Spitter
spitterRepository.save(spitter);
// 重定向到新的页面
return "redirect:/" + spitter.getUsername();
}
运行测试:
表单界面
校验失败返回错误信息
校验成功返回注册用户的信息
参考:
《Spring实战(第4版)》