JSR303的简单应用(谷粒商城

JSR303的简单应用

JSR的介绍

JSR

JSR是Java Specification Requests的缩写,意思是Java 规范提案。是指向JCP(Java Community Process)提出新增一个标准化技术规范的正式请求。任何人都可以提交JSR,以向Java平台增添新的API和服务。JSR已成为Java界的一个重要标准。

JSR303

JSR-303 是JAVA EE 6 中的一项子规范,叫做Bean Validation,Hibernate Validator 是 Bean Validation 的参考实现 . Hibernate Validator 提供了 JSR 303 规范中所有内置 constraint 的实现,除此之外还有一些附加的 constraint。

简单校验的实际运用

第1步:属性添加注解

给javabean中的属性添加校验注解(校验注解可以在javax.validation.constraints中查看

/**
	 * 品牌id
	 */
	@NotNull(message = "修改信息必须指定品牌id",groups = {UpdateGroup.class})
	@Null(message = "新增信息不能指定品牌id",groups = {AddGroup.class})
	@TableId
	private Long brandId;

message为校验不通过时,给出的提示信息;groups为分组校验(这个后面在讲

第2步:形参添加注解

在controller形参列表中对应的javabean前面添加**@Valid**注解

    /**
     * 保存
     */
    @RequestMapping("/save")
    //@RequiresPermissions("product:brand:save")
    public R save(@Valid(AddGroup.class) @RequestBody BrandEntity brand ){
        brandService.save(brand);
        return R.ok();
    }

此时已经开启了数据校验功能额

第3步:获取javabean校验失败的属性和原因

紧跟被@Valid注解的形参后,使用BindingResult result,可以通过result对象获取校验失败的属性和失败原因

    /**
     * 保存
     */
    @RequestMapping("/save")
    //@RequiresPermissions("product:brand:save")
    public R save(@Valid(AddGroup.class) @RequestBody BrandEntity brand , BindingResult result){
        Map<String,String> map = new HashMap<>();
        //判断是否含有校验失败
        if(result.hasErrors()){
            //1.获取校验的错误信息
            result.getFieldErrors().forEach((item)->{
                //FieldError 获取错误提示信息
                String defaultMessage = item.getDefaultMessage();
                //获取错误的属性名称
                String field = item.getField();
                map.put(field,defaultMessage);
            });
            //将校验不通过的属性和失败原因放入R返回值对象中
            return R.error(400,"提交的数据不合法").put("data",map);
        }
        else{
            brandService.save(brand);
        }
        brandService.save(brand);
        return R.ok();
    }

此时就能获的校验不通过的属性和原因

优化:如果在controller中有很多方法都需要进行数据校验之后的处理,为了方便,我们可以把数据校验之后的处理放在全局异常处理类中

上面的步骤中,第一步和第二步不变,将第三步中的处理逻辑注释

第3.1步

/**
     * 保存
     */
    @RequestMapping("/save")
    //@RequiresPermissions("product:brand:save")
    public R save(@Valid(AddGroup.class) @RequestBody BrandEntity brand /*, BindingResult result*/){
//        Map<String,String> map = new HashMap<>();
//        //判断是否含有校验失败
//        if(result.hasErrors()){
//            //1.获取校验的错误信息
//            result.getFieldErrors().forEach((item)->{
//                //FieldError 获取错误提示信息
//                String defaultMessage = item.getDefaultMessage();
//                //获取错误的属性名称
//                String field = item.getField();
//                map.put(field,defaultMessage);
//            });
//            return R.error(400,"提交的数据不合法").put("data",map);
//        }
//        else{
//            brandService.save(brand);
//        }
        /**
         * 将数据校验出现的异常放到统一异常处理中处理
         */
        brandService.save(brand);
        return R.ok();
    }

第3.2步 编写全局异常处理类

package com.watching.gulimall.product.exception;

import com.watching.common.exception.BizCodeEnume;
import com.watching.common.utils.R;
import lombok.extern.slf4j.Slf4j;
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.Map;

/**
 * @author Watching
 * * @date 2022/10/8
 * * Describe:集中处理所有异常
 */
@Slf4j
@RestControllerAdvice(basePackages = "com.watching.gulimall.product.controller")
public class GulimallExceptionControllerAdvice  {

    /**
     * 处理数据校验异常
     * @param e
     * @return
     */
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public R handleValidException(MethodArgumentNotValidException e){
        log.error("数据校验出现异常:{};异常类型:{}",e.getMessage(),e.getClass());
        //获取数据校验错误的信息
        Map<String,String> map = new HashMap<>();
        e.getBindingResult().getFieldErrors().forEach((item)->{
            String field = item.getField();
            String defaultMessage = item.getDefaultMessage();
            map.put(field,defaultMessage);
        });
        return R.error(BizCodeEnume.VAILD_EXCEPTION.getCode(), BizCodeEnume.VAILD_EXCEPTION.getMsg()).put("data",map);
    }

 

}

在全局异常处理类中可以使用MethodArgumentNotValidException e的对象获取 BindingResult对象。然后使用第3步中相同的逻辑进行处理

分组校验的实际运用

有些情况,controller中不同的方法需要对不同的属性进行校验,此时就需要用到分组校验

第1步 创建标识性接口

/**
 * @author Watching
 * * @date 2022/10/8
 * * Describe: jsr303分组校验标识
 */
public interface AddGroup {
}
/**
 * @author Watching
 * * @date 2022/10/8
 * * Describe: jsr303分组校验标识
 */
public interface UpdateGroup {
}

第2步 在属性的校验注解中添加groups属性

/**
	 * 品牌id
	 */
	@NotNull(message = "修改信息必须指定品牌id",groups = {UpdateGroup.class})
	@Null(message = "新增信息不能指定品牌id",groups = {AddGroup.class})
	@TableId
	private Long brandId;
/**
	 * 品牌名
	 */
	@NotBlank(message = "品牌名称不能空",groups = {UpdateGroup.class,AddGroup.class})
	private String name;

表明这些属性都在不同的校验分组下

第3步 更改controller形参列表中的注解@Valid => @Validated

在controller形参列表中给对应形参前面加上 @Validated({AddGroup.class}) 表明该方法只需要校验在AddGroup分组下的属性。将 @Valid 改为 @Validated({“此处写标识性接口”})
@Validated代表分组校验

/**
     * 保存
     */
    @RequestMapping("/save")
    //@RequiresPermissions("product:brand:save")
    public R save(@Validated(AddGroup.class) @RequestBody BrandEntity brand /*, BindingResult result*/){
//        Map<String,String> map = new HashMap<>();
//        //判断是否含有校验失败
//        if(result.hasErrors()){
//            //1.获取校验的错误信息
//            result.getFieldErrors().forEach((item)->{
//                //FieldError 获取错误提示信息
//                String defaultMessage = item.getDefaultMessage();
//                //获取错误的属性名称
//                String field = item.getField();
//                map.put(field,defaultMessage);
//            });
//            return R.error(400,"提交的数据不合法").put("data",map);
//        }
//        else{
//            brandService.save(brand);
//        }
        /**
         * 将数据校验出现的异常放到统一异常处理中处理
         */
        brandService.save(brand);
        return R.ok();
    }

注意,如果属性的校验注解中没有写groups属性,则默认为在分组校验的情况下不会进行校验

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值