springboot项目使用validation-api进行参数校验

一、引入依赖

要使用参数校验注解,需要引入以下依赖,注意springboot2.0的web模块已经包含此依赖

        <dependency>
            <groupId>jakarta.validation</groupId>
            <artifactId>jakarta.validation-api</artifactId>
        </dependency>

添加了这个jar包,仅代表可以在项目中引入如@NotNull等注解,但是它并不会起作用,上面的依赖只是使用了Java规范,并没有提供实现,因此还需要引入hibernate-validator模块

		<dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>6.1.0.Final</version>
        </dependency>

在springboot项目中直接使用场景启动器即可

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

二、参数校验

1- 在Controller中使用

由于springweb对http接口的参数校验进行了封装,在requestbody中使用参数校验如果校验未通过,则抛出的异常为spring定义的异常org.springframework.web.bind.MethodArgumentNotValidException。使用 @Valid@Validated都可,区别在于前者由hibernate-validator提供,后者由spring提供。如果是对象参数则抛出org.springframework.validation.BindException

@RestController
@RequestMapping("/validator")
public class ValidatorController {

    @PostMapping("test1")
    public String test1(@Valid @RequestBody TestDto testDto) {
        System.out.println(testDto);
        return "success";
    }

    @Data
    private static class TestDto {
        @NotNull(message = "id不能为空")
        private Long id;
        @NotBlank(message = "name不能为空")
        private String name;
    }
}

2 - 在其它bean中使用

单参数校验

在controller中使用参数校验可以保证接口请求时数据的完整性,在其它的参数校验情况下,例如service中需要校验某方法参数,bean一定要加入 @Validated注解,使用方式如下:

@Service
@Validated
public class ValidatorService {

    public void test1(@NotNull String name) {
        System.out.println(name);
    }

}

在调用此test1方法时,如果实参为null,则抛出 javax.validation.ConstraintViolationException异常。

bean属性校验

如果方法的参数为对象,则需要对形参加入@Valid 或者 @Validated注解才能起作用

@Service
@Validated
public class ValidatorService {

    public void test2(@Valid SaveDTO saveDTO) {
        System.out.println(saveDTO);
    }
    
    @Data
    public static final class SaveDTO {
        @NotNull(message = "id不能为空")
        private Long id;
        
        @NotEmpty(message = "username不能为空")
        private String username;
    }

}

三、分组校验

在对象参数校验场景下,有一种特殊场景,同一个参数对象在不同的场景下有不同的校验规则。比如,在创建对象时不需要传入id字段(id字段是主键,由系统生成,不由用户指定),但是在修改对象时就必须要传入id字段。在这样的场景下就需要对注解进行分组。此时只能使用 @Validated

组件有一个默认的分组 Default.class,我们可以再创建一个分组

public @interface UpdateAction {

}

在参数类中需要校验的属性上,在注解中添加groups属性:

package com.example.demo.service;

import com.example.demo.config.UpdateAction;
import lombok.Data;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import javax.validation.groups.Default;

/**
 * @author Lianghao Teng
 * @date 2022/2/7 11:18 AM
 */
@Service
@Validated
public class ValidatorService {

    /**
     * update时需要校验id字段不为空,校验分组为UpdateAction
     * @param saveDTO
     */
    public void update(@Validated({Default.class, UpdateAction.class}) SaveDTO saveDTO) {
        System.out.println(saveDTO);
    }

    /**
     * 保存时不需要校验id字段,使用Default,也可以不写,它是默认的
     * @param saveDTO
     */
    public void save(@Validated({Default.class}) SaveDTO saveDTO) {
        System.out.println(saveDTO);
    }

    @Data
    public static final class SaveDTO {
        /**表示只在UpdateAction分组下校验id字段*/
        @NotNull(message = "id不能为空", groups = {UpdateAction.class})
        private Long id;
        /**表示只在默认分组下校验username字段*/
        @NotEmpty(message = "username不能为空")
        private String username;
    }

}

上一篇:接口指南,快递鸟物流开放平台API对接,极兔速递


下一篇:Activiti6核心API