涉及的类:com.alibaba.fastjson.util.TypeUtils.fnv1a_64_lower()
问题描述:升级fastjson版本号后对含_的key无法正常反序列化
比如我有一个如下的类:
class Person {
@JSONField(name="person_name")
private String personName;
public String getPersonName() {
return personName;
}
public void setPersonName(String personName) {
this.personName = personName;
}
}
进行如下反序列化时:
Person a = JsonUtil.fromJson("{\"person_name\":\"zhoudapeng\"}",Person.class);
Person b = JsonUtil.fromJson("{\"personName\":\"zhoudapeng\"}",Person.class);
结果如下
版本 | a的personName | b的personName |
---|---|---|
1.2.70 | zhoudapeng | zhoudapeng |
1.2.76 | zhoudapeng | null |
问题分析
fastjson有智能匹配的功能,推测是此处逻辑有改动导致的
源码分析
老版本实现:
public static long fnv1a_64_lower(String key){
long hashCode = 0xcbf29ce484222325L;
for(int i = 0; i < key.length(); ++i){
char ch = key.charAt(i);
// 老版本遇到_和-会直接跳过,所以json字符串里即使key里面含有下划线或者-也能正常反序列化成驼峰,比如 {"a_b":"xxx"} 的字符串反序列化时可用 ab,aB来接
if(ch == '_' || ch == '-'){
continue;
}
if(ch >= 'A' && ch <= 'Z'){
ch = (char) (ch + 32);
}
hashCode ^= ch;
hashCode *= 0x100000001b3L;
}
return hashCode;
}
新版本实现:
public static long fnv1a_64_lower(String key){
long hashCode = 0xcbf29ce484222325L;
for(int i = 0; i < key.length(); ++i){
char ch = key.charAt(i);
<font color='red'>// 新版本对-和_的特殊处理被取消了</font>
if(ch >= 'A' && ch <= 'Z'){
ch = (char) (ch + 32);
}
hashCode ^= ch;
hashCode *= 0x100000001b3L;
}
return hashCode;
}
4条答案
按热度按时间oyxsuwqo1#
我觉得这个问题是之前版本实现的BUG,如果规定了name字段,就得用name字段来进行匹配,不能加入蛇形命名和驼峰命名的转换,所以新版本的行为才是正确的,老版本的行为不正确。 @zhoudapeng
332nm8kg2#
我觉得这个问题是之前版本实现的BUG,如果规定了name字段,就得用name字段来进行匹配,不能加入蛇形命名和驼峰命名的转换,所以新版本的行为才是正确的,老版本的行为不正确。 @zhoudapeng
可以这样解释,但是这样升级的话可能会导致不兼容,既然是不兼容升级的话我觉得有必要改下大版本号,同时需要给出可能不兼容的点,否则的话从开发者看来的话是个小版本升级,大概率会直接升级版本号,然后就会遇到这类问题
fnx2tebb3#
我觉得这个问题是之前版本实现的BUG,如果规定了name字段,就得用name字段来进行匹配,不能加入蛇形命名和驼峰命名的转换,所以新版本的行为才是正确的,老版本的行为不正确。 @zhoudapeng
可以这样解释,但是这样升级的话可能会导致不兼容,既然是不兼容升级的话我觉得有必要改下大版本号,同时需要给出可能不兼容的点,否则的话从开发者看来的话是个小版本升级,大概率会直接升级版本号,然后就会遇到这类问题
确实,这个需要作者在更新时候进行一个版本更新文档说明,否则对于开发者来说确实整个系统就得重写,ps: 选择jackson或者gson吧
7uhlpewt4#
碰到这个bug了,人都傻了