记一次 @Valid校验不生效的问题
表现:
在类字段上加上的@NotNull 与 @Patern的注解校验,用于校验该参数是否符合正则表达式规范。但观察线上数据,发现该校验并未生效。
使用的是Spring framwork 自带的 LocalValidatorFactoryBean 作为校验器
排查流程:
首先,获取该对象的JSON string, 通过http访问请求,发现校验生效。
通过dubeg 调试,获取 valid Context, 发现对应的字段读入了校验的范围内
登录线上服务器,通过telnet dubbo 调用 与 curl 调用发现校验依然生效
百思不得其解,由于线上该接口通过dubbo调用,本机的dubbo调用与http调用皆校验生效
排查dubbo版本,发现均为1.3.1版本
查看dubbo序列化与反序列化
-
发现,通过合作方的调用,其该对象传值被转化为 HashMap 类型
dubbo在反序列化时,会找到对应的类,当期发现consumer写入的类,provider无法找到,会将其转化为HashMap 或 LinkedHashMap
由于provider收到的类为HashMap,而不是原始的对象,因此 导致 @Valid不生效
思考,为什么会传递hashmap对象呢?之前已提供合作方对应的common包了。
排查:
找到调用方的代码,进行调试
-
发现在调用该接口参数时,该对象与Common包内的对象不一致
由于参数为对象内部 持有的List 对象,而List 内的泛型与原先要求的泛型类型不一致。
通过排查,发现在对象转化的使用,使用 BeanUtils.copyProperties方法,该方法只校验了字段name与类型是否一致。发现 字段名一致,字段类型都有List类型,因此将 List<A> list 类型 赋值了原先需要的 List<B> list中,在provider方 找不到 A类型,dubbo 将其转为HashMap