-
引入依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> <version>2.3.4.RELEASE</version> </dependency>
-
数据约束实体类代码BrandEntity.java
package com.kenai.gulimall.product.entity; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import java.io.Serializable; import java.util.Date; import lombok.Data; import org.hibernate.validator.constraints.URL; import javax.validation.constraints.*; /** * 品牌 * * @author zhaolijian * @email [email protected] * @date 2021-02-20 20:39:29 */ @Data @TableName("pms_brand") public class BrandEntity implements Serializable { private static final long serialVersionUID = 1L; /** * 品牌id */ @TableId private Long brandId; /** * 品牌名 */ @NotBlank(message = "品牌名不能为空") private String name; /** * 品牌logo地址 */ @NotBlank(message = "品牌logo地址不能为空") @URL(message = "logo必须是一个合法的url地址") private String logo; /** * 介绍 */ private String descript; /** * 显示状态[0-不显示;1-显示] */ private Integer showStatus; /** * 检索首字母 */ @NotBlank(message = "检索首字母不能为空") // ^: 匹配输入字符串的开始位置, $: 匹配输入字符串的结尾位置 @Pattern(regexp = "[a-zA-Z]", message = "检索首字母必须是一个字母") private String firstLetter; /** * 排序 */ @NotNull(message = "排序字段不能为空") @Min(value = 0, message = "排序字段必须大于等于0") private Integer sort; }
-
数据校验使用代码
package com.kenai.gulimall.product.controller; import java.util.Arrays; import java.util.HashMap; import java.util.Map; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import org.springframework.validation.BindingResult; import com.kenai.gulimall.product.entity.BrandEntity; import com.kenai.gulimall.product.service.BrandService; import com.kenai.common.utils.PageUtils; import com.kenai.common.utils.R; import javax.validation.Valid; /** * 品牌 * * @author zhaolijian * @email [email protected] * @date 2021-02-20 20:39:29 */ @RestController @RequestMapping("product/brand") public class BrandController { @Autowired private BrandService brandService; /** * 保存 * @Valid注解的作用是让BrandEntity满足约定的规范,比如非空等 * BindingResult是规范校验的返回结果 */ @RequestMapping("/save") //@RequiresPermissions("product:brand:save") public R save(@Valid @RequestBody BrandEntity brand, BindingResult result){ if(result.hasErrors()){ Map<String, String> map = new HashMap<>(); result.getFieldErrors().forEach((item) -> { // 获取错误的属性名称 String field = item.getField(); // 获取错误提示 String message = item.getDefaultMessage(); map.put(field, message); }); return R.error(400, "提交的数据不合法").put("data", map); }else{ brandService.save(brand); return R.ok(); } } }
-
分组校验
-
背景
有些字段在不同环境下的校验规则不同
比如id在新增的时候必须为空,但是在修改的时候必须不为空 -
实体类(UpdateGroup.class、AddGroup.class为空接口)
package com.kenai.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.kenai.common.valid.AddGroup; import com.kenai.common.valid.UpdateGroup; import lombok.Data; import org.apache.ibatis.annotations.Update; import org.hibernate.validator.constraints.URL; import org.springframework.lang.Nullable; import javax.validation.constraints.*; /** * 品牌 * * @author zhaolijian * @email [email protected] * @date 2021-02-20 20:39:29 */ @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 = "品牌名不能为空",groups = { UpdateGroup.class, AddGroup.class}) private String name; /** * 品牌logo地址 */ @NotBlank(message = "品牌logo地址不能为空",groups = { AddGroup.class}) @URL(message = "logo必须是一个合法的url地址",groups = { UpdateGroup.class, AddGroup.class}) private String logo; /** * 介绍 */ private String descript; /** * 显示状态[0-不显示;1-显示] */ private Integer showStatus; /** * 检索首字母 */ @NotBlank(message = "检索首字母不能为空",groups = { AddGroup.class}) // ^: 匹配输入字符串的开始位置, $: 匹配输入字符串的结尾位置 @Pattern(regexp = "[a-zA-Z]", message = "检索首字母必须是一个字母",groups = { UpdateGroup.class, AddGroup.class}) private String firstLetter; /** * 排序 */ @NotNull(message = "排序字段不能为空",groups = { AddGroup.class}) @Min(value = 0, message = "排序字段必须大于等于0",groups = { UpdateGroup.class, AddGroup.class}) private Integer sort; }
-
逻辑处理类
/** * 使用统一异常处理,通过@RestControllerAdvice能自动获取抛出的异常 * @Validated: 当使用JSR303分组校验功能时,指定属于哪个分组,同一个字段对于不同分组可能有不同的处理方式 * @param brand * @return */ @RequestMapping("/save") public R save(@Validated({ AddGroup.class}) @RequestBody BrandEntity brand){ brandService.save(brand); return R.ok(); } /** * 修改 */ @RequestMapping("/update") //@RequiresPermissions("product:brand:update") public R update(@Validated({ UpdateGroup.class}) @RequestBody BrandEntity brand){ brandService.updateById(brand); return R.ok(); }
注: 在分组校验的情况下(即逻辑处理类中的方法参数注解@Validated中有分组信息,比如@Validated({UpdateGroup.class})), 没有指定分组的实体类中校验注解不生效.需要指定分组才能生效(即如@NotBlank(group={UpdateGroup.class})指定了分组才会生效).
要想使没有指定分组的实体类中校验注解生效,则逻辑处理类中的注解@Validated不能带分组参数