前言
在日常开发中,会有些字段经常发生变化的类,但是每次都要修改数据传输类,例如前端需要额外新增一个 参数响应,或者业务上需要调整某些动态的字段等等,那如何解决此类问题呢。
Example
定义了一个用户的实体类User,类中只有 id、name 两个字段:
@Data
public class User {
private String id;
private String name;
}
但是在业务上,用户可以根据需要添加一些自定义属性,比如age、address等,因为业务不确定,所以我们也没办法提前在类中定义这些属性。
那么处理方式也简单,如下所示。
@Data
public class User {
private String id;
private String name;
// 扩展字段
private Map<String, String> extFields = Maps.newHashMap();
}
序列化后,如下所示。
{
"id": "100001",
"name": "小明",
"extFields": {
"address": "浙江省杭州市",
"age": "22"
}
}
可以看到自定义的字段都是在extFields中,但是你可能想要的是如下结构:
{
"id": "100001",
"name": "小明",
"address": "浙江省杭州市",
"age": "22"
}
@JsonAnyGetter & @JsonAnySetter
- JsonAnyGetter:在getter方法上使用,此方法返回一个map对象,序列化的时候,此map所有的键值对,都会与对象的成员变量同级。
- JsonAnySetter:在setter方法上使用,此方法为键值对,反序列化的时候,所有不包含在此对象中的未知属性,都会调用此方法进行设置。
使用方法如下所示。
public class User {
private String id;
private String name;
// 扩展字段
private Map<String, String> extFields = Maps.newHashMap();
@JsonAnyGetter
public Map<String, String> getExtFields() {
return extFields;
}
@JsonAnySetter
public void setExtFields(String key, String value) {
this.extFields.put(key, value);
}
}
需要注意的是setExtFields方法的参数,不能直接传递extFields字段,因为传过来的Json中很可能是没有这个字段的,所以可以提供两个参数key和value,反序列化时,@JsonAnySetter会自动把自定义的属性添加到extFields字段中。详见:Jackson @JsonAnyGetter and @JsonAnySetter Example