【Springboot之切面编程】通过切面AOP实现入参校验
最简洁、最少侵入实现接口入参校验
原创:https://www.jianshu.com/p/a9e96e815b53
目录
- 实现入参校验Aop
- 使用入参校验Aop
- 演示
- 附
实现入参校验Aop
1.定义一个入参基类
package com.param.validate.aop;
/**
* 基础请求基类
*
* @author: zetting
* @date: 2018/8/22 7:15
*/
public class Request {
}
2.实现入参校验切面
package com.param.validate.aop;
import com.param.validate.base.BusinessCode;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
import javax.annotation.Resource;
import javax.validation.ConstraintViolation;
import javax.validation.groups.Default;
import java.util.Iterator;
import java.util.Set;
/**
* controller 层入参校验切面
*
* @Author zetting
* @Date 2017/11/15 21:50
**/
@Order(2)
@Component
@Aspect
public class ValidatorAspect {
@Resource
private LocalValidatorFactoryBean localValidatorFactoryBean;
public ValidatorAspect() {
}
/**
* 方式1:切入点(
*/
@Pointcut(
"@annotation(org.springframework.web.bind.annotation.RequestMapping)" +
"||@annotation(org.springframework.web.bind.annotation.GetMapping)" +
"||@annotation(org.springframework.web.bind.annotation.PostMapping)" +
"||@annotation(org.springframework.web.bind.annotation.PutMapping)"
)
// @Pointcut("execution(* com.*..controller.*.*(..))")//方式2
private void parameterPointCut() {
}
/**
* 处理
*
* @param joinPoint
* @param request
*/
@Before("parameterPointCut() && args(request,..)")
public void validateParameter(JoinPoint joinPoint, Request request) {
Set<ConstraintViolation<Request>> validErrors = this.localValidatorFactoryBean.validate(request, new Class[]{Default.class});
Iterator iterator = validErrors.iterator();
StringBuilder errorMsg = new StringBuilder();
while (iterator.hasNext()) {
ConstraintViolation constraintViolation = (ConstraintViolation) iterator.next();
String error = constraintViolation.getPropertyPath() + ":" + constraintViolation.getMessage();
errorMsg.append(iterator.hasNext() ? error + "; " : error);
}
if (!validErrors.isEmpty()) {
throw new BusinessException(BusinessCode.PARAM_ILLEGAL, errorMsg.toString());
}
}
}
使用入参校验Aop
1.入参请求类集成基类Request并在相应字段加上校验注解
package com.param.validate.modules.dto;
import com.param.validate.aop.Request;
import org.hibernate.validator.constraints.NotBlank;
import javax.validation.constraints.NotNull;
/**
* 入参校验请求
*
* @author: zetting
* @date: 2018/12/19 22:16
*/
public class ValidateRequest extends Request {
/**
* 用户名
*/
@NotBlank
private String userName;
/**
*性别
*/
@NotNull
private Integer sex;
/**
* 地址
*/
private String address;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public Integer getSex() {
return sex;
}
public void setSex(Integer sex) {
this.sex = sex;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
2.controller层正常使用、无需添加任何东西
package com.param.validate.modules.controller;
import com.param.validate.modules.dto.ValidateRequest;
import com.param.validate.base.Response;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 切面实现入参校验
*/
@RestController
public class MyController {
@GetMapping(value = "/validate")
public Response validate(ValidateRequest request) {
return Response.success();
}
}
演示
1.入参不合法
2.入参合法
附
gitee源码:
https://gitee.com/zetting/my-gather/tree/master/springboot-param-validate
推荐阅读:
springboot入参检验之枚举检验