当前位置:   article > 正文

爆破专栏丨SpringBoot2.x系列教程之WebData Binder对请求参数进行合法性校验和数据绑定_webdatabinderfactory

webdatabinderfactory

前言

在上一章节的内容中,壹哥 给大家讲解了@InitBinder的原理及使用教程,我们利用InitBinder实现了对日期类型参数的格式转换。

本章节我会利用另一种技术WebDataBinder,继续处理SpringBoot中的参数传递及数据绑定,并在本文中带大家实现自定义的属性编辑器,以及自定义参数校验器。

一. WebDataBinder简介

在进行代码实现之前,我们先来看看WebDataBinder是个什么东东!

1. WebDataBinder的由来

Servlet中,有一个方法:request.getParameter("paramName") ,它会根据key返回一个String类型的数据,从而获取到前端传递过来的请求参数。

但是如果我们这样一个一个地去取出Web请求中的所有参数,就会很麻烦。我们知道Java中有对象的概念,那有没有办法将request中的请求参数都自动封装到一个Java对象中呢?为了解决这个问题,SpringMVC中就引入了WebDataBinder的概念。

2. WebDataBinder类关系

我们再来看看WebDataBinder的类关系图:

图片

3. WebDataBinder的作用

WebDataBinder的作用是从Web 请求中,把请求里的**参数**都绑定到对应的**JavaBean**上!

在Controller方法中的参数类型可以是基本类型,也可以是封装后的普通Java类型。若这个普通的Java类型没有声明任何注解,则意味着它的每一个属性都需要到Request中去查找对应的请求参数,而WebDataBinder则可以帮助我们实现从Request中取出请求参数并绑定到JavaBean中。

4. WebDataBinder工作机制

WebDataBinder用于绑定请求参数到指定的属性编辑器里。由于前台传到Controller里的值是String类型,当往Java Bean里设置这个值的时候,如果设置的这个属性是对象,SpringMVC就会去找到对应的编辑器editor进行转换,然后再设置进去!

SpringMVC自己提供了大量的editor编辑器实现类,诸如CustomDateEditor,CustomBooleanEditor,CustomNumberEd itor等,基本上够我们使用了。

图片

但在平时使用SpringMVC时,可能会碰到Java Bean中有Date类型的参数,表单中传来代表日期的字符串转化为日期类型,SpringMVC在默认时,是不支持这种类型转换的。此时我们就需要手动设置时间格式并在WebDateBinder上注册这个编辑器!

5. 示例代码

利用CustomDateEditor实现日期格式转换的示例代码,如下所示:

  1. @InitBinder  
  2. public void bindingPreparation(WebDataBinder binder) {  
  3.   DateFormat dateFormat1 = new SimpleDateFormat("dd-MM-yyyy");  
  4.   CustomDateEditor orderDateEditor = new CustomDateEditor(dateFormat1, true);  
  5.   DateFormat dateFormat2 = new SimpleDateFormat("MMM d, YYYY");  
  6.   CustomDateEditor shipDateEditor = new CustomDateEditor(dateFormat2, true);  
  7.   binder.registerCustomEditor(Date.class, "orderDate", orderDateEditor);  
  8.   binder.registerCustomEditor(Date.class, "shipDate", shipDateEditor);  
  9. }

二. WebDataBinder实现过程

了解了上面的这些理论内容,接下来我就利用WebDataBinder实现参数的转换。

1. 创建Web项目

首先我们要创建一个Web项目,或者也可以直接在上一个项目的基础之上编写本案例代码,具体请参考之前的章节。

2. 创建User类

我们在项目中创建一个domain包,在该包下创建一个User实体类,里面有个日期类型的birthday字段。

  1. package com.yyg.boot.domain;
  2. import lombok.Data;
  3. import java.util.Date;
  4. /**
  5.  * @Description Description
  6.  * @Author 一一哥Sun
  7.  * @Date Created in 2020/3/23
  8.  */
  9. @Data
  10. public class User {
  11.     private String name;
  12.     private String password;
  13.     private String email;
  14.     private Date birthday;
  15. }

3. Validator接口介绍

