前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >一个奇怪的ConstraintViolationException

一个奇怪的ConstraintViolationException

作者头像
烟雨平生
发布2023-03-07 14:12:15
3680
发布2023-03-07 14:12:15
举报
文章被收录于专栏:数字化之路数字化之路

缘起

联调时,前端同学说接口报500了。。。

到PINPOINT上看了下,只有一个ConstraintViolationException null

一下子也没搞明白问题在哪

这是个老接口,本次需求也没有涉及这个点。

感觉凭空飞来一口锅。。。

追查

拿PINPOINT上报错请求的TransactionId 去ELK上查了下,只看到一个null。 说明:调用栈因为换行在ELK中查不到,好烦

继续

没有办法,只能登陆k8s,从容器日志中找找:

日志是找到了。

从执行栈的package上看,的确是与业务代码没有关系。

10分钟过去。。。

复现

从日志中拿到请求的数据,使用Postman调API。

稳稳复现

本地Debug

在Debug模式下,启动本地服务,准备Debug

打断点时,发现这个老接口有一些地方很奇怪:

  • 接口的入口处,没有做参数的常规校验

看报错日志中有validation及异常ConstraintViolationException,隐隐觉得与参数校验有关。

在想,如果在接口的入口处把数据校验做了,不就好了?!

先定位问题,再确定fix方案

在本地swagger中发起请求。

执行到日志中看到的业务代码

代码语言:javascript
复制
User user = userPersonAccountService.userRegister(userPersonInfo);

时,按F7【step into】。

果然没有走到service层的userRegister方法中,而是跑到这个地方,

如图所示:

继续debug。。。

一路debug下来,终于找到关键所在。

如下图所示:

可以看到,这部分逻辑的确是做数据校验,校验结果也与期望的相同。

但日志为什么只是个null呢?

继续Debug。。。

参数校验的结果也拿到了,但没有赋值给ConstraintViolationException的message属性。

原来如此!

Spring参数校验中validation-api的作用,进门左手边有篇文章有讲到: 一个奇怪的HV000030: No validator could be found for constraint

validation-api 1.x,对应hibernate-validator 5.x validation-api 2.x,对应hibernate-validator 6.x

升级下版本?

spring 5.x仍是

throw new ConstraintViolationException(result);

无效!

点进去看下,message的值不再是Hard code的null,而是前面校验的结果。

看来升级validation-api版本,有戏!

在项目的pom.xml中添加validation-api 2.x的依赖,并且exclusion掉validation-api 1.x【一定要做】:

代码语言:javascript
复制
<exclusions>
    <exclusion>
        <artifactId>validation-api</artifactId>
        <groupId>javax.validation</groupId>
    </exclusion>
    <exclusion>
        <artifactId>hibernate-validator</artifactId>
        <groupId>org.hibernate</groupId>
    </exclusion>
</exclusions>

work!

至此,未通过校验日志只打印了null的问题解决。 但不完美:返回的message除了期望的提示信息外,还有别的噪音。

调整参数校验的位置

在API入口进行校验。这也是改动最小的。

如下图所示,在需要校验的入参前增加@Validated或@Valid注解:

至此,问题解决。

前端传的参数没有通过校验导致。

问题是个小问题,但从发现到排查结束花了1个多小时!

小结: (1)validation-api 1.x时,Spring的方法级别的数据校验,校验结果会丢失

(2)接口的参数校验尽量前置

(3)推荐使用Spring MVC的参数校验,因为比较合适

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-03-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 的数字化之路 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档