本指南将引导你完成配置网络应用程序表单以支持验证的过程。
What You Will Build
你将建立一个简单的Spring MVC应用程序,它接受用户的输入并通过使用标准的验证注解来检查输入。你还将看到如何在屏幕上显示错误信息,以便用户可以重新输入,使其有效。
What You Need
- 大约15分钟
- 你喜欢的文本编辑器或IDE
- JDK 1.8 以上
- Graddle 4+ 或 Maven 3.2+
- 你也可以直接将代码导入进你的IDE
- Spring Tool Suite (STS)
- InteelliJ IDEA
How to complete this guide
正如Spring大多数指南一样,你可以从头开始并且完成每一个步骤或者你可以绕开你已经熟悉的基本设置。无论哪种方式,你最终都是完成代码。
为了从头开始,移步到Starting with Spring Initializr
。
为了跳过基础,做如下步骤:
- 下载并解压这篇指南的原仓库,或者使用GIt克隆
git clone https://github.com/spring-guides/gs-validating-form-input.git
- 进入(cd)
gs-validating-form-input/initial
- 移步到
Create a PersonForm
当你完成以后,你可以再次检查你的gs-validating-form-input/complete
的代码。
Starting with Spring Initializr
你可以使用预初始化项目点击Generate来下载ZIP文件。这一项目被配置为适合本篇指南。
为了手动初始化项目:
- 浏览https://start.spring.io/。这个服务拉取了你的应用所有需要的依赖并且已经为了做了多数配置。
- 选择Gradle或Maven与你想使用的语言。本文假设你选择Java。
- 点击Dependencies选择Spring Web、Thymeleaf和Validation。
- 点击Generate。
- 下载ZIP文件,这是一个为你的选择配置好的网络应用文件。
如果你的IDE整合了Spring Initializr,你可以从你的IDE完成此步骤
你也可以从GitHub中fork此项目使用你的IDE或者编辑器打开。
Create a PersonForm
Object
该应用涉及验证用户的姓名和年龄,所以你首先需要创建一个类来支持用于创建一个人的表单。下面的列表(来自 src/main/java/com/example/validatingforminput/PersonForm.java
)展示了如何做到这一点。
package com.example.validatingforminput;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
public class PersonForm {
@NotNull
@Size(min=2, max=30)
private String name;
@NotNull
@Min(18)
private Integer age;
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String toString() {
return "Person(Name: " + this.name + ", Age: " + this.age + ")";
}
}
PersonForm
类有两个属性:name
和age
。它被标记了一些标准的验证注解:
@Size(min=2, max=30)
: 允许长度在2到30个字符之间的名称。@NotNull
: 不允许出现空值,如果输入为空,Spring MVC就会生成空值。@Min(18)
: 不允许年龄低于18岁。
除此之外,你还可以看到name
和age
的getter和setter以及一个方便的toString()
方法。
Create a Web Controller
现在你已经定义了一个表单支持对象,现在是时候创建一个简单的Web控制器了。下面的列表(来自src/main/java/com/example/validatingforminput/WebController.java
)展示了如何做到这一点。
package com.example.validatingforminput;
import javax.validation.Valid;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Controller
public class WebController implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/results").setViewName("results");
}
@GetMapping("/")
public String showForm(PersonForm personForm) {
return "form";
}
@PostMapping("/")
public String checkPersonInfo(@Valid PersonForm personForm, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
return "form";
}
return "redirect:/results";
}
}
这个控制器有一个GET方法和一个POST方法。这两种方法都被映射到/
。
showForm
方法返回form
模板。它的方法签名中包括一个PersonForm
,这样模板就可以将表单属性与PersonForm
联系起来。
checkPersonInfo
方法接受两个参数:
- 一个标有
@Valid
的personForm
对象,用来收集表单中填写的属性。 - 一个
bindingResult
对象,以便你可以测试和检索验证错误。
你可以从表单中检索所有的属性,它被绑定到PersonForm
对象上。在代码中,你测试错误。如果你遇到一个错误,你可以把用户送回原始表单模板。在这种情况下,所有的错误属性都会显示出来。
如果person的所有属性都是有效的,它就会把浏览器重定向到最终result
模板。
Build an HTML Front End
现在建立主页面,正如下面的列表(来自 src/main/resources/templates/form.html)所示。
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<body>
<form action="#" th:action="@{/}" th:object="${personForm}" method="post">
<table>
<tr>
<td>Name:</td>
<td><input type="text" th:field="*{name}" /></td>
<td th:if="${#fields.hasErrors('name')}" th:errors="*{name}">Name Error</td>
</tr>
<tr>
<td>Age:</td>
<td><input type="text" th:field="*{age}" /></td>
<td th:if="${#fields.hasErrors('age')}" th:errors="*{age}">Age Error</td>
</tr>
<tr>
<td><button type="submit">Submit</button></td>
</tr>
</table>
</form>
</body>
</html>
这个页面包含一个简单的表单,它的每个字段都在一个表格的单独单元中。这个表单是用来post到/
的,它被标记为由personForm对象支持,你在Web控制器的GET
方法中看到了这个对象。这就是所谓的 "bean-backed form"。PersonForm
Bean中有两个字段,你可以看到它们被标记为th:field="*{name}"
和th:field="*{age}"
。每个字段旁边都有一个辅助元素,用来显示任何验证错误。
最后,你有一个提交表单的按钮。一般来说,如果用户输入的姓名或年龄违反了@Valid
约束,它就会弹回到这个页面,并显示错误信息。如果输入的是有效的姓名和年龄,用户会被引导到下一个网页。
下面的例子(来自src/main/resources/templates/results.html
)显示了结果页面。
<html>
<body>
Congratulations! You are old enough to sign up for this site.
</body>
</html>
在这个简单的例子中,这些网页没有任何复杂的CSS或JavaScript。
Run the Application
对于这个应用,你使用的是Thymeleaf的模板语言。这个应用程序需要的不仅仅是原始HTML。Spring Initializr为你创建了一个应用类。下面的列表(来自src/main/java/com/example/validatingforminput/ValidatingFormInputApplication.java
)显示了该类。
package com.example.validatingforminput;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ValidatingFormInputApplication {
public static void main(String[] args) throws Exception {
SpringApplication.run(ValidatingFormInputApplication.class, args);
}
}
为了激活Spring MVC,你通常会在应用类中添加@EnableWebMvc
。但是Spring Boot的@SpringBootApplication
在检测到classpath上的spring-webmvc
时已经添加了这个注解。这个注解也让它找到了被注解的@Controller
类和它的方法。
Thymeleaf的配置也由@SpringBootApplication
负责。默认情况下,模板位于classpath中的templates/
下,并通过去除文件名中的'.html'后缀被解析为视图。(Thymeleaf的设置可以通过各种方式改变和重写,这取决于你需要实现什么,但细节与本指南无关)。
Build an executable JAR
你可以在命令行以Gradle或Maven运行应用程序。你也可以构建一个单一可执行的JAR包,其中包含所有必须的依赖、类以及资源并且运行。构建一个可执行jar可以易于传输、版本和部署服务作为应用,贯穿至整个开发周期,穿插于不同环境等等。
如果你使用Gradle,你可以通过使用./gradlew bootRun
来运行应用程序。或者说,你可以使用./gradlew build
来构建JAR包,然后运行JAR包,如下命令:
java -jar build/libs/gs-validating-form-input-0.1.0.jar
如果你使用Maven,你可以通过./mvnw spring-boot:run
来运行应用程序。或者说,你可以使用./mvnw clean package
来构建JAR包,通过如下命令执行JAR包。
java -jar target/gs-validating-form-input-0.1.0.jar
此处步骤描述了创建一个可执行JAR包。你也可以构造一个经典的WAR文件。
该应用程序应在几秒钟内启动和运行。
如果你访问http://localhost:8080/
,你应该看到类似以下图片的东西。
下面一对图片显示了如果你在姓名中输入N,在年龄中输入15,然后点击提交会发生什么。
前面的图片显示,由于这些值违反了PersonForm
类中的约束条件,你被退回到主页面。注意,如果你在输入框中什么都没有的情况下点击提交,你会得到一个不同的错误,如下图所示。
如果你输入有效的姓名和年龄,你就会出现在结果页面,如下图所示。