在使用Validator之前,我先介绍一下Validator接口。

  • Validator 是一个有着两个方法的接口;

  • boolean supports(Class<?> clazz) : 检验参数是否验证成功的实例类;

  • void validate(Object target, Errors errors) : 如果 suppo rts()方法返回真, targetobject 合法. Errors.reject Value() 方法用一个字段名注册错误信息。

4. 创建UserValidator验证类

我们创建一个validator包,在该包下面创建一个UserValidator验证类,在这里负责对前端传递过来的User类型参数进行必要的校验,判断用户名和密码是否符合规范。

  1. package com.yyg.boot.domain;
  2. import lombok.Data;
  3. import java.util.Date;
  4. /**
  5.  * @Description Description
  6.  * @Author 一一哥Sun
  7.  * @Date Created in 2020/3/23
  8.  */
  9. @Data
  10. public class User {
  11.     private String name;
  12.     private String password;
  13.     private String email;
  14.     private Date birthday;
  15. }package com.yyg.boot.validator;
  16. import com.yyg.boot.domain.User;
  17. import org.springframework.stereotype.Component;
  18. import org.springframework.validation.Errors;
  19. import org.springframework.validation.ValidationUtils;
  20. import org.springframework.validation.Validator;
  21. /**
  22.  * @Description Description
  23.  * @Author 一一哥Sun
  24.  * @Date Created in 2020/3/23
  25.  */
  26. @Component
  27. public class UserValidator implements Validator {
  28.     /**
  29.      * 检验参数是否验证成功的实例类
  30.      */
  31.     @Override
  32.     public boolean supports(Class<?> clazz) {
  33.         //isAssignableFrom()方法是判断是否为某个类的父类,instanceof关键字是判断是否某个类的子类。
  34.         return User.class.isAssignableFrom(clazz);
  35.     }
  36.     /**
  37.      * 如果 supports() 方法返回真, target object 合法. Errors.rejectValue() 方法会用一个字段名注册错误信息;
  38.      */
  39.     @Override
  40.     public void validate(Object target, Errors errors) {
  41.         User user = (User)target;
  42.         //配置字段验证信息
  43.         ValidationUtils.rejectIfEmptyOrWhitespace(errors, "name""","Username is empty");
  44.         ValidationUtils.rejectIfEmptyOrWhitespace(errors, "password""""Password is empty");
  45.         
  46.         //用户名长度不能小于5个字符
  47.         if (user.getName().length()<5) {
  48.             errors.rejectValue("name","""Username length is less than 5");
  49.         }
  50.     }
  51. }package com.yyg.boot.validator;
  52. import com.yyg.boot.domain.User;
  53. import org.springframework.stereotype.Component;
  54. import org.springframework.validation.Errors;
  55. import org.springframework.validation.ValidationUtils;
  56. import org.springframework.validation.Validator;
  57. /**
  58.  * @Description Description
  59.  * @Author 一一哥Sun
  60.  * @Date Created in 2020/3/23
  61.  */
  62. @Component
  63. public class UserValidator implements Validator {
  64.     /**
  65.      * 检验参数是否验证成功的实例类
  66.      */
  67.     @Override
  68.     public boolean supports(Class<?> clazz) {
  69.         //isAssignableFrom()方法是判断是否为某个类的父类,instanceof关键字是判断是否某个类的子类。
  70.         return User.class.isAssignableFrom(clazz);
  71.     }
  72.     /**
  73.      * 如果 supports() 方法返回真, target object 合法. Errors.rejectValue() 方法会用一个字段名注册错误信息;
  74.      */
  75.     @Override
  76.     public void validate(Object target, Errors errors) {
  77.         User user = (User)target;
  78.         //配置字段验证信息
  79.         ValidationUtils.rejectIfEmptyOrWhitespace(errors, "name""","Username is empty");
  80.         ValidationUtils.rejectIfEmptyOrWhitespace(errors, "password""""Password is empty");
  81.         
  82.         //用户名长度不能小于5个字符
  83.         if (user.getName().length()<5) {
  84.             errors.rejectValue("name","""Username length is less than 5");
  85.         }
  86.     }
  87. }

5. 创建EmailValidator验证类

