Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/234.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 具有变量JsonProperty的Jackson泛型(与泛型一起使用)_Java_Android_Generics_Jackson - Fatal编程技术网

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
对你的情况应该有帮助。太好了。。。它起作用了。我很高兴听到这个消息,我会写回信的。我在等你的解决办法。也许,这会对其他人有所帮助。