普通web请求可以通过 javax.validation.constraints package下的注解进行参数校验,校验的结果会被Spring Mvc包装处理返回到前端,那么rpc调用如何通过注解进行参数校验呢?
查找资料发现可以通过 hibernate validator 进行参数校验,对校验结果进行自定义处理展示。
导入pom依赖
<!-- hibernate validator -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.13.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.13.Final</version>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
provider 提供的facade接口
/**
* 更新库存
*
* @param businessStockMessageDTO businessStockMessageDTO
* @return RpcBaseResponse
*/
RpcBaseResponse<String> updateStock(BusinessStockMessageDTO businessStockMessageDTO);
对 provider 的参数进行注解校验(注解同样是javax.validation.constraints包下的)
// BusinessStockMessageDTO 类的部分参数
private static final long serialVersionUID = 1L;
/**
* xxx id
*/
@NotNull(message = "entityId 不能为空")
@Min(value = 1, message = "entityId 不能小于1")
private Long entityId;
/**
* xxx 类型(仓库/供应商/酒店)
*/
@EnumValue(enumClass = EntityTypeEnum.class, message = "非法 entityType")
private String entityType;
/**
* xxx 来源
*/
@NotBlank(message = "source 不能为空")
private String source;
在facade接口实现进行参数校验
@Override
public RpcBaseResponse<String> updateStock(BusinessStockMessageDTO businessStockMessageDTO) {
log.info("[BusinessStockMessageBizServiceImpl.updateStock] businessStockMessageDTO:{}", JSON.toJSONString(businessStockMessageDTO));
String validate = ValidationUtils.validate(businessStockMessageDTO);
if (StringUtils.isNotBlank(validate)) {
// 有参数校验错误
return RpcBaseResponse.fail(RpcResponseEnum.INVALID_PARAMETER_VALUE, validate);
}
// TODO: ...
}
校验工具类[ValidationUtils]的实现
package com.oyo.inventory.common.utils;
import com.google.common.collect.Lists;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.hibernate.validator.HibernateValidator;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import java.util.List;
import java.util.Set;
/**
* @author kermit.liu on 2018/3/15
*/
public class ValidationUtils {
/**
* 使用hibernate的注解来进行验证
*/
private static Validator validator = Validation.byProvider(HibernateValidator.class)
.configure().failFast(true).buildValidatorFactory().getValidator();
/**
* 功能描述: <br>
* 〈注解验证参数〉
*
* @param obj obj
*/
public static <T> String validate(T obj) {
Set<ConstraintViolation<T>> constraintViolations = validator.validate(obj);
// 检验不合格处理
if (CollectionUtils.isNotEmpty(constraintViolations)) {
List<String> tipList = Lists.newArrayList();
constraintViolations.forEach(constraintViolationImpl -> tipList.add(constraintViolationImpl.getMessage()));
return StringUtils.join(tipList, ",");
} else {
return "";
}
}
}
结果
consumer 调用接口传入的参数若不满足参数要求,上面工具类会返回参数校验注解中的 message 信息。