需求
项目中保存和提交方法共用同一个,现在需要在后端进行参数校验,保存时不要校验必填项,提交时需要校验必填项
思路
目前保存和提交的request是同一个,根据状态字段判断是否开启流程。
使用validation进行校验,使用AOP提前获取到状态,若是提交则进行校验,否则直接执行保存方法。
直接上代码,欢迎交流指正
代码
- 首先定义一个注解,作为切点
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestValid {
}
- 请求类:这里随便定义了一个用户类
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class User {
private Integer id;
@Size(min = 5, max = 10, message = "请输入5-10个字符的用户名")
private String username;
@NotBlank(message = "密码不能为空")
private String password;
@Min(18)
private Integer age;
}
- 控制层
@RestController
@RequestMapping("/user")
public class UserController {
@PostMapping("/fun")
@RequestValid
public Object fun1(@RequestBody User user) {
// 校验通过,才会执行业务逻辑处理
return 1111;
}
}
- 切面:由于执行顺序的问题,必须手动校验
@Aspect// 这个注解表明 使用spring boot 的aop,需要开启aop spring.aop.auto=true
@Component
@Slf4j
public class ValidationInspect {
@Pointcut("@annotation(cn.king.validation02.annotation.RequestValid)")
public void pointcut() {
}
@Before(value = "pointcut()")
public void before(JoinPoint joinPoint) throws Throwable {
log.info(">>>>>Inspect.before");
// 获取参数
Object[] args = joinPoint.getArgs();
for (Object arg : args) {
//通过反射获取所有的字段,getFileds()获取public的修饰的字段、getDeclaredFields获取private protected public修饰的字段
Field[] declaredFields = arg.getClass().getDeclaredFields();
for (Field f : declaredFields){
if ("username".equals(f.getName())) {
// 获取值判断是否校验必填项
f.setAccessible(true);
String userName = (String) f.get(arg);
if ("zhangsan".equals(userName)) {
try {
ValidatorUtils.validateEntity(arg);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
}
}
}
}
- 校验工具类
public class ValidatorUtils {
private ValidatorUtils() {
}
private static Validator validator;
static {
validator = Validation.buildDefaultValidatorFactory().getValidator();
}
/**
* 校验对象
*
* @param object 待校验对象
* @param groups 待校验的组
* 校验不通过,则报RRException异常
*/
public static void validateEntity(Object object, Class<?>... groups) throws Exception {
Set<ConstraintViolation<Object>> constraintViolations = validator.validate(object, groups);
if (!constraintViolations.isEmpty()) {
Iterator<ConstraintViolation<Object>> iterator = constraintViolations.iterator();
StringBuilder msg = new StringBuilder();
while (iterator.hasNext()) {
ConstraintViolation<Object> constraint = iterator.next();
msg.append(constraint.getMessage()).append(',');
}
System.out.println(msg.toString().substring(0, msg.toString().lastIndexOf(',')));
throw new Exception("校验异常");
}
}
}