1. 参考代码下载
下载代码分支dev-feature-yuhl
2. 创建自定义注解
所在Module:scrm-common
所在包:org.springblade.common.valid.annotation
注解:ListValue
说明:ListValueConstraintValidator.class为此注解的验证器
package org.springblade.common.valid.annotation;
import org.springblade.common.valid.validator.ListValueConstraintValidator;
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
/**
* 自定义注解
*/
@Documented
@Constraint(validatedBy = { ListValueConstraintValidator.class})
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
@Retention(RUNTIME)
public @interface ListValue {
String message() default "{com.scrm.common.valid.ListValue.message}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
int[] vals() default {};
}
3. 创建提示信息
所在Module:scrm-common
路径:scrm-common/src/main/resources/ValidationMessages.properties
com.scrm.common.valid.ListValue.message=\u5FC5\u987B\u63D0\u4EA4\u6307\u5B9A\u7684\u503C
com.scrm.common.valid.ConstantValue.message=\u987B\u63D0\u4EA4\u5F20\u4E09
4. 创建验证器
所在Module:scrm-common
路径:org.springblade.common.valid.validator.ListValueConstraintValidator
package org.springblade.common.valid.validator;
import org.springblade.common.valid.annotation.ListValue;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.HashSet;
import java.util.Set;
/**
* 验证器
*/
public class ListValueConstraintValidator implements ConstraintValidator<ListValue,Integer> {
private Set<Integer> set = new HashSet<>();
/**
* 初始化方法
*/
@Override
public void initialize(ListValue constraintAnnotation) {
int[] vals = constraintAnnotation.vals();
for (int val : vals) {
set.add(val);
}
}
//判断是否校验成功
/**
*
* @param value 需要校验的值
* @param context
* @return
*/
@Override
public boolean isValid(Integer value, ConstraintValidatorContext context) {
return set.contains(value);
}
}
5. 统一异常处理
所在Module:scrm-member
路径:com.scrm.member.exception.MemberExceptionControllerAdvice
package com.scrm.member.exception;
import lombok.extern.slf4j.Slf4j;
import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.tool.api.IResultCode;
import org.springblade.core.tool.api.R;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
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;
/**
* 集中处理所有异常
*/
@Slf4j
@RestControllerAdvice(basePackages = "com.scrm.member.controller") // 包含@ResponseBody和@ControllerAdvice
public class MemberExceptionControllerAdvice extends ServiceException {
public MemberExceptionControllerAdvice(String message) {
super(message);
}
public MemberExceptionControllerAdvice(IResultCode resultCode) {
super(resultCode);
}
public MemberExceptionControllerAdvice(IResultCode resultCode, Throwable cause) {
super(resultCode, cause);
}
/**
* 真对MethodArgumentNotValidException异常的处理逻辑
* @param e
* @return
*/
@ExceptionHandler(value= MethodArgumentNotValidException.class)
public R handleVaildException(MethodArgumentNotValidException e){
log.error("数据校验出现问题{},异常类型:{}",e.getMessage(),e.getClass());
BindingResult bindingResult = e.getBindingResult();
//fieldError.getField() :可以获取具体那个字段有问题
Map<String,String> errorMap = new HashMap<>();
bindingResult.getFieldErrors().forEach((fieldError)->{
errorMap.put(fieldError.getField(),fieldError.getDefaultMessage());
});
return R.fail("数据校验出现问题" + e.getMessage() + ",异常类型:" + e.getClass() + ")");
}
/**
* 托底的异常处理逻辑
* @param e
* @return
*/
@ExceptionHandler(value= Exception.class)
public R handleVaildException(Exception e){
log.error("数据校验出现问题{},异常类型:{}",e.getMessage(),e.getClass());
return R.fail("系统未知异常");
}
}
6. 创建Group
所在Module:scrm-common
路径:org.springblade.common.valid.group
7. 实体类
所在Module:scrm-member-api
路径:com.scrm.member.entity.Brand
package com.scrm.member.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import org.hibernate.validator.constraints.URL;
import org.springblade.common.valid.annotation.ConstantValue;
import org.springblade.common.valid.group.AddGroup;
import org.springblade.common.valid.annotation.ListValue;
import org.springblade.common.valid.group.UpdateGroup;
import org.springblade.common.valid.group.UpdateStatusGroup;
import org.springblade.common.valid.group.UpdateZhangsanGroup;
import javax.validation.constraints.*;
import java.io.Serializable;
/**
* 品牌
*
* @author yuhl
* @email fsjwin@163.com
* @date 2020-09-04 14:12:07
*/
@Data
@TableName("brand")
public class Brand 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地址
*/
@URL(message = "logo必须是一个url地址",groups = {UpdateGroup.class,AddGroup.class})
@NotBlank(groups = AddGroup.class)
private String logo;
/**
* 介绍
*/
private String descript;
/**
* 显示状态[0-不显示;1-显示]
*/
// @Pattern()
@ListValue(vals = {0,1},groups = {AddGroup.class, UpdateStatusGroup.class})
@NotNull(groups = {AddGroup.class,UpdateStatusGroup.class})
private Integer showStatus;
/**
* 检索首字母
* @Pattern 自定义正则
*/
@Pattern(regexp = "^[a-zA-Z]$",message = "检索输字母必须是一个字母",groups = {UpdateGroup.class,AddGroup.class})
@NotEmpty(groups = {AddGroup.class})
private String firstLetter;
/**
* 排序
*/
@Min(value=0,message = "排序必须大于等于0",groups = {UpdateGroup.class,AddGroup.class})
@NotNull(groups = {AddGroup.class})
private Integer sort;
@ConstantValue(value = "张三",groups = {AddGroup.class, UpdateStatusGroup.class})
@NotNull(groups = {UpdateZhangsanGroup.class})
@TableField(exist = false)
private String other;
}
8. controller使用
所在Module:scrm-member
路径:com.scrm.member.controller.BrandController
package com.scrm.member.controller;
import com.scrm.member.entity.Brand;
import org.springblade.common.valid.group.AddGroup;
import org.springblade.common.valid.group.UpdateGroup;
import org.springblade.common.valid.group.UpdateStatusGroup;
import org.springblade.common.valid.group.UpdateZhangsanGroup;
import org.springblade.core.tool.api.R;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 品牌
*
* @author yuhl
* @email fsjwin@163.com
* @date 2020-09-04 14:48:33
*/
@RestController
@RequestMapping("brand")
public class BrandController {
/**
* 信息
*/
@RequestMapping("/infos")
public R info(@RequestParam("brandIds") List<Long> brandIds){
//List<Brand> brands = brandService.getBrandByIds(brandIds);
return R.success("成功");
}
/**
* 保存
* 使用BindingAdvise去感知异常,不在自己使用BindingResult封装异常
*/
@RequestMapping("/save1")
public R save1(@Valid @RequestBody Brand brand, BindingResult result){
if(result.hasErrors()){
Map<String,String> map = new HashMap();
//1 获得验证的错误结果
result.getFieldErrors().forEach((item)->{
//FieldError 获得到错误提示
String message = item.getDefaultMessage();
//获取错误的属性的名字
String field = item.getField();
map.put(field,message);
});
return R.fail("提交的数据不合法");
} else {
//brandService.save(brand);
}
//brandService.save(brand);
return R.success("成功!");
}
/**
* 保存
*/
@RequestMapping("/save")
public R save(@Validated({AddGroup.class})@RequestBody Brand brand){
//brandService.save(brand);
return R.success("成功!");
}
@RequestMapping("/mysave")
public R mysave(@Valid @RequestBody Brand brand){
//brandService.save(brand);
return R.success("成功!");
}
/**
* 修改
*/
@RequestMapping("/update")
public R update(@Validated(UpdateGroup.class) @RequestBody Brand brand){
//brandService.updateDetail(brand);
return R.success("成功!");
}
/**
* 修改
*/
@RequestMapping("/updatezhangsan")
//@RequiresPermissions("product:brand:update")
public R updatezhangsan(@Validated(UpdateZhangsanGroup.class) @RequestBody Brand brand){
//brandService.updateDetail(brand);
return R.success("成功!");
}
/**
* 修改状态
*/
@RequestMapping("/update/status")
public R updateStatus(@Validated(UpdateStatusGroup.class) @RequestBody Brand brand){
//brandService.updateById(brand);
return R.success("成功!");
}
/**
* 删除
*/
@RequestMapping("/delete")
public R delete(@RequestBody Long[] brandIds){
//brandService.removeByIds(Arrays.asList(brandIds));
return R.success("成功!");
}
}