我们在validator包中,再创建一个EmailValidator验证类,判断用户的邮箱信息是否符合要求。

  1. package com.yyg.boot.validator;
  2. import com.yyg.boot.domain.User;
  3. import org.springframework.stereotype.Component;
  4. import org.springframework.validation.Errors;
  5. import org.springframework.validation.ValidationUtils;
  6. import org.springframework.validation.Validator;
  7. /**
  8.  * @Description Description
  9.  * @Author 一一哥Sun
  10.  * @Date Created in 2020/3/23
  11.  */
  12. @Component
  13. public class EmailValidator implements Validator {
  14.     @Override
  15.     public boolean supports(Class<?> clazz) {
  16.         return User.class.isAssignableFrom(clazz);
  17.     }
  18.     @Override
  19.     public void validate(Object target, Errors errors) {
  20.         User user = (User)target;
  21.         ValidationUtils.rejectIfEmptyOrWhitespace(errors, "email""","Email is empty");
  22.         if (!user.getEmail().contains("@")) {
  23.             errors.rejectValue("email","""Email is not valid.");
  24.         }
  25.     }
  26. }

6. 创建ValidatorController测试接口

接下来我们创建一个web包,在该包下面创建一个ValidatorController类,并且编写一个接口,接受前端传递过来的User参数。而且该类中还要实现InitBinder的参数格式化校验。

  1. package com.yyg.boot.web;
  2. import com.yyg.boot.domain.User;
  3. import com.yyg.boot.validator.EmailValidator;
  4. import com.yyg.boot.validator.UserValidator;
  5. import org.springframework.beans.factory.annotation.Autowired;
  6. import org.springframework.beans.propertyeditors.CustomDateEditor;
  7. import org.springframework.stereotype.Controller;
  8. import org.springframework.validation.BindingResult;
  9. import org.springframework.web.bind.WebDataBinder;
  10. import org.springframework.web.bind.annotation.*;
  11. import javax.validation.Valid;
  12. import java.text.SimpleDateFormat;
  13. import java.util.Date;
  14. /**
  15.  * @Description Description
  16.  * @Author 一一哥Sun
  17.  * @Date Created in 2020/3/23
  18.  */
  19. @Controller
  20. public class ValidatorController {
  21.     @Autowired
  22.     private UserValidator userValidator;
  23.     @Autowired
  24.     private EmailValidator emailValidator;
  25.     /**
  26.      * 接收参数,自定义编辑器
  27.      */
  28.     @InitBinder
  29.     public void dataBinding(WebDataBinder binder) {
  30.         //将UserValidator和EmailValidator添加到WebDataBinder中
  31.         binder.addValidators(userValidator, emailValidator);
  32.         
  33.         SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
  34.         //setLenient用于设置Calendar是否宽松解析字符串,如果为false,则严格解析;默认为true,宽松解析
  35.         dateFormat.setLenient(false);
  36.         
  37.         binder.registerCustomEditor(Date.class"birthday", new CustomDateEditor(dateFormat, true));
  38.     }
  39.     @ResponseBody
  40.     @RequestMapping(value = "/user"method = RequestMethod.POST)
  41.     public String createUser(@RequestBody @Valid User user, BindingResult result) {
  42.         if (result.hasErrors()) {
  43.             return result.getFieldError().getDefaultMessage();
  44.         }
  45.         
  46.         System.out.println("Name:" + user.getName());
  47.         System.out.println("Email:" + user.getEmail());
  48.         System.out.println("Date of Birth:" + user.getBirthday());
  49.         
  50.         return "success";
  51.     }
  52. }

7. 项目结构

完整的项目结构如下图所示,各位可以参考创建。

图片

8. 启动程序进行测试

最后我们启动项目,在Postman中进行测试,输入地址:

http://localhost:8080/user,

8.1 验证用户名长度

这里我们要使用post请求,传递一个json格式的参数:

  1. {
  2.  "name":"一一哥",
  3.  "password":"123",
  4.  "email":"sss@33",
  5.   "birthday""2020-03-20"
  6. }

执行完毕后可以看到返回的验证数据:

图片

8.2 验证邮箱格式

当传入的参数中,email不合格时,有如下返回值。

图片

至此,我们就实现了数据绑定和自定义的属性编辑器,以及自定义的参数校验器效果了!

 

需要更多教程,微信扫码即可

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/66277
推荐阅读
相关标签