fastjson
fastjson copied to clipboard
JSON序列化丢掉了JavaBean里带下划线前缀带属性名称的下划线前缀
` package com.ebanma.cloud.poi_search;
import static org.junit.Assert.*;
import java.util.HashMap;
import org.junit.Test;
import com.alibaba.fastjson.JSON;
import lombok.Data; import lombok.EqualsAndHashCode; import lombok.extern.slf4j.Slf4j;
@Data class Bean { String _name = "hello"; }
@Data @EqualsAndHashCode(callSuper = false) class Bean2 extends HashMap<String, Object> { /** * */ private static final long serialVersionUID = -3294517155381419370L;
public Bean2() {
super.put("_name", "hello");
}
}
@Slf4j public class FastjsonSerializeTest {
@Test
public void test() {
Bean bean = new Bean();
String json1 = JSON.toJSONString(bean);
log.info("json1="+json1);
Bean2 bean2 = new Bean2();
String json2 = JSON.toJSONString(bean2);
log.info("json2="+json2);
assert json1.equals(json2);
}
} `
大致看了一下里面特意去掉了前缀下划线,不知道为啥,应该不是bug,只是大致看了一下,没做深入测试
又看了一下fastjson是根据get方法确定属性名的,这里你用了lombok会生成一个get_name方法,他会把下划线去掉应该是为了兼容以前的命名方式,如果你手动把get_name改成getOther就会生成other的key值,规则就是去掉get然后把首字母小写,正宗方式应该用JSONField注解。此为非bug,是你的使用方式不对。
参考 #3549,关闭FieldSmartMatch功能即可精准匹配字段
参考 #3549,关闭FieldSmartMatch功能即可精准匹配字段
#3549的问题是反序列化的时候的操作,楼主的问题是序列化的时候,所以关闭FieldSmartMatch对序列化不起作用
我去翻看了下1.2.60版本 fastjson中JSON.toJSONString的源码,发现TypeUtils中computeGetters方法的逻辑如下图
如果属性名是以_开头则从get方法的第四位开始截取,
作为对比,我又去翻了高版本1.2.83版本的fastjson源码,发现其中做了修改,改成了从第三位开始截取,这样就不会丢失属性开头的_了
至于解决办法可以在字段上增加JSONField注解,因为源码中会优先判断有没有JSONField注解有的话使用注解中配置的name,没有则调用get方法,当然升级一下fastjson版本也可以,但是不确定从哪个版本开始fastjson在序列化的时候做了这个逻辑修改。