【墙裂推荐】球球了,RPC之间调用别再使用 if-else做参数校验了
RPC调用时使用 @Validated进行参数校验不起作用
球球了,RPC之间调用别再使用 if-else做参数校验了。众所周知,@Validated 是一款非常好用的参数校验工具。但在RPC调用时不可用,在当前的微服务大环境下,微服务之间的调用怎么做到优雅的参数校验呢?
话不多说,直接上干货
引包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
1. 参数校验 这里我们先要定义一个注解来代替来继承 @Validated
import org.springframework.validation.annotation.Validated;
@Validated
public @interface RPCValidated {
}
2. 然后使用AOP来解析参数,进行参数校验。
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.hibernate.validator.messageinterpolation.ResourceBundleMessageInterpolator;
import org.hibernate.validator.resourceloading.PlatformResourceBundleLocator;
import org.springframework.stereotype.Component;
import wangjubao.base.common.extend.Response;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
@Aspect
@Component
@Slf4j
public class ValidatedAop {
private static Validator validator;
static {
validator = Validation.byDefaultProvider().configure()
.messageInterpolator(new ResourceBundleMessageInterpolator(
new PlatformResourceBundleLocator("validationMessages")))
.buildValidatorFactory().getValidator();
}
@Around("@annotation(com.qiaoba.annotation.RPCValidated))")
public Object around(ProceedingJoinPoint joinPoint) {
Object[] args = joinPoint.getArgs();
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
// 执行方法参数的校验
Set<ConstraintViolation<Object>> constraintViolations = validator.forExecutables().validateParameters(joinPoint.getThis(), signature.getMethod(), args);
List<String> messages = new ArrayList<>();
for (ConstraintViolation<Object> error : constraintViolations) {
messages.add(error.getMessage());
}
if (!messages.isEmpty()) {
return Response.paramError("参数错误:", messages.get(0));
}
try {
return joinPoint.proceed(args);
} catch (Throwable e) {
e.printStackTrace();
return Response.error("操作失败:", e.getMessage());
}
}
}
3. 使用方法,在接口Impl实现类加上定义的@RPCValidated
@Override
@RPCValidated
public Response create(MessageSmsRechargeDto dto) {
//todo:业务逻辑......
}
4. 在Interfaces接口层加上@Valid注解
Response create(@Valid MessageSmsRechargeDto params);
5. 实体类
@Data
public class MessageSmsRechargeDto implements Serializable {
/**
* 充值公司
*/
@NotNull(message = "充值公司不能为空 ")
private Long companyId;
/**
* 充值备注
*/
@NotEmpty(message = "充值备注不能为空 ")
private String rechargeRemark;
}
--- 至此,整个流程完成,加上自定义的参数校验注解@RPCValidated后,就可以优雅的进行参数校验,不用再写各种if-else 做参数校验了
作者:乔巴21121
链接:https://juejin.cn/post/7040683548604366885
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。