Spring中使用JSR303请求约束判空的实现

 更新时间:2020年12月18日 08:34:38   作者:niewj  
这篇文章主要介绍了Spring中使用JSR303请求约束判空的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

 1. 适用场景

有时候我们在表单里提交一系列参数, 到后台封装成一个对象, 要对对象的属性做各种字段值的约束; 这时候, 当然可以if-else一个一个的判断, 有更简洁的做法, 就是使用 JSR303+spring的validation:

2. 使用方法步骤(分3步)

  • 实体类加字段约束注解
  • Controller类中@Valid标注启用(@Validated也兼容@Valid)
  • BindingResult获取报错信息

2.1 实体类加字段约束注解

如我们要收集前端表单的字段数据到Person实体中:

对需要约束的字段进行注解标注;

示例:

2.1.1 Person.java

package com.niewj.demo.model;
import lombok.Data;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.URL;
import javax.validation.constraints.*;
import java.util.List;

@Data
public class Person {
  @Length(min = 4, max = 10)
  @NotNull(message = "name不能为空")
  private String name;

  @Min(0)
  @Max(40)
  @NotNull(message = "age不能为空")
  private Integer age;

  @NotBlank
  @NotBlank
  @URL(message = "logo必须是URL格式")
  private String logo;

  @NotEmpty(message = "hobbies不能为空")
  private List<String> hobbies;

  @Email
  @NotNull(message = "email不能为空!")
  private String mail;
}

@NotNull 约束字段不可为空;

@NotEmpty 约束集合/map等不能为空不能为0元素

@Email 约束是 email格式

@URL 约束必须是url的格式

message属性可以修改默认错误说明

2.2 Controller类中@Valid标注启用(@Validated兼容@Valid)

2.2.1 HelloController.java

package com.niewj.demo.controller;

import com.google.gson.Gson;
import com.niewj.demo.common.Result;
import com.niewj.demo.model.Person;
import com.niewj.demo.service.TestService1;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.HashMap;
import java.util.Map;

/**
 * test
 *
 * @author niewj
 * @since 2020/11/16 15:22
 */
@Controller
public class HelloController {

  /**
   * @param person
   * @param bindingResult
   * @return
   */
  @PostMapping("/test")
  @ResponseBody
  public Result doSth(@Valid @RequestBody Person person, BindingResult bindingResult) {
    Map<String, String> map = new HashMap<>();
    if (bindingResult.hasErrors()) {
      bindingResult.getFieldErrors().stream().forEach(fe-> map.put(fe.getField(), fe.getDefaultMessage()));
      System.out.println(bindingResult.getFieldError().getDefaultMessage());
      return Result.withErrorParamData(map);
    }

    return Result.withSuccessData(person);
  }
}

@RequestBody可以将body中的请求流信息(Request.getInputStream)通过HttpMessageConverter自动转换为目标java类型:

  • 如果前端 Content-Type为application/json, 就使用 JSON消息转换器 帮你转为JSON对象;
  • 如果前端 Content-Type为application/xml, 就使用 XML消息转换器 帮你转为xml;
  • 如果前端 Content-Type为text/plain, 就是用 String消息转换器 帮你转成 String; (只有类型为String时才可以转换)

2.2.2 Result.java:

package com.niewj.demo.common;

import lombok.Data;

import java.io.Serializable;
import java.util.Map;

/**
 * 返回结果模板封装
 *
 * @author niewj
 * @since 2020/12/17 18:05
 */
@Data
public class Result<T> implements Serializable {
  private int code;
  private String msg;
  private T data;

  public Result(int code, String msg, T data) {
    this(code, msg);
    this.data = data;
  }

  public Result(int code, String msg) {
    this.msg = msg;
    this.code = code;
  }

  public static <T> Result<T> withData(ResponseEnum responseCode, T data) {
    Result<T> re = new Result(responseCode.getCode(), responseCode.getMsg());
    re.data = data;
    return re;
  }

  public static Result<String> withSuccessNoData() {
    Result re = new Result(ResponseEnum.SUCCESS.getCode(), ResponseEnum.SUCCESS.getMsg());
    re.data = "";
    return re;
  }

  public static <T> Result<T> withSuccessData(T data) {
    Result re = new Result(ResponseEnum.SUCCESS.getCode(), ResponseEnum.SUCCESS.getMsg());
    re.data = data;
    return re;
  }

  public static Result<Map<String, String>> withErrorParamData(Map<String, String> data) {
    Result re = new Result(ResponseEnum.BAD_REQUEST.getCode(), ResponseEnum.BAD_REQUEST.getMsg());
    re.data = data;
    return re;
  }
}

2.2.3 ResponseEnum.java

package com.niewj.demo.common;

/**
 * 通用响应码
 */
public enum ResponseEnum {

  SUCCESS(200, "成功"),
  BAD_REQUEST(400, "请求参数不合规");

  /**
   * 错误码
   */
  private Integer code;
  /**
   * 错误信息
   */
  private String msg;

  ResponseEnum(Integer code, String msg) {
    this.code = code;
    this.msg = msg;
  }

  public String getMsg() {
    return msg;
  }

  public Integer getCode() {
    return code;
  }
}

2.3 BindingResult获取报错信息

  • BindingResult用来收集约束字段的错误信息, 可通过 bindingResult.hasErrors()的 true来过滤错误信息;
  • bindingResult.getFieldErrors() 会返回 List<FieldError>;
  • FieldError 得到字段名: getField(); 得到错误信息: getDefaultMessage()

3. 调用测试:

http://localhost:8888/test

3.1 请求用例1: 字段为空

header: Content-Type: application/json

{
  "name": "1"
}

响应:

{
  "code": 400,
  "msg": "请求参数不合规",
  "data": {
    "mail": "email不能为空!",
    "hobbies": "hobbies不能为空",
    "name": "长度需要在4和10之间",
    "logo": "不能为空",
    "age": "age不能为空"
  }
}

3.2 请求用例2: list无元素/email/url格式不对

header: Content-Type: application/json

{
  "name": "1234",
  "hobbies": [],
  "mail": "niewj",
  "logo": "niewj.com"
}

响应:

{
  "code": 400,
  "msg": "请求参数不合规",
  "data": {
    "mail": "不是一个合法的电子邮件地址",
    "hobbies": "hobbies不能为空",
    "logo": "logo必须是URL格式",
    "age": "age不能为空"
  }
}

3.3 请求用例3: 完整字段信息

header: Content-Type: application/json

{
  "name": "1234",
  "hobbies": ["running"],
  "mail": "hi@niewj.com",
  "logo": "http://niewj.com",
  "age": 40
}

响应:

{
  "code": 200,
  "msg": "成功",
  "data": {
    "name": "1234",
    "age": 40,
    "logo": "http://niewj.com",
    "hobbies": [
      "running"
    ],
    "mail": "hi@niewj.com"
  }
}

到此这篇关于Spring中使用JSR303请求约束判空的实现的文章就介绍到这了,更多相关Spring JSR303请求约束判空内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • java实现Object转String的4种方法小结

    java实现Object转String的4种方法小结

    这篇文章主要介绍了java实现Object转String的4种方法小结,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-09-09
  • 解决程序包org.springframework.test.context不存在

    解决程序包org.springframework.test.context不存在

    这篇文章主要介绍了解决程序包org.springframework.test.context不存在的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-09-09
  • java 计算中位数的实现方法

    java 计算中位数的实现方法

    这篇文章主要介绍了java 计算中位数的实现方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-08-08
  • Mybatis控制台打印SQL语句的两种方式实现

    Mybatis控制台打印SQL语句的两种方式实现

    这篇文章主要介绍了Mybatis控制台打印SQL语句的两种方式实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-03-03
  • 详解SpringBoot结合swagger2快速生成简单的接口文档

    详解SpringBoot结合swagger2快速生成简单的接口文档

    这篇文章主要介绍了详解SpringBoot结合swagger2快速生成简单的接口文档,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-05-05
  • java利用正则表达式处理特殊字符的方法实例

    java利用正则表达式处理特殊字符的方法实例

    这篇文章主要给大家介绍了关于java利用正则表达式处理特殊字符的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-12-12
  • Java14对于NullPointerException的新处理方式示例解析

    Java14对于NullPointerException的新处理方式示例解析

    这篇文章主要为大家介绍了Java14对于NullPointerException的新处理方式示例解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-09-09
  • Kafka中使用Avro序列化和反序列化详解

    Kafka中使用Avro序列化和反序列化详解

    这篇文章主要介绍了Kafka中使用Avro序列化和反序列化详解,由于Kafka中的数据都是字节数组,在将消息发送到Kafka之前需要先将数据序列化为字节数组, 序列化器的作用就是用于序列化要发送的消息的,需要的朋友可以参考下
    2023-12-12
  • Java的包装类特性总结

    Java的包装类特性总结

    这篇文章主要介绍Java的包装类的一些特性,包装类的作用,哪些类属于包装类等,文中有详细的代码示例,对我们的学习或工作有一定的帮助,需要的朋友可以参考下
    2023-05-05
  • SpringBoot打印POST请求原始入参body体方式

    SpringBoot打印POST请求原始入参body体方式

    这篇文章主要介绍了SpringBoot打印POST请求原始入参body体方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-09-09

最新评论