表单验证,是最为常见的,今天演示的是利用hibernate-validtor进行校验,有的时候,虽然前端方面通过jQuery或者require.js校验框架进行校验,可以减轻服务器的压力和改善用户体验,但是比如第三方请求接口方面也需要校验,在Controller里面套着一大堆if-elseif-else等等,两层嵌套还好,三层或者三层以上就不好了,日子久了继续嵌套,就会导致后面变得难以维护。我有一个朋友在一家国企,据他所说,他遇到的最烂代码是if-else if里面套者十几层,而且一个类的代码居然上千行,正常合理情况,当达到上千行代码就要考虑抽象继承或者多态,再设计模式了。设计模式,我不懂,只是了解,这里就不提了,后续博文会讲到设计模式的。

这里说Validator的意义在于,通过注解减少if-else等重复判断代码,从而使Java代码行数减少,因为加载类中的代码是需要时间的。代码行数减少,意味着加载时间减少,从而提高代码效率。

演示示例如下:

一、导入maven依赖

<?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"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <groupId>org.springframework</groupId>
<artifactId>gs-validating-form-input</artifactId>
<version>0.1.0</version> <parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.8.RELEASE</version>
</parent> <properties>
<java.version>1.8</java.version>
</properties> <build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build> <dependencies> <dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.4.1.Final</version>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency> <dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-el</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies> </project>

二、编写实体

package hello;

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 + ")";
}
}

三、编写Controller

package hello;

import java.util.List;

import javax.validation.Valid;

