注册
RPC

【墙裂推荐】球球了,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
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

0 个评论

要回复文章请先登录注册