JSON Spring 集成中的映射错误
JSON mapping error in Spring integration
我已经配置了一个入站 HTTP 网关,它接受 POST 个请求 (JSON) 并为 return 一个 JSON 响应做作业,请求和响应负载是同一个POJO。
我为 Json 转换器创建了如下 bean
@Bean
public Jackson2ObjectMapperBuilder jacksonBuilder() {
Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
builder.indentOutput(true);
return builder;
}
@Bean
public List<HttpMessageConverter<?>> getConverters(){
List<HttpMessageConverter<?>> converters = new ArrayList<HttpMessageConverter<?>>();
converters.add(new MappingJackson2HttpMessageConverter(jacksonBuilder().build()));
return converters;
}
然后我将它们连接到相同 Java 配置 class 中的网关定义,代码段如下:
@Bean
public HttpRequestHandlingMessagingGateway gateway(){
HttpRequestHandlingMessagingGateway gateway = new HttpRequestHandlingMessagingGateway(true);
RequestMapping requestMapping = new RequestMapping();
requestMapping.setMethods(HttpMethod.POST);
requestMapping.setPathPatterns("/appliance/v1/status");
requestMapping.setConsumes("application/json");
requestMapping.setProduces("application/json");
gateway.setRequestMapping(requestMapping);
gateway.setRequestChannel(requestChannel());
gateway.setReplyChannel(replyChannel());
gateway.setMessageConverters(getConverters());
return gateway;
}
我打算转换的 POJO 非常简单
public class ApplianceStatus {
private String gatewayId;
private String applianceId;
private boolean running;
public String getGatewayId() {
return gatewayId;
}
public void setGatewayId(String gatewayId) {
this.gatewayId = gatewayId;
}
public String getApplianceId() {
return applianceId;
}
public void setApplianceId(String applianceId) {
this.applianceId = applianceId;
}
public boolean isRunning() {
return running;
}
public void setRunning(boolean running) {
this.running = running;
}
}
然而 POST 请求 Content-Type header 设置为 application/json returns 400,我发送的 JSON 是
{
"gatewayId": 1,
"applianceId": 123,
"running": false
}
我收到回复
{
"timestamp" : 1434615561240,
"status" : 400,
"error" : "Bad Request",
"exception" : "org.springframework.http.converter.HttpMessageNotReadableException",
"message" : "Bad Request",
"path" : "/appliance/v1/status"
}
并在日志中
2015-06-18 14:55:30.501 DEBUG 3447 --- [tp1023996917-22] .w.s.m.a.ResponseStatusExceptionResolver : Resolving exception from handler [gateway]: org.springframework.http.converter.HttpMessageNotReadableException: Could not read JSON: Can not deserialize instance of byte[] out of START_OBJECT token
at [Source: HttpInputOverHTTP@55c2d2c5; line: 1, column: 1]; nested exception is com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of byte[] out of START_OBJECT token
at [Source: HttpInputOverHTTP@55c2d2c5; line: 1, column: 1]
2015-06-18 14:55:30.501 DEBUG 3447 --- [tp1023996917-22] .w.s.m.s.DefaultHandlerExceptionResolver : Resolving exception from handler [gateway]: org.springframework.http.converter.HttpMessageNotReadableException: Could not read JSON: Can not deserialize instance of byte[] out of START_OBJECT token
at [Source: HttpInputOverHTTP@55c2d2c5; line: 1, column: 1]; nested exception is com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of byte[] out of START_OBJECT token
at [Source: HttpInputOverHTTP@55c2d2c5; line: 1, column: 1]
问题是由于未在网关上设置请求负载类型
gateway.setRequestPayloadType(ApplianceStatus.class);
那就解决了。
我已经配置了一个入站 HTTP 网关,它接受 POST 个请求 (JSON) 并为 return 一个 JSON 响应做作业,请求和响应负载是同一个POJO。
我为 Json 转换器创建了如下 bean
@Bean
public Jackson2ObjectMapperBuilder jacksonBuilder() {
Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
builder.indentOutput(true);
return builder;
}
@Bean
public List<HttpMessageConverter<?>> getConverters(){
List<HttpMessageConverter<?>> converters = new ArrayList<HttpMessageConverter<?>>();
converters.add(new MappingJackson2HttpMessageConverter(jacksonBuilder().build()));
return converters;
}
然后我将它们连接到相同 Java 配置 class 中的网关定义,代码段如下:
@Bean
public HttpRequestHandlingMessagingGateway gateway(){
HttpRequestHandlingMessagingGateway gateway = new HttpRequestHandlingMessagingGateway(true);
RequestMapping requestMapping = new RequestMapping();
requestMapping.setMethods(HttpMethod.POST);
requestMapping.setPathPatterns("/appliance/v1/status");
requestMapping.setConsumes("application/json");
requestMapping.setProduces("application/json");
gateway.setRequestMapping(requestMapping);
gateway.setRequestChannel(requestChannel());
gateway.setReplyChannel(replyChannel());
gateway.setMessageConverters(getConverters());
return gateway;
}
我打算转换的 POJO 非常简单
public class ApplianceStatus {
private String gatewayId;
private String applianceId;
private boolean running;
public String getGatewayId() {
return gatewayId;
}
public void setGatewayId(String gatewayId) {
this.gatewayId = gatewayId;
}
public String getApplianceId() {
return applianceId;
}
public void setApplianceId(String applianceId) {
this.applianceId = applianceId;
}
public boolean isRunning() {
return running;
}
public void setRunning(boolean running) {
this.running = running;
}
}
然而 POST 请求 Content-Type header 设置为 application/json returns 400,我发送的 JSON 是
{
"gatewayId": 1,
"applianceId": 123,
"running": false
}
我收到回复
{
"timestamp" : 1434615561240,
"status" : 400,
"error" : "Bad Request",
"exception" : "org.springframework.http.converter.HttpMessageNotReadableException",
"message" : "Bad Request",
"path" : "/appliance/v1/status"
}
并在日志中
2015-06-18 14:55:30.501 DEBUG 3447 --- [tp1023996917-22] .w.s.m.a.ResponseStatusExceptionResolver : Resolving exception from handler [gateway]: org.springframework.http.converter.HttpMessageNotReadableException: Could not read JSON: Can not deserialize instance of byte[] out of START_OBJECT token
at [Source: HttpInputOverHTTP@55c2d2c5; line: 1, column: 1]; nested exception is com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of byte[] out of START_OBJECT token
at [Source: HttpInputOverHTTP@55c2d2c5; line: 1, column: 1]
2015-06-18 14:55:30.501 DEBUG 3447 --- [tp1023996917-22] .w.s.m.s.DefaultHandlerExceptionResolver : Resolving exception from handler [gateway]: org.springframework.http.converter.HttpMessageNotReadableException: Could not read JSON: Can not deserialize instance of byte[] out of START_OBJECT token
at [Source: HttpInputOverHTTP@55c2d2c5; line: 1, column: 1]; nested exception is com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of byte[] out of START_OBJECT token
at [Source: HttpInputOverHTTP@55c2d2c5; line: 1, column: 1]
问题是由于未在网关上设置请求负载类型
gateway.setRequestPayloadType(ApplianceStatus.class);
那就解决了。