毕业三年连fastjson都不会用,没错就是我自己。
场景描述:工作当中遇得一个历史遗留的问题。问题是读取xml文件,xml中的一个属性值没有保存到数据库中。主要的代码逻辑读取xml,转成json,然后再调用JSON.parseObject转成java类包存到数据中(反序列化)。同时还保存一份json字符串的数据再数据库中,后面查询也是查的json字符串,
解决思路:首先我不想出脚本修改原有的数据库字段,想找一个改动代码最小的方式,于是就想到了修改实体类,以及mapper中的属性映射,利用序列化时候会根据get方法生成key的特点实现属性名称的转换保存到数据中的json串中。
//修改前的代码
//最初的实体和数据是name字段,但是xml中是xm字段
@Column(name = "NAME")
private String name;
修改后的代码
@Collumn(name="NAME")
private String xm;
//保留原来的name 的get方法,这样其他类中也能调用以前方法也不会报错,并且序列化时候还能把name值序列化出来。
private String getName(){
returen xm;
}
最后测试发现,数据是报存上了,但是页面上还是没有展示这个字段(怀疑还是因为反序列化的原因),最后就还是把数据库字段也统一改了,先把问题给解决了。这是我就发现了我用了三年的fastjson,居然只知道parseObject,toJSON两个方法,下班后就决定跟一下业务代码,和fastjson的基本原理。
先说为什么我页面上还是没有展示这个字段的问题,跟了代码之后发现后端接口取值之后用了反射去取属性名称和值,发现他还是用了以前的name成员变量。name成员变量已经被我删了,自然也去取不到值了。
之后问题之后,又跟了一下fastjson的源码和基本用法,这里简述一下我看到的东西以及我又是如何修改的这个问题。
1.JOSN.toJSON的方法,是根据getter方法去获取json的key的,而不是反射获取java对象的成员变量
List<FieldInfo> getters = TypeUtils.computeGetters(clazz, null);
JSONObject json = new JSONObject(getters.size());
for (FieldInfo field : getters) {
Object value = field.get(javaObject);
Object jsonValue = toJSON(value);
json.put(field.getName(), jsonValue);
}
return json;
2.JSONField注解的用法
@Target({ ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER })
public @interface JSONField {
/**
* config encode/decode ordinal
* @since 1.1.42
* @return
*/
int ordinal() default 0;
//序列化、反序列化字段名称
String name() default "";
//序列化指定格式
String format() default "";
//默认参与序列化
boolean serialize() default true;
//m默认参与反序列化
boolean deserialize() default true;
SerializerFeature[] serialzeFeatures() default {};
Feature[] parseFeatures() default {};
}