具有可变JsonProperty的Jackson Generics(使用generics)
我的课程看起来像这样:
public class Data { @JsonProperty("difficulties") private U[] data; // ... geter setter constructor }
而且我不想再创建10个类似的类,因为我只需要更改一行代码(在这种情况下为@JsonProperty(“困难”))。 属性值取决于Type。 有可能把它写在一个class级吗?
基于Jackson的响应- 在运行时修改属性而没有 MichałZiober的注释 ,我可以通过覆盖PropertyNamingStrategy来更改默认字段名称值:
这些是我收到的JSON示例(简化):
{"status": "OK","error": null,"data": { "difficulties": [{"value":"easy"},{"value":"medium"}] }} {"status": "ok", "error": null, "data": { "countries": [{"code": "AT"},{"code": "BE"}] }}
查看数据对象包含困难或国家(或许多其他基于上下文的名称)的第二行的差异。
基于JSON响应的响应类:
public class Response{ private String status; private String error; private Data data; // Getters Setters Constructors }
基于JSON响应的数据类:
public class Data { // 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 = mapper.readValue(result, type);
result
是Json为String, tableName
是将在JSON中使用的String而不是默认值,而dataClass
是U
类(例如Difficulty.class)。
更好地使用PropertyNamingStrategy
应该是Map
而不是一个String
。 但我只需要改变一个特定的值。
另请参阅 PropertyNamingStrategy
文档或再次查看MichałZiober的答案
您可以使用@JsonAnyGetter
注释。
public class Data { @JsonIgnore private U[] data; @JsonIgnore private String propertyName; public Data(String propertyName) { this.propertyName = propertyName; } // ... geter setter @JsonAnyGetter public Map any() { return Collections.singletonMap(propertyName, data); } }
并使用如下:
Data difficulties = new Data<>("difficulties");
写任何你想要的而不是“困难”字符串。 如果需要,将列表设置为Datagenerics类而不是Difficulties对象