bean validation校验方法参数_记录 JSR303的学习,主要包括简单校验,分组校验,自定义校验

其实JSR303没啥介绍的,大家知道是做校验的就可以了。简书里面是这样说的:SR-303 是JAVA EE 6 中的一项子规范,叫做Bean Validation,Hibernate Validator 是 Bean Validation 的参考实现 . Hibernate Validator 提供了 JSR 303 规范中所有内置 constraint 的实现,除此之外还有一些附加的 constraint。

一切尽在代码中:

快捷创建一个springboot项目

369c693b7fb69fa69ab0faa81faf258e.png

1,pom文件如下:

<?xml version="1.0" encoding="UTF-8"?>4.0.0org.springframework.boot        spring-boot-starter-parent        2.1.8.RELEASEcom.dwsoft.test    test-jsr303    0.0.1-SNAPSHOTtest-jsr303Demo project for Spring Boot11org.apache.httpcomponents            httpcore            4.4.13org.springframework.boot            spring-boot-starter-web        org.springframework.boot            spring-boot-starter-test            testorg.junit.vintage                    junit-vintage-engine                org.projectlombok            lombok            1.18.8org.springframework.boot                spring-boot-maven-plugin            

我用的springboot版本是:2.1.8.RELEASE,如果使用其他版本也可以,但是一定要确保引入了校验包:

4899b660d34711f0839f243fe079b0a8.png

2,创建主类,实体类,控制器

主类:

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

控制类:

/** * @author tlk * @date 2020/8/4-18:36 */@RestControllerpublic class TestController {    }

实体类:

package com.dwsoft.test.testjsr303.entity;import lombok.Data;import java.io.Serializable;/** * @author tlk * @date 2020/8/4 */@Datapublic class Brand implements Serializable {    private static final long serialVersionUID = 6249214818970952452L;    /**     * 品牌id     */    private Long brandId;    /**     * 品牌名     */    private String name;    /**     * 品牌logo地址     */    private String logo;    /**     * 介绍     */    private String descript;    /**     * 显示状态[0-不显示;1-显示]     */    private Integer showStatus;    /**     * 检索首字母     */    private String firstLetter;    /**     * 排序     */    private Integer sort;}

用的是注解@Data,需要安装插件lombok;你也可以不用这个注解,直接写get,set等方法。

统一格式响应封装类:

package com.dwsoft.test.testjsr303.utils;import org.apache.http.HttpStatus;import java.util.HashMap;import java.util.Map;/** * 返回数据 * * @author tlk  */public class R extends HashMap {    private static final long serialVersionUID = 1L;    public R() {        put("code", 0);        put("msg", "success");    }    public static R error() {        return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, "未知异常,请联系管理员");    }    public static R error(String msg) {        return error(HttpStatus.SC_INTERNAL_SERVER_ERROR, msg);    }    public static R error(int code, String msg) {        R r = new R();        r.put("code", code);        r.put("msg", msg);        return r;    }    public static R ok(String msg) {        R r = new R();        r.put("msg", msg);        return r;    }    public static R ok(Map map) {        R r = new R();        r.putAll(map);        return r;    }    public static R ok() {        return new R();    }    public R put(String key, Object value) {        super.put(key, value);        return this;    }}

开始校验:

1》简简单单的校验

给bean添加校验注解:

c58f96460dc8ae34760531741f82cef9.png

开启校验功能@Valid
4ac589cf139da77e58b16e1e8e150067.png

用postman测试(入参给的是一个空的json串):

761a13a3f05ac19a2b21cf761f9c6aa9.png

这是原始响应,我们可以封装统一格式,并且自定义message

改动如下:

f5faa1dd19e4e842cfb3bccdd36511cc.png

控制器中引入 BindingResult

