杰克逊泛型与变量JsonProperty(用泛型) [英] Jackson Generics with variable JsonProperty (usage with generics)
问题描述
public class Data< U> {
@JsonProperty(困难)
私人U []数据;
// ... geter setter构造函数
}
我不想创建10个更类似的类,因为我只需要更改一行代码(在这种情况下@JsonProperty(困难))。属性值取决于类型。是否可以在一个类中编写它?
基于MichałZiober在这里我能够改变默认值字段名称通过重写PropertyNamingStrategy值 这些是我收到的JSON示例(简化版): 查看第二行的差异,其中数据对象包含难度 基于JSON响应的响应类: 基于JSON响应的数据类: 这是命名策略,将默认值更改为运行时指定值 使用应该如下所示: 其中 更好地使用 另请参阅 I have class that looks like this: And I don't want to create 10 more similar classes just because I need to change only one line of code (@JsonProperty("difficulties") in this case). The property value depends on Type. Is it possible to write it in one class? Based on response of Jackson - Modify an attribute at runtime without annotation by Michał Ziober here I was able to change default field name values
by overriding PropertyNamingStrategy: These are my received JSON examples (simplified): see the difference in second line where data object contains either difficulties
or countries (or many other names based on context). Response class based on JSON response: Data class based on JSON response: And this is Naming strategy, that changes default value to runtime specified value And usage should look like this: Where Better usage of Also have a look at 这篇关于杰克逊泛型与变量JsonProperty(用泛型)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
:
{status:OK,error:null,data:{
困难:[{value:easy},{ value:medium}]
}}
{status:ok,error:null,data:{
countries :[{code:AT},{code:BE}]
}}
或国家(或许多其他基于上下文的名称)。
public class Response< T> {
private String status;
私有字符串错误;
私人资料< T>数据;
// Getters Setters构造函数
}
public class Data< T> {
//属性名称,将被更改
@JsonProperty(DataNamingStrategy.DATA_FIELD)
private T [] data;
// Getters Setters构造函数
}
public class DataNamingStrategy extends PropertyNamingStrategy {
//由其他类(这将是应该更改的默认字段名称)
public static final String DATA_FIELD =variable:data;
private String fieldName;
public DataNamingStrategy(String fieldName){
this.fieldName = fieldName;
}
//在这种情况下,使用它来改变不需要的字段名称(格式variable:value)
@Override
public String nameForField MapperConfig<?> config,AnnotatedField field,
String defaultName){
return(defaultName.equals(DATA_FIELD))?
fieldName:
super.nameForField(config,field,defaultName);
}
//使用它来更改setter方法字段名称(JSON - >格式为variable的对象:{})
@Override
public String nameForSetterMethod(MapperConfig<?> config,
AnnotatedMethod方法,String defaultName){
return(defaultName.equals(DATA_FIELD))?
fieldName:
super.nameForGetterMethod(config,method,defaultName);
}
//使用它来改变getter方法字段名称(Object - >格式为variable的JSON:{})
//应该和nameForSetterMethod相同
@Override
public String nameForGetterMethod(MapperConfig<?> config,
AnnotatedMethod method,String defaultName){
return nameForSetterMethod(config,method,defaultName);
}
}
ObjectMapper mapper = new ObjectMapper();
mapper.setPropertyNamingStrategy(new DataNamingStrategy(tableName));
JavaType type = mapper.getTypeFactory()。constructParametricType(Response.class,dataClass);
回应< U> u = mapper.readValue(result,type);
result
是Json as String, code> tableName 是将用于JSON而不是默认值的字符串, dataClass
是 U的类(例如Difficulty.class)。
PropertyNamingStrategy
应该是 Map
而不是一个字符串
。但我只需要改变一个特定的值。
PropertyNamingStrategy
文档或在米奇尔齐奥贝的回答 public class Data<U> {
@JsonProperty("difficulties")
private U[] data;
// ... geter setter constructor
}
{"status": "OK","error": null,"data": {
"difficulties": [{"value":"easy"},{"value":"medium"}]
}}
{"status": "ok", "error": null, "data": {
"countries": [{"code": "AT"},{"code": "BE"}]
}}
public class Response<T>{
private String status;
private String error;
private Data<T> data;
// Getters Setters Constructors
}
public class Data<T> {
// property name, that will be changed
@JsonProperty(DataNamingStrategy.DATA_FIELD)
private T[] data;
// Getters Setters Constructors
}
public class DataNamingStrategy extends PropertyNamingStrategy{
// used by other classes (this will be default field name that should be changed)
public static final String DATA_FIELD = "variable:data";
private String fieldName;
public DataNamingStrategy(String fieldName) {
this.fieldName = fieldName;
}
// use this to change field name (format "variable":"value") not needed in my case
@Override
public String nameForField(MapperConfig<?> config, AnnotatedField field,
String defaultName) {
return (defaultName.equals(DATA_FIELD))?
fieldName :
super.nameForField(config, field, defaultName);
}
// use this to change setter method field name (JSON -> Object with format "variable":{})
@Override
public String nameForSetterMethod(MapperConfig<?> config,
AnnotatedMethod method, String defaultName) {
return (defaultName.equals(DATA_FIELD))?
fieldName :
super.nameForGetterMethod(config, method, defaultName);
}
// use this to change getter method field name (Object -> JSON with format "variable":{})
// should be same as nameForSetterMethod
@Override
public String nameForGetterMethod(MapperConfig<?> config,
AnnotatedMethod method, String defaultName) {
return nameForSetterMethod(config, method, defaultName);
}
}
ObjectMapper mapper = new ObjectMapper();
mapper.setPropertyNamingStrategy(new DataNamingStrategy(tableName));
JavaType type = mapper.getTypeFactory().constructParametricType(Response.class, dataClass);
Response<U> u = mapper.readValue(result, type);
result
is Json as String, tableName
is String that will be used in JSON instead of default value and dataClass
is class for U
(for example Difficulty.class).PropertyNamingStrategy
should be Map
instead of one String
. But I just needed to change one particular value.PropertyNamingStrategy
documentation or again at Michał Ziober's answer