【发布时间】:2021-12-08 09:46:20
【问题描述】:
根据 VizGhar 的回答“Jackson Generics with variable JsonProperty”,我正在尝试使用 WebClient 来使用 API 响应,其中包含 json 响应中的通用对象:
{
"meta": {
"RID": "abc9f-defgh-hj78k-lkm9n",
"QID": "abc9f-defgh-hj78k-lkm9n" },
"data": {
"Inquiry": {
"multiCurrency": [{"TaxStat": "Y", "TaxAmt": 0}],
"Type": "Tax",
"TaxFreq": {
"weekDay": 0,
"startDay": 0
},
"TaxRegion": "Tx"
}
}
}
“查询”的类型是通用的,即“数据”是通用响应对象的包装,在这种情况下是“查询”,但它可能会改变。
查询.java:
public class Inquiry {
@JsonProperty("multiCurrency")
private List<MultiCurrencyInq> multiCurrency;
@JsonProperty("Type")
private String Type;
@JsonProperty("TaxFreq")
private TaxFreq taxFreq;
@JsonProperty("TaxRegion")
private String TaxRegion;
// Getters Setters Constructors
}
MultiCurrencyInq.java:
public class MultiCurrencyInq {
@JsonProperty("TaxStat")
private String TaxStat;
@JsonProperty("TaxAmt")
private int TaxAmt;
// Getters Setters Constructors
}
TaxFreq.java:
public class TaxFreq {
@JsonProperty("weekDay")
private int weekDay;
@JsonProperty("startDay")
private int startDay;
// Getters Setters Constructors
}
我的 Response.java 看起来像这样:
public class Response<T>{
private Meta meta;
private Data<T> data;
// Getters Setters Constructors
}
元.java:
public class Meta{
private String RID;
private String QID;
// Getters Setters Constructors
}
Data.java:
public class Data<T> {
// property name, that will be changed
@JsonProperty(DataNamingStrategy.DATA_FIELD)
private T data;
// Getters Setters Constructors
}
我的控制器:
@RestController
public class InquiryController {
@Autowired private WebClient webClient;
@GetMapping("/inquiry") public Response<Inquiry> getInquiryApiResponse() {
ResponseEntity<String> response = webClient.get()
.uri("http://my.org.com/clientId/inquiry")
.retrieve()
.toEntity(String.class)
.block();
ObjectMapper mapper = new ObjectMapper();
mapper.setPropertyNamingStrategy(new DataNamingStrategy("Inquiry"));
JavaType type = mapper.getTypeFactory()
.constructParametricType(Response.class, Inquiry.class);
Response<Inquiry> res = mapper.readValue(response.getBody(), type);
return res;
}
}
DataNamingStrategy.java:
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);
}
}
这对我不起作用。没有为 Data.java 中的 @JsonProperty(DataNamingStrategy.DATA_FIELD) 将泛型类型设置为 "Inquiry" 的原因可能是什么
【问题讨论】:
-
我的两分钱:杰克逊图书馆最近发生了变化。这也可能导致此问题。
标签: java json spring-boot jackson