package com.dwsoft.test.testjsr303.controller;import com.dwsoft.test.testjsr303.entity.Brand;import com.dwsoft.test.testjsr303.utils.R;import org.apache.http.HttpStatus;import org.springframework.validation.BindingResult;import org.springframework.validation.FieldError;import org.springframework.web.bind.annotation.RequestBody;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import javax.validation.Valid;import java.util.HashMap;import java.util.List;import java.util.Map;/** * @author tlk * @date 2020/8/4 */@RestControllerpublic class TestController {    @RequestMapping("/test/jsr303")    public R testJsr303(@Valid @RequestBody Brand brand, BindingResult bindingResult) {        if(bindingResult.hasErrors()){            Mapmap=new HashMap<>();            List fieldErrors = bindingResult.getFieldErrors();            fieldErrors.forEach((item) ->{                String field = item.getField();                String defaultMessage = item.getDefaultMessage();                map.put(field,defaultMessage);            });            return R.error(HttpStatus.SC_BAD_REQUEST,"入参不合法").put("data",map);        }        //业务处理        return R.ok();    }}

再次测试:

18bbd13f1f34a124fc448f0c4e0c1d46.png

完美!

2》分组校验主要用于表单的添加或者修改进行区分

添加两个接口:

package com.dwsoft.test.testjsr303.valid;/** * @author tlk * @date 2020/8/4-11:08 */public interface UpdateGroup {}
package com.dwsoft.test.testjsr303.valid;/** * @author tlk * @date 2020/8/4-11:08 */public interface AddGroup {}

如果想在添加的时候生效,如下:

cf1b294160158bc2239db75b09a7c473.png

0312963ab229c8824defbbd2f873edc4.png

​ 测试:

451f74bb77b04844d268cfd94be139c1.png

如果只是把bean改成:

15208938d1f8dc86dffdec43453ee69e.png

测试:

2c964033b81af67b1a8b9030f59d5fa8.png

校验没有起作用。

也可这样配置:

a22ab3ee6410c72a6c3f730ccc16ca80.png

ba112260e11856401fbb343721d8ec36.png

正常逻辑添加修改分开写,控制器对应方法只会配置一个分组

只要满足校验规则,就起作用。

注意:如果采用分组校验的形式,对应bean中的属性必须标注采用哪个校验组,不然不起任何校验作用

比如:

21315951d94ebd66a52ee0c878581bae.png

ba112260e11856401fbb343721d8ec36.png

正常逻辑添加修改分开写,控制器对应方法只会配置一个分组

测试:

e621e3d6df5e2f9f233bc643d030bafd.png

加上分组:

cf515a2ea17a99b8ffb901e22ac62e0d.png

测试:

200a9aebc2e76e2a169a3445c7a762f5.png

完美!分组主要看自己的分配逻辑,我这边只是做一个引导!

3》自定义校验:

如显示状态,我们要求在指定的数据中选择

2a7f98cda67b4fbec305abdeebe279b5.png

该怎么操作?

a》编写一个自定义的校验注解(可以参照@NotBlank等注解格式)

package com.dwsoft.test.testjsr303.valid;import javax.validation.Constraint;import javax.validation.Payload;import java.lang.annotation.*;/** * @author tlk * @date 2020/8/4-14:15 */@Documented@Constraint(        validatedBy = {})@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE})@Retention(RetentionPolicy.RUNTIME)@Repeatable(Checkvalue.List.class)public @interface Checkvalue {    String message() default "{com.dwsoft.test.testjsr303.valid.Checkvalue.message}";    Class>[] groups() default {};    Class extends Payload>[] payload() default {};    int[] value() default {};    @Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE})    @Retention(RetentionPolicy.RUNTIME)    @Documented    public @interface List {        Checkvalue[] value();    }}
20c6ba1208d32400bd046cd42b69e5c5.png

这个地方可以创建自己的消息文件(位置:resources/),ValidationMessages.properties,文件名一定要是这个

com.dwsoft.test.testjsr303.valid.Checkvalue.message = "请使用指定值"

b》编写一个自定义的校验器

