号外号外:麻烦点击左侧
我正在参加博客之星评选,请您投票
,给个五星好评,谢谢大家了!!!
写在前面
本文在这篇文章 基础上改造进行测试。
dubbo的参数验证基于JSR303规范
就是定义了校验注解,错误信息如何提示等的规范
,我们只需要使用规定的注解,并声明Filter就可以了。
源码。
1:改造rpc-service-api
1.1:引入依赖
<dependencies>
<!-- 参数校验相关依赖 -->
<!-- JSR303参数校验相关对应规范API -->
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
<!-- JSR 参数校验规范实现,我们使用 hibernate-validator,注意:仅仅是个实现,不要被hibernate关键字干扰了,即不操作数据库!!! -->
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.18.Final</version>
</dependency>
<!-- 可能涉及到 EL 表达,所以引入,否则 hibernate-validator 在初始化会报错 -->
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.el</artifactId>
<version>3.0.1-b11</version>
</dependency>
</dependencies>
1.2:UserAddDTO
public class UserAddDTO implements Serializable {
/**
* 昵称
*/
@NotEmpty(message = "昵称不能为空")
@Length(min = 5, max = 16, message = "账号长度为 5-16 位")
private String name;
/**
* 性别
*/
@NotNull(message = "性别不能为空")
private Integer gender;
// getter setter tostring
}
1.3:UserRpcService
public interface UserRpcService {
/**
* 根据指定用户编号,获得用户信息
*
* @param id 用户编号
* @return 用户信息
*/
UserDTO get(@NotNull(message = "用户编号不能为空") Integer id)
throws ConstraintViolationException;
/**
* 添加新用户,返回新添加的用户编号
*
* @param addDTO 添加的用户信息
* @return 用户编号
*/
Integer add(UserAddDTO addDTO)
throws ConstraintViolationException;
}
注意在方法中抛出ConstraintViolationException
的原因是参数校验不通过时会抛出该异常,所以这里抛出提供给用户查看错误信息。
2:改造rpc-service-provider
2.1:UserRpcServiceImpl
@Service
public class UserRpcServiceImpl implements UserRpcService {
@Override
public UserDTO get(Integer id) {
/*return new UserDTO().setId(id)
.setName("没有昵称:" + id)
.setGender(id % 2 + 1); // 1 - 男;2 - 女*/
UserDTO userDTO = new UserDTO();
userDTO.setId(id);
userDTO.setName("没有昵称:" + id);
userDTO.setGender(id % 2 + 1);
return userDTO;
}
@Override
public Integer add(UserAddDTO addDTO) {
return (int) (System.currentTimeMillis() / 1000); // 嘿嘿,随便返回一个 id
}
}
2.2:dubbo.xml
<!-- 服务提供者暴露服务配置 -->
<dubbo:service ref="userRpcServiceImpl" interface="dongshi.daddy.api.UserRpcService"
version="${dubbo.provider.UserRpcService.version}" validation="true"/>
增加了validation="true"
开启服务提供者端的参数校验,如果是参数校验不通过则抛出ConstraintViolationException
。
可以通过在application.yml中配置
dubbo.provider.validation = true
开启服务提供者所有service的参数校验。
3:改造rpc-service-consumer
3.1:dubbo.xml
<!-- 服务消费者引用服务配置 -->
<dubbo:reference id="userService" interface="dongshi.daddy.api.UserRpcService"
version="${dubbo.consumer.UserRpcService.version}" validation="true"/>
通过validation="true"
开启服务消费者的参数校验。
3.2:触发异常执行类
@Component
public class UserRpcServiceTest02 implements CommandLineRunner {
private final Logger logger = LoggerFactory.getLogger(getClass());
@Resource
private UserRpcService userRpcService;
@Override
public void run(String... args) throws Exception {
// 获得用户
try {
// 发起调用
UserDTO user = userRpcService.get(null); // 故意传入空的编号,为了校验编号不通过
logger.info("[run][发起一次 Dubbo RPC 请求,获得用户为({})]", user);
} catch (Exception e) {
logger.error("[run][获得用户发生异常,信息为:[{}]", e.getMessage());
}
// 添加用户
try {
// 创建 UserAddDTO
UserAddDTO addDTO = new UserAddDTO();
// 故意把名字打的特别长,为了校验名字不通过
addDTO.setName("dongshidaddydongshidaddydongshidaddydongshidaddy");
// 不传递性别,为了校验性别不通过
addDTO.setGender(null);
// 发起调用
userRpcService.add(addDTO);
logger.info("[run][发起一次 Dubbo RPC 请求,添加用户为({})]", addDTO);
} catch (Exception e) {
logger.error("[run][添加用户发生异常,信息为:[{}]", e.getMessage());
}
}
}
3.3:执行
如下红框中是错误执行触发的异常信息,蓝色框是正常的调用: