在 Spring 中使用 postForEntity 时,错误的 POST 正文 JSON 序列化
Wrong POST body JSON serialization when using postForEntity in Spring
我正在尝试通过 Spring 中的 POST 正文将对象 EGiftCreationRequest
的实例作为 JSON 发送:
final BigDecimal amount = new BigDecimal(100.00);
final String configurationId = "test_configuration_id";
final String referenceNumber = "12345";
EGiftCreationRequest giftCreationRequest = new EGiftCreationRequest() {{
giftAmount(amount);
productConfigurationId(configurationId);
retrievalReferenceNumber(referenceNumber);
}};
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<EGiftCreationRequest> httpEntity = new HttpEntity<EGiftCreationRequest>(giftCreationRequest, headers);
ResponseEntity<EGift> entity = new TestRestTemplate().postForEntity(
"http://localhost:" + this.port + "/eGiftProcessing/v1/generateEGift",
httpEntity,
EGift.class
);
但是,由于某种原因,该对象被序列化为以下字符串:
{"headerParams":{}}
显然这与我的EGiftCreationRequest
无关,实际上是:
public class EGiftCreationRequest extends RequestBase<EGiftCreationRequest> {
private BigDecimal giftAmount;
private String productConfigurationId;
private String retrievalReferenceNumber;
public BigDecimal giftAmount() {
return this.giftAmount;
}
public String productConfigurationId() {
return this.productConfigurationId;
}
public String retrievalReferenceNumber() {
return this.retrievalReferenceNumber;
}
public EGiftCreationRequest giftAmount(final BigDecimal giftAmount) {
this.giftAmount = giftAmount;
return this;
}
public EGiftCreationRequest productConfigurationId(final String productConfigurationId) {
this.productConfigurationId = productConfigurationId;
return this;
}
public EGiftCreationRequest retrievalReferenceNumber(final String retrievalReferenceNumber) {
this.retrievalReferenceNumber = retrievalReferenceNumber;
return this;
}
}
可能发生了什么?
这是由错误配置的 Jackson 映射器引起的。默认情况下,Jackson 正在寻找以 JavaBeans 方式命名的访问器 (get*(), set*()) 来检索和设置值。由于模型使用不同的命名约定(字段名称本身),Jackson 无法序列化对象。
以下映射器配置使一切正常工作:
ObjectMapper mapper = new ObjectMapper();
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
mapper.setVisibility(PropertyAccessor.GETTER, JsonAutoDetect.Visibility.NONE);
mapper.setVisibility(PropertyAccessor.SETTER, JsonAutoDetect.Visibility.NONE);
mapper.setVisibility(PropertyAccessor.CREATOR, JsonAutoDetect.Visibility.NONE);
TestRestTemplate testRestTemplate = new TestRestTemplate();
List<HttpMessageConverter<?>> messageConverters = new ArrayList<HttpMessageConverter<?>>();
messageConverters.add(new MappingJackson2HttpMessageConverter(mapper));
testRestTemplate.setMessageConverters(messageConverters);
我正在尝试通过 Spring 中的 POST 正文将对象 EGiftCreationRequest
的实例作为 JSON 发送:
final BigDecimal amount = new BigDecimal(100.00);
final String configurationId = "test_configuration_id";
final String referenceNumber = "12345";
EGiftCreationRequest giftCreationRequest = new EGiftCreationRequest() {{
giftAmount(amount);
productConfigurationId(configurationId);
retrievalReferenceNumber(referenceNumber);
}};
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<EGiftCreationRequest> httpEntity = new HttpEntity<EGiftCreationRequest>(giftCreationRequest, headers);
ResponseEntity<EGift> entity = new TestRestTemplate().postForEntity(
"http://localhost:" + this.port + "/eGiftProcessing/v1/generateEGift",
httpEntity,
EGift.class
);
但是,由于某种原因,该对象被序列化为以下字符串:
{"headerParams":{}}
显然这与我的EGiftCreationRequest
无关,实际上是:
public class EGiftCreationRequest extends RequestBase<EGiftCreationRequest> {
private BigDecimal giftAmount;
private String productConfigurationId;
private String retrievalReferenceNumber;
public BigDecimal giftAmount() {
return this.giftAmount;
}
public String productConfigurationId() {
return this.productConfigurationId;
}
public String retrievalReferenceNumber() {
return this.retrievalReferenceNumber;
}
public EGiftCreationRequest giftAmount(final BigDecimal giftAmount) {
this.giftAmount = giftAmount;
return this;
}
public EGiftCreationRequest productConfigurationId(final String productConfigurationId) {
this.productConfigurationId = productConfigurationId;
return this;
}
public EGiftCreationRequest retrievalReferenceNumber(final String retrievalReferenceNumber) {
this.retrievalReferenceNumber = retrievalReferenceNumber;
return this;
}
}
可能发生了什么?
这是由错误配置的 Jackson 映射器引起的。默认情况下,Jackson 正在寻找以 JavaBeans 方式命名的访问器 (get*(), set*()) 来检索和设置值。由于模型使用不同的命名约定(字段名称本身),Jackson 无法序列化对象。
以下映射器配置使一切正常工作:
ObjectMapper mapper = new ObjectMapper();
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
mapper.setVisibility(PropertyAccessor.GETTER, JsonAutoDetect.Visibility.NONE);
mapper.setVisibility(PropertyAccessor.SETTER, JsonAutoDetect.Visibility.NONE);
mapper.setVisibility(PropertyAccessor.CREATOR, JsonAutoDetect.Visibility.NONE);
TestRestTemplate testRestTemplate = new TestRestTemplate();
List<HttpMessageConverter<?>> messageConverters = new ArrayList<HttpMessageConverter<?>>();
messageConverters.add(new MappingJackson2HttpMessageConverter(mapper));
testRestTemplate.setMessageConverters(messageConverters);