Java:SpringBoot整合hibernate-validator实现入参数据校验

时间:2022-11-17 12:09:39

本文仅实现了api接口基本的参数校验,还有更多的校验场景,可以参考文章底部的参考链接

使用starter 创建 SpringBoot项目,并添加依赖

依赖

<properties>
    <java.version>1.8</java.version>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <spring-boot.version>2.3.7.RELEASE</spring-boot.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>

    <!-- hibernate-validator -->
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-validator</artifactId>
        <version>6.0.1.Final</version>
    </dependency>
    
</dependencies>

文件入口

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

定义校验规则

package com.example.demo.dto;

import lombok.Data;
import org.hibernate.validator.constraints.Length;

import javax.validation.constraints.NotNull;


@Data
public class UserDTO {

    private Long userId;

    @NotNull
    @Length(min = 2, max = 10)
    private String userName;

    @NotNull
    @Length(min = 6, max = 20)
    private String account;

    @NotNull
    @Length(min = 6, max = 20)
    private String password;
}

统一的数据返回

package com.example.demo.common;


/**
 * 统一的数据返回
 */
public class JsonResult {
    private Integer code;
    private String msg;
    private Object data;

    public JsonResult(Integer code, String msg, Object data) {
        this.code = code;
        this.msg = msg;
        this.data = data;
    }

    public static JsonResult success(Object data){
        return new JsonResult(0, "success", data);
    }

    public static JsonResult error(String errorMessage) {
        return new JsonResult(-1, errorMessage, null);
    }

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }
}


全局异常处理

package com.example.demo.common;

import org.springframework.http.HttpStatus;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.validation.ConstraintViolationException;

/**
 * 全局异常处理
 */
@RestControllerAdvice
public class CommonExceptionHandler {

    /**
     * 参数校验失败
     *
     * @param ex
     * @return
     */
    @ExceptionHandler({MethodArgumentNotValidException.class})
    @ResponseStatus(HttpStatus.OK)
    @ResponseBody
    public JsonResult handleMethodArgumentNotValidException(MethodArgumentNotValidException ex) {
        BindingResult bindingResult = ex.getBindingResult();

        StringBuilder sb = new StringBuilder("校验失败:");

        for (FieldError fieldError : bindingResult.getFieldErrors()) {
            sb.append(fieldError.getField())
                    .append(":")
                    .append(fieldError.getDefaultMessage())
                    .append(", ");
        }
        
        String msg = sb.toString();
        return JsonResult.error("参数校验失败" + msg);
    }

    /**
     * 参数校验失败
     *
     * @param ex
     * @return
     */
    @ExceptionHandler({ConstraintViolationException.class})
    @ResponseStatus(HttpStatus.OK)
    @ResponseBody
    public JsonResult handleConstraintViolationException(ConstraintViolationException ex) {
        return JsonResult.error("参数校验失败" + ex.getMessage());
    }
}

控制器

package com.example.demo.controller;


import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import com.example.demo.common.JsonResult;
import com.example.demo.dto.UserDTO;

@RestController
public class UserController {
    @PostMapping("/save")
    public JsonResult saveUser(@RequestBody @Validated UserDTO userDTO) {
        // 校验通过,才会执行业务逻辑处理
        System.out.println(userDTO);

        return JsonResult.success(userDTO);
    }
}

HTTP Client配置

http-client.env.json

{
  "dev": {
    "baseUrl": "http://localhost:8080"
  }
}

接口测试文件

user.http


POST {{baseUrl}}/save
content-type: application/json

{
  "name": "Tom"
}

###


POST {{baseUrl}}/save
content-type: application/json

{
  "userName": "Tom"
}

###

POST {{baseUrl}}/save
content-type: application/json

{
  "userName": "Tom",
  "password": "11"
}

###

POST {{baseUrl}}/save
content-type: application/json

{
  "userName": "Tom",
  "password": "1133344"
}

###

POST {{baseUrl}}/save
content-type: application/json

{
  "userName": "Tom",
  "password": "1133344",
  "account": "account"
}

###

参考 SpringBoot 实现各种参数校验