Java 具有变量JsonProperty的Jackson泛型(与泛型一起使用)
我有这样的课:Java 具有变量JsonProperty的Jackson泛型(与泛型一起使用),java,android,generics,jackson,Java,Android,Generics,Jackson,我有这样的课: public class Data<U> { @JsonProperty("difficulties") private U[] data; // ... geter setter constructor } ObjectMapper mapper = new ObjectMapper(); mapper.setPropertyNamingStrategy(new DataNamingStrategy(tableName)); JavaT
public class Data<U> {
@JsonProperty("difficulties")
private U[] data;
// ... geter setter constructor
}
ObjectMapper mapper = new ObjectMapper();
mapper.setPropertyNamingStrategy(new DataNamingStrategy(tableName));
JavaType type = mapper.getTypeFactory().constructParametricType(Response.class, dataClass);
Response<U> u = mapper.readValue(result, type);
公共类数据{
@JsonProperty(“困难”)
私人U[]数据;
//…geter setter构造函数
}
我不想再创建10个类似的类,因为我只需要更改一行代码(在本例中为@JsonProperty(“困难”)。属性值取决于类型。可以在一个类中编写它吗?根据MichałZiober在这里的响应,我可以更改默认字段名值
通过覆盖PropertyName策略:
以下是我收到的JSON示例(简化):
请参见第二行中的差异,其中数据对象包含
或国家(或基于上下文的许多其他名称)
基于JSON响应的响应类:
public class Response<T>{
private String status;
private String error;
private Data<T> data;
// Getters Setters Constructors
}
公共类响应{
私有字符串状态;
私有字符串错误;
私人数据;
//Getters Setters构造函数
}
基于JSON响应的数据类:
public class Data<T> {
// property name, that will be changed
@JsonProperty(DataNamingStrategy.DATA_FIELD)
private T[] data;
// Getters Setters Constructors
}
公共类数据{
//属性名称,该名称将被更改
@JsonProperty(DataNamingStrategy.DATA_字段)
私有T[]数据;
//Getters Setters构造函数
}
这就是命名策略,它将默认值更改为运行时指定的值
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);
}
}
公共类DataNamingStrategy扩展了PropertyNamingStrategy{
//由其他类使用(这将是应更改的默认字段名)
公共静态最终字符串数据\u FIELD=“变量:数据”;
私有字符串字段名;
公共数据命名策略(字符串字段名){
this.fieldName=字段名;
}
//使用此选项可以更改本例中不需要的字段名(格式为“变量”:“值”)
@凌驾
公共字符串名称字段(MapperConfig配置,AnnotatedField字段,
字符串(默认名称){
返回值(defaultName.equals(数据_字段))?
字段名:
super.nameForField(config,field,defaultName);
}
//使用此选项更改setter方法字段名(JSON->格式为“variable”的对象:{})
@凌驾
SetterMethod的公共字符串名称(MapperConfig配置,
AnnotatedMethod方法,字符串defaultName){
返回值(defaultName.equals(数据_字段))?
字段名:
super.nameforgermethod(config、method、defaultName);
}
//使用此选项更改getter方法字段名(Object->JSON,格式为“variable”:{}
//应与“选择方法”的名称相同
@凌驾
公共字符串名称遗忘方法(MapperConfig配置,
AnnotatedMethod方法,字符串defaultName){
返回setterMethod的名称(配置、方法、默认名称);
}
}
用法应如下所示:
public class Data<U> {
@JsonProperty("difficulties")
private U[] data;
// ... geter setter constructor
}
ObjectMapper mapper = new ObjectMapper();
mapper.setPropertyNamingStrategy(new DataNamingStrategy(tableName));
JavaType type = mapper.getTypeFactory().constructParametricType(Response.class, dataClass);
Response<U> u = mapper.readValue(result, type);
ObjectMapper mapper=new ObjectMapper();
setPropertyNamingStrategy(新数据命名策略(tableName));
JavaType type=mapper.getTypeFactory().ConstructParameterType(Response.class,dataClass);
响应u=mapper.readValue(结果,类型);
其中,result
是作为字符串的Json,tableName
是将在Json中使用的字符串,而不是默认值,dataClass
是U
的类(例如defestion.class)
更好地使用属性命名策略
应该是映射
,而不是一个字符串
。但我只需要改变一个特定的值
还可以查看或再次查看您可以使用
@JsonAnyGetter
注释
public class Data<U> {
@JsonIgnore
private U[] data;
@JsonIgnore
private String propertyName;
public Data(String propertyName) {
this.propertyName = propertyName;
}
// ... geter setter
@JsonAnyGetter
public Map<String, Object> any() {
return Collections.singletonMap(propertyName, data);
}
}
公共类数据{
@杰索尼奥雷
私人U[]数据;
@杰索尼奥雷
私有字符串propertyName;
公共数据(字符串propertyName){
this.propertyName=propertyName;
}
//…geter setter
@JsonAnyGetter
公共地图任意(){
返回集合.singletonMap(propertyName,data);
}
}
并按如下方式使用:
Data<Difficulties> difficulties = new Data<>("difficulties");
数据困难=新数据(“困难”);
写你想要的任何东西,而不是“困难”字串。如果需要,请将列表设置为数据通用类而不是对象检查我的答案以了解其他问题:。我认为,
PropertyNamingStrategy
对你的情况应该有帮助。太好了。。。它起作用了。我很高兴听到这个消息,我会写回信的。我在等你的解决办法。也许,这会对其他人有所帮助。