场景:在调用第三方接口时,对方接口可能会新增或者修改一些参数,你这边代码怎么做适配才能把所有参数接收到?@JsonAnyGetter和@JsonAnySetter可以很好解决,在不修改代码的情况下接收新增或者修改的参数。
接收到json字符串
String s = "[{\"s\":\"hah\",\"b\":\"hehe\",\"uuid\":\"uuid\",\"name\":\"213\"}]";
uuid和name是必传的,但是s和b这两个字段可能是变化的扩展字段,我们要怎么在代码里去适配获取这两个字段呢?
使用@JsonAnyGetter和@JsonAnySetter可以完美解决
public class User2Info {
public User2Info(){
}
public User2Info(String uuid, String name){
this.uuid = uuid;
this.name = name;
}
private String uuid;
private String name;
private Map<String,Object> other = new HashMap<>();
public String getUuid() {
return uuid;
}
public void setUuid(String uuid) {
this.uuid = uuid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@JsonAnyGetter
public Map<String, Object> getOther() {
return other;
}
/**
* 没有匹配上的反序列化属性,放到这里
* @param key
* @param value
*/
@JsonAnySetter
public void setOther(String key, Object value) {
this.other.put(key,value);
}
试试看:
public static void main(String[] args){
String s = "[{\"s\":\"hah\",\"b\":\"hehe\",\"uuid\":\"uuid\",\"name\":\"213\"}]";
TypeReference<List<User2Info>> infos = new TypeReference<List<User2Info>>(){};
List<User2Info> user2Infos = JsonUtil.toPojo(s, infos);
String l = JsonUtil.toJson(user2Infos);
System.out.println("json2:"+l);
}
输出:json2:[{“uuid”:“uuid”,“name”:“213”,“b”:“hehe”,“s”:“hah”}]
我们将@JsonAnyGetter去掉试试看
public Map<String, Object> getOther() {
return other;
}
输出:json2:[{“uuid”:“uuid”,“name”:“213”,“other”:{“b”:“hehe”,“s”:“hah”}}]
多了一个other的json对象。
我们看下@JsonAnyGetter用法:
可用于定义非静态的标记注释,无参数方法为“any getter”;访问器获得*一组键/值对,作为包含POJO的一部分进行序列化(类似于展开)以及它具有的常规属性值。这通常是对应的 to“any setter”mutators(参见{@link JsonAnySetter})。注意,带注释的方法的返回类型必须是 { @link java.util.Map })。与{@link JsonAnySetter}一样,只应该注释一个属性附此注释;如果注释了多个方法,则为异常可能被抛出。
我们看下@JsonAnySetter用法:
可用于定义逻辑“任意setter”mutator的标记注释——使用非静态双参数方法(属性的第一个参数名称,第二个值设置)或字段(类型为{@link java.util)。Map}或POJO) -用作“回退”处理程序用于从JSON内容中找到的所有无法识别的属性。类似于{@link javax.xml.bin .annotation. xmlanyelement}在行为;只能用于表示单个属性每类型。如果使用,则从JSON对象值映射所有未映射的键-值对使用mutator添加 。注:2.8版本增加了对字段进行注释的功能;早些时候,只有方法可以被注释。
可以看出@JsonAnyGetter只能用于getter方法,@JsonAnySetter既可以作用于属性,也可以作用于setter方法。
且如果使用了@JsonAnyGetter,getter方法会将map对象里的键值对取出来。