package com.dwsoft.test.testjsr303.valid;import javax.validation.ConstraintValidator;import javax.validation.ConstraintValidatorContext;import java.util.HashSet;import java.util.Set;/** * @author tlk * @date 2020/8/4-14:29 */public class CheckValueConstraintValidator implements ConstraintValidator {    private Set set=new HashSet<>();    @Override    public void initialize(Checkvalue constraintAnnotation) {        int[] value = constraintAnnotation.value();        if(value!=null && value.length>1){            for (Integer integer : set) {                set.add(integer);            }        }    }    @Override    public boolean isValid(Integer integer, ConstraintValidatorContext constraintValidatorContext) {        if(set.contains(integer)) return true;        return false;    }}

c》关联自定义的校验器和自定义的校验注解

ba68359a83b284984d8acbb14915e5de.png

测试:

先修改控制器:

90e824bd2a0aff30cf60084482e19ef6.png

修改bean:

35d39c91de3b5c5f34355efb327aa74c.png

postman:

17a08251a98d09b3fbf0bd6cbd61c914.png

成功!

474181d399b8b677cfeebf340a848f9d.png

这个是配置文件的提示,咱们也可以在bean上再自定义

e8912323c8fa0395656503f3b0e707e1.png

测试:

8a8540defe3a62e715e07c9d9735e8b4.png

校验这一块结束!!!!!!

补充一下全局异常处理:

a》编写异常处理类,使用@ControllerAdvice,使用@ExceptionHandler标注方法可以处理的异常。

package com.dwsoft.test.testjsr303.expection;import com.dwsoft.test.testjsr303.utils.R;import lombok.extern.slf4j.Slf4j;import org.apache.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.RestControllerAdvice;import java.util.HashMap;import java.util.List;import java.util.Map;/** * @author tlk * @date 2020/8/4-15:31 *///@ResponseBody//@ControllerAdvice    合二为一@RestControllerAdvicepublic class MyControllerAdvice {    @ExceptionHandler(value = MethodArgumentNotValidException.class)    public R handleValidExpection(MethodArgumentNotValidException e){        Mapmap=new HashMap<>();        BindingResult bindingResult = e.getBindingResult();        List fieldErrors = bindingResult.getFieldErrors();        fieldErrors.forEach((one)->{            String field = one.getField();            String defaultMessage = one.getDefaultMessage();            map.put(field,defaultMessage);        });        return R.error(HttpStatus.SC_BAD_REQUEST,"入参不合法").put("data",map);    }    //其他异常    @ExceptionHandler(value = Throwable.class)    public R handleOtherExpection(Throwable  throwable){        return R.error();    }}

控制器注释掉之前的处理:

package com.dwsoft.test.testjsr303.controller;import com.dwsoft.test.testjsr303.entity.Brand;import com.dwsoft.test.testjsr303.utils.R;import com.dwsoft.test.testjsr303.valid.AddGroup;import com.dwsoft.test.testjsr303.valid.UpdateGroup;import org.apache.http.HttpStatus;import org.springframework.validation.BindingResult;import org.springframework.validation.FieldError;import org.springframework.validation.annotation.Validated;import org.springframework.web.bind.annotation.RequestBody;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.ResponseBody;import org.springframework.web.bind.annotation.RestController;import javax.validation.Valid;import java.security.acl.Group;import java.util.HashMap;import java.util.List;import java.util.Map;/** * @author tlk * @date 2020/8/4 */@RestControllerpublic class TestController {    @RequestMapping("/test/jsr303")    public R testJsr303(@Validated(value = {AddGroup.class}) @RequestBody Brand brand//            , BindingResult bindingResult      )    {//        if(bindingResult.hasErrors()){//            Mapmap=new HashMap<>();//            List fieldErrors = bindingResult.getFieldErrors();//            fieldErrors.forEach((item) ->{//                String field = item.getField();//                String defaultMessage = item.getDefaultMessage();//                map.put(field,defaultMessage);//            });//            return R.error(HttpStatus.SC_BAD_REQUEST,"入参不合法").put("data",map);//        }        //业务处理        return R.ok();    }}

测试:

2402dfcef75f8f320953804c0954f0ff.png

​​​

大功告成!!!!!!!!!!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值