import org.springframework.format.FormatterRegistry;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.validation.MessageCodesResolver;
import org.springframework.validation.Validator;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.config.annotation.AsyncSupportConfigurer;
import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.PathMatchConfigurer;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.ViewResolverRegistry;
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 "/results";
} @Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> arg0) {
// TODO Auto-generated method stub } @Override
public void addCorsMappings(CorsRegistry arg0) {
// TODO Auto-generated method stub } @Override
public void addFormatters(FormatterRegistry arg0) {
// TODO Auto-generated method stub } @Override
public void addInterceptors(InterceptorRegistry arg0) {
// TODO Auto-generated method stub } @Override
public void addResourceHandlers(ResourceHandlerRegistry arg0) {
// TODO Auto-generated method stub } @Override
public void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> arg0) {
// TODO Auto-generated method stub } @Override
public void configureAsyncSupport(AsyncSupportConfigurer arg0) {
// TODO Auto-generated method stub } @Override
public void configureContentNegotiation(ContentNegotiationConfigurer arg0) {
// TODO Auto-generated method stub } @Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer arg0) {
// TODO Auto-generated method stub } @Override
public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> arg0) {
// TODO Auto-generated method stub } @Override
public void configureMessageConverters(List<HttpMessageConverter<?>> arg0) {
// TODO Auto-generated method stub } @Override
public void configurePathMatch(PathMatchConfigurer arg0) {
// TODO Auto-generated method stub } @Override
public void configureViewResolvers(ViewResolverRegistry arg0) {
// TODO Auto-generated method stub } @Override
public void extendHandlerExceptionResolvers(List<HandlerExceptionResolver> arg0) {
// TODO Auto-generated method stub } @Override
public void extendMessageConverters(List<HttpMessageConverter<?>> arg0) {
// TODO Auto-generated method stub } @Override
public MessageCodesResolver getMessageCodesResolver() {
// TODO Auto-generated method stub
return null;
} @Override
public Validator getValidator() {
// TODO Auto-generated method stub
return null;
}
}

四、编写html代码

form.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>

result.html

<html xmlns:th="http://www.thymeleaf.org">
<body>
Congratulations! You are old enough to sign up for this site.
</body>
</html>

五、编写配置文件

application.properties

server.port=8080
spring.thymeleaf.cache=false
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.check-template-location=true
spring.thymeleaf.suffix=.html
spring.thymeleaf.encoding=UTF-8
spring.thymeleaf.content-type=text/html
spring.thymeleaf.mode=HTML5

六、编写启动类

package hello;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication
public class Application { public static void main(String[] args) throws Exception {
SpringApplication.run(Application.class, args);
} }

最后运行main方法,在浏览器输入localhost:8080/

会出现对应的表单页面,输入不合法会出现提示,表示验证成功

SpringBoot实战(九)之Validator的更多相关文章

  1. SpringBoot实战 之 异常处理篇

    在互联网时代,我们所开发的应用大多是直面用户的,程序中的任何一点小疏忽都可能导致用户的流失,而程序出现异常往往又是不可避免的,那该如何减少程序异常对用户体验的影响呢?其实方法很简单,对异常进行捕获,然 ...

  2. apollo客户端springboot实战(四)

    1. apollo客户端springboot实战(四) 1.1. 前言   经过前几张入门学习,基本已经完成了apollo环境的搭建和简单客户端例子,但我们现在流行的通常是springboot的客户端 ...

  3. 千锋很火的SpringBoot实战开发教程视频

    springboot是什么? Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框架使用了特定的方式来进行配置,从而使开发人员 ...

  4. SpringBoot实战(四)获取接口请求中的参数(@PathVariable,@RequestParam,@RequestBody)

    上一篇SpringBoot实战(二)Restful风格API接口中写了一个控制器,获取了前端请求的参数,现在我们就参数的获取与校验做一个介绍: 一:获取参数 SpringBoot提供的获取参数注解包括 ...

  5. SpringBoot实战(二)Restful风格API接口

    在上一篇SpringBoot实战(一)HelloWorld的基础上,编写一个Restful风格的API接口: 1.根据MVC原则,创建一个简单的目录结构,包括controller和entity,分别创 ...

  6. SpringBoot实战之异常处理篇

    在互联网时代,我们所开发的应用大多是直面用户的,程序中的任何一点小疏忽都可能导致用户的流失,而程序出现异常往往又是不可避免的,那该如何减少程序异常对用户体验的影响呢?其实方法很简单,对异常进行捕获,然 ...

  7. springboot(十九)使用actuator监控应用【转】【补】

    springboot(十九)使用actuator监控应用 微服务的特点决定了功能模块的部署是分布式的,大部分功能模块都是运行在不同的机器上,彼此通过服务调用进行交互,前后台的业务流会经过很多个微服务的 ...

  8. Docker深入浅出系列 | 单机Nginx+Springboot实战

    目录 Nginx+Springboot实战 前期准备 实战目标 实战步骤 创建Docker网络 搭建Mysql容器 搭建额度服务集群 搭建Nginx服务 验证额度服务 附录 Nginx+Springb ...

  9. SpringSecurity权限管理系统实战—九、数据权限的配置

    目录 SpringSecurity权限管理系统实战-一.项目简介和开发环境准备 SpringSecurity权限管理系统实战-二.日志.接口文档等实现 SpringSecurity权限管理系统实战-三 ...

随机推荐

  1. 【SSH网上商城项目实战09】添加和更新商品类别功能的实现

    转自:https://blog.csdn.net/eson_15/article/details/51347734 上一节我们做完了查询和删除商品的功能,这一节我们做一下添加和更新商品的功能. 1.  ...

  2. MyBatis学习(二)---数据表之间关联

    想要了解MyBatis基础的朋友可以通过传送门: MyBatis学习(一)---配置文件,Mapper接口和动态SQL http://www.cnblogs.com/ghq120/p/8322302. ...

  3. python学习之老男孩python全栈第九期_day019作业

    # 计算时间差 import time start_time = time.mktime(time.strptime('2017-09-11 08:30:00','%Y-%m-%d %H:%M:%S' ...

  4. js获取昨天/上周/上个月开始和结束的时间戳,可以设置时分秒 js obtain start and end timestamp of yesterday/last week/last month, with set of hour/minute/second

    //obtain timestamp of last week var now=new Date() var nowDayOfWeek = now.getDay(); //今天本周的第几天 var n ...

  5. wget 抓取整站

    wget -r -p -np -k http://doc.code365.net/Manual/FreeBSD_Arch_HandBook/ -r 递归 -p, --page-requisites(页 ...

  6. css中元素的auto属性值是什么意思,比如margin:0 auto表示什么?

    auto 你可以理解为一种 自动/自适应 的概念 比如 现在项目需要一个宽度为960px的整体布局居中 根据用户浏览器大小不同你将需要使用margin:0 auto;来实现. 无论用户浏览器宽度为多少 ...

  7. 使用js在HTML中自定义字符串格式化方法

    Python中支持字符串格式化,其基本形式如下: str = "I'm {name},{age} years old" print(str.format(name="te ...

  8. MongoDB 更改数据库位置

    MongoDB在Windows中默认的数据库目录是 C:\data.如果在没有该目录的情况下,执行命令mongod,则会报如下错误: 如果我们不想把mongoDB的数据库放在C盘,可以使用如下两种方法 ...

  9. Android LinkedList和ArrayList的区别

    LinkedeList和ArrayList都实现了List接口,但是它们的工作原理却不一样.它们之间最主要的区别在于ArrayList是可改变大小的数组,而LinkedList是双向链接串列(doub ...

  10. SVG坐标系统和transformation彻底理解

    翻译自https://sarasoueidan.com/blog/svg-coordinate-systems/ SVG元素不像传统的HTML elements一样受制于css box model.这 ...