JSR303分组校验属于后端校验的一种很方便的方式
步骤:
1.新建两个接口,用来代表哪两个组,比如,AddGroup,UpdateGroup代表添加分组和修改分组
//添加分组
package com.jc.common.valid;
public interface AddGroup {
}
//修改分组
package com.jc.common.valid;
public interface UpdateGroup {
}
2.给需要验证的实体类的字段上添加对应的校验注解,并且指定其分组
package com.jc.gulimall.product.entity;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.util.Date;
import com.jc.common.valid.AddGroup;
import com.jc.common.valid.UpdateGroup;
import lombok.Data;
import org.hibernate.validator.constraints.URL;
import javax.validation.constraints.*;
/**
* 品牌
*
* @author wjc
* @email 1678912421@gmail.com
* @date 2021-07-16 21:22:32
*/
@Data
@TableName("pms_brand")
public class BrandEntity implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 品牌id
*/
@NotNull(message = "修改必须指定品牌id",groups = {UpdateGroup.class})
@Null(message = "添加不能添加品牌id",groups = {AddGroup.class})
@TableId
private Long brandId;
/**
* 品牌名
*/
@NotBlank(message = "品牌名不能为空!")
private String name;
/**
* 品牌logo地址
*/
@URL(message = "logo地址必须是一个合法的URL!",groups = {AddGroup.class,UpdateGroup.class})
@NotNull(message = "logo不能为空!",groups = {AddGroup.class,UpdateGroup.class})
private String logo;
/**
* 介绍
*/
private String descript;
/**
* 显示状态[0-不显示;1-显示]
*/
private Integer showStatus;
/**
* 检索首字母
*/
@NotNull(message = "首字母不能为空!",groups = {AddGroup.class,UpdateGroup.class})
@Pattern(regexp = "/^[a-zA-Z]$/",message = "检索首字符必须是一个字母",groups = {AddGroup.class,UpdateGroup.class})
private String firstLetter;
/**
* 排序
*/
@NotNull(message = "排序字段不能为空!",groups = {AddGroup.class,UpdateGroup.class})
@Min(value = 0,message = "排序必须大于等于0",groups = {AddGroup.class,UpdateGroup.class})
private Integer sort;
}
上边的logo,firstLetter,sort字段我都添加了两个分组,也就是说在修改和添加的情况下都会校验
3.在url对应的方法参数中需要校验的实体类前加上@Validated(AddGroup.class)注解,在需要校验的实体类中标注AddGroup分组的字段进行校验,@Validated注解后边不指定分组类别,则默认是对不标注分组的字段进行校验
//对BrandEntity 字段中指定UpdaGroup分组的字段就行校验
@RequestMapping("/update")
public R update(@Validated(UpdateGroup.class) @RequestBody BrandEntity brand){
brandService.updateByid(brand);
return R.ok();
}
@RequestMapping("/save")
public R save(@Validated(AddGroup.class) @RequestBody BrandEntity brand/*, BindingResult bindingResult*/){
// 统一异常处理
// if (bindingResult.hasErrors()){
// Map<String,String> map = new HashMap<>();
// bindingResult.getFieldErrors().stream().forEach((item)->{
// String defaultMessage = item.getDefaultMessage();
// String field = item.getField();
// map.put(field,defaultMessage);
// });
// return R.error(400,"提交的数据不合法").put("data",map);
// }
brandService.save(brand);
return R.ok();
}
实践:
在save请求中,对实体类标注了AddGroup分组,则对实体类中所有标注AddGroup的分组就行校验,
对应上边的也就是,
@Null(message = "添加不能添加品牌id",groups = {AddGroup.class})
private Long brandId;
@NotNull(message = "首字母不能为空!",groups = {AddGroup.class,UpdateGroup.class})
@Pattern(regexp = "/^[a-zA-Z]$/",message = "检索首字符必须是一个字母",groups = {AddGroup.class,UpdateGroup.class})
private String firstLetter;
/**
* 排序
*/
@NotNull(message = "排序字段不能为空!",groups = {AddGroup.class,UpdateGroup.class})
@Min(value = 0,message = "排序必须大于等于0",groups = {AddGroup.class,UpdateGroup.class})
private Integer sort;
@URL(message = "logo地址必须是一个合法的URL!",groups = {AddGroup.class,UpdateGroup.class})
@NotNull(message = "logo不能为空!",groups = {AddGroup.class,UpdateGroup.class})
private String logo;
下面我们再看没有标注任何分组的字段,也就是name字段
@NotBlank(message = "品牌名不能为空!")
private String name;
我们将BrandController中的update方法中分组去掉原来是@Validated(updateGroup.class)
@RequestMapping("/update")
public R update(@Validated @RequestBody BrandEntity brand){
brandService.updateByid(brand);
return R.ok();
}
由于除了name之外的字段都标注了分组,所以name之外的字段是不进行校验的,只有没有标注分组的name字段才进行校验。
总结:
在需要校验的实体类中,哪个字段标注了哪个分组,就在方法参数注解中指定校验分组的情况下进行校验。
字段没有标注分组的情况下,就在方法参数注解中没指定校验分组的情况下进行校验。