Spring中使用JSR303请求约束判空
1. 适用场景
有时候我们在表单里提交一系列参数, 到后台封装成一个对象, 要对对象的属性做各种字段值的约束; 这时候, 当然可以if-else一个一个的判断, 有更简洁的做法, 就是使用 JSR303+spring的validation:
2. 使用方法步骤(分3步)
如我们要收集前端表单的字段数据到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"
}
}
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 hi@niewj.com