SpringBoot - 优雅的实现【参数校验】高级进阶

简介: SpringBoot - 优雅的实现【参数校验】高级进阶


Pre

SpringBoot - 优雅的实现【参数校验】高级进阶

SpringBoot - 优雅的实现【自定义参数校验】高级进阶

SpringBoot - 优雅的实现【参数分组校验】高级进阶

SpringBoot - 使用Assert校验让业务代码更简洁


概述

日常开发中,对入参进行参数校验是必不可少的一个环节。 而使用最多的就是Validator框架 。

Validator校验框架遵循了JSR-303 【Java Specification Requests】验证规范 。

这里我们探讨下,在boot项目中如何优雅的集成参数校验框架



参数校验三部曲

Step1 搞依赖

boot 2.3 以后版本的pom信息如下

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>
    </dependencies>
  • spring boot-2.3之前的版本只需要引入 spring-boot-starter-web 即可 ,已经包含了

  • spring boot-2.3及以后的版本,校验包是一个单独的starter,需要同时引入spring-boot-starter-validation


Step2 搞参数校验的实体类

package com.artisan.vo;
import lombok.Data;
import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
/**
 * @author 小工匠
 * @version 1.0 
 * @mark: show me the code , change the world
 */
@Data
public class Artisan {
    private String id;
    @NotBlank(message = "名字为必填项")
    private String name;
    @Length(min = 8, max = 12, message = "password长度必须位于8到12之间")
    private String password;
    @Email(message = "请填写正确的邮箱地址")
    private String email;
    private String sex;
    @NotEmpty(message = "Code不能为空")
    private String code;
}

常用的校验注解

注解 功能
@AssertFalse 可以为null,如果不为null的话必须为false
@AssertTrue 可以为null,如果不为null的话必须为true
@DecimalMax 设置不能超过最大值
@DecimalMin 设置不能超过最小值
@Digits 设置必须是数字且数字整数的位数和小数的位数必须在指定范围内
@Future 日期必须在当前日期的未来
@Past 日期必须在当前日期的过去
@Max 最大不得超过此最大值
@Min 最大不得小于此最小值
@NotNull 不能为null,可以是空
@Null 必须为null
@Pattern 必须满足指定的正则表达式
@Size 集合、数组、map等的size()值必须在指定范围内
@Email 必须是email格式
@Length 长度必须在指定范围内
@NotBlank 字符串不能为null,字符串trim()后也不能等于“”
@NotEmpty 不能为null,集合、数组、map等size()不能为0;字符串trim()后可以等于“”
@Range 值必须在指定范围内
@URL 必须是一个URL



Step3 开始验证

注意看注释

package com.artisan.controller;
import com.artisan.vo.Artisan;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.validation.constraints.Email;
/**
 * @author 小工匠
 * @version 1.0
 * @mark: show me the code , change the world
 */
@RestController
@Slf4j
@Validated
@RequestMapping("/valid")
public class ArtisanController {
    /**
     * 使用@RequestBody注解,用于接受前端发送的json数据
     *
     * @param artisan
     * @return
     */
    @PostMapping("/testJson")
    public String testJson(@Validated @RequestBody Artisan artisan) {
        log.info("InComing Param  {}", artisan);
        return "testJson valid success";
    }
    /**
     * 模拟表单提交
     *
     * @param artisan
     * @return
     */
    @PostMapping(value = "/testForm")
    public String testForm(@Validated Artisan artisan) {
        log.info("InComing Param is {}", artisan);
        return "testForm valid success";
    }
    /**
     * 模拟单参数提交
     *
     * @param email
     * @return
     */
    @PostMapping(value = "/testParma")
    public String testParma(@Email String email) {
        log.info("InComing Param is {}", email);
        return "testParma  valid success";
    }
}
  • testJson使用 @RequestBody注解,用于接受前端发送的json数据
  • testForm模拟表单提交
  • testParma模拟单参数提交
    当使用单参数校验时需要在Controller上加上@Validated注解,否则不生效


【测试第一个接收JSON的接口 】

可以看到抛出的异常为: org.springframework.web.bind.MethodArgumentNotValidException


【测试第二个接收表单的接口 】

可以看到抛出的异常为: org.springframework.validation.BindException


【测试第三个接收单参数的接口 】

可以看到抛出的异常为:javax.validation.ConstraintViolationException


存在的问题

且不说好不好看, 不管怎么样,现在是通过Validation框架实现了校验。 当然了,我们的追求肯定不是这样的,Validator校验框架返回的错误提示太臃肿了 ,格式啥的都不一样,很难搞哦, 怎么给前台返回????



使用 统一格式 + 全局异常Handler 优化

增加统一返回 和 全局异常Handler,单独拦截参数校验的三个异常:javax.validation.ConstraintViolationExceptionorg.springframework.validation.BindExceptionorg.springframework.web.bind.MethodArgumentNotValidException

/**
     * @param e
     * @return
     */
    @ExceptionHandler(value = {BindException.class, ValidationException.class, MethodArgumentNotValidException.class})
    public ResponseEntity<ResponseData<String>> handleValidatedException(Exception e) {
        ResponseData<String> resp = null;
        if (e instanceof MethodArgumentNotValidException) {
            // BeanValidation exception
            MethodArgumentNotValidException ex = (MethodArgumentNotValidException) e;
            resp = ResponseData.fail(HttpStatus.BAD_REQUEST.value(),
                    ex.getBindingResult().getAllErrors().stream()
                            .map(ObjectError::getDefaultMessage)
                            .collect(Collectors.joining("; "))
            );
        } else if (e instanceof ConstraintViolationException) {
            // BeanValidation GET simple param
            ConstraintViolationException ex = (ConstraintViolationException) e;
            resp = ResponseData.fail(HttpStatus.BAD_REQUEST.value(),
                    ex.getConstraintViolations().stream()
                            .map(ConstraintViolation::getMessage)
                            .collect(Collectors.joining("; "))
            );
        } else if (e instanceof BindException) {
            // BeanValidation GET object param
            BindException ex = (BindException) e;
            resp = ResponseData.fail(HttpStatus.BAD_REQUEST.value(),
                    ex.getAllErrors().stream()
                            .map(ObjectError::getDefaultMessage)
                            .collect(Collectors.joining("; "))
            );
        }
        log.error("参数校验异常:{}", resp.getMessage());
        return new ResponseEntity<>(resp, HttpStatus.BAD_REQUEST);
    }

重新测试


源码

https://github.com/yangshangwei/boot2


相关文章
|
1月前
|
JSON 前端开发 Java
Spring MVC——获取参数和响应
本文介绍了如何在Spring框架中通过不同的注解和方法获取URL参数、上传文件、处理cookie和session、以及响应不同类型的数据。具体内容包括使用`@PathVariable`获取URL中的参数,使用`MultipartFile`上传文件,通过`HttpServletRequest`和`@CookieValue`获取cookie,通过`HttpSession`和`@SessionAttribute`获取session,以及如何返回静态页面、HTML代码片段、JSON数据,并设置HTTP状态码和响应头。
50 1
Spring MVC——获取参数和响应
|
1月前
|
JSON NoSQL Java
springBoot:jwt&redis&文件操作&常见请求错误代码&参数注解 (九)
该文档涵盖JWT(JSON Web Token)的组成、依赖、工具类创建及拦截器配置,并介绍了Redis的依赖配置与文件操作相关功能,包括文件上传、下载、删除及批量删除的方法。同时,文档还列举了常见的HTTP请求错误代码及其含义,并详细解释了@RequestParam与@PathVariable等参数注解的区别与用法。
|
2月前
|
缓存 前端开发 Java
springboot 的单体服务 字典参数转译
本文介绍了如何在Spring Boot项目中使用缓存来管理字典参数,并确保前后端数据一致性。首先,通过`@EnableCaching`启用缓存功能,接着创建一个自定义的字典缓存类`DicCache`。然后,通过配置类将`DicCache`添加到`cacheManager`中。此外,对字典服务进行改造,使用`@CachePut`和`@CacheEvict`注解保证数据一致性。最后,实现自定义注解`@DicSerializer`和序列化处理类`DictSerializerHandel`,用于在序列化过程中自动转换字典值。通过这种方式,可最小化代码改动并提高系统性能。
springboot 的单体服务 字典参数转译
|
1月前
|
前端开发 Java Spring
【Spring】“请求“ 之传递单个参数、传递多个参数和传递对象
【Spring】“请求“ 之传递单个参数、传递多个参数和传递对象
115 2
|
2月前
|
JSON Java 数据格式
springboot 参数统一处理
springboot 参数统一处理
|
1月前
|
监控 Java Maven
springboot学习二:springboot 初创建 web 项目、修改banner、热部署插件、切换运行环境、springboot参数配置,打包项目并测试成功
这篇文章介绍了如何快速创建Spring Boot项目,包括项目的初始化、结构、打包部署、修改启动Banner、热部署、环境切换和参数配置等基础操作。
136 0
|
2月前
|
Java Spring
spring boot 启动项目参数的设定
spring boot 启动项目参数的设定
|
3月前
|
XML Java 数据库
Spring5入门到实战------15、事务操作---概念--场景---声明式事务管理---事务参数--注解方式---xml方式
这篇文章是Spring5框架的实战教程,详细介绍了事务的概念、ACID特性、事务操作的场景,并通过实际的银行转账示例,演示了Spring框架中声明式事务管理的实现,包括使用注解和XML配置两种方式,以及如何配置事务参数来控制事务的行为。
Spring5入门到实战------15、事务操作---概念--场景---声明式事务管理---事务参数--注解方式---xml方式
|
3月前
|
Java API 数据格式
Spring Boot API参数读取秘籍大公开!6大神器助你秒变参数处理大师,让你的代码飞起来!
【8月更文挑战第4天】Spring Boot凭借其便捷的开发和配置特性,成为构建微服务的热门选择。高效处理HTTP请求参数至关重要。本文介绍六种核心方法:查询参数利用`@RequestParam`;路径变量采用`@PathVariable`;请求体通过`@RequestBody`自动绑定;表单数据借助`@ModelAttribute`或`@RequestParam`;请求头使用`@RequestHeader`;Cookie则依靠`@CookieValue`。每种方法针对不同场景,灵活运用可提升应用性能与用户体验。
67 9

热门文章

最新文章