我将以下输入JSON格式提供给spring控制器。我在弹簧启动控制器中将JSON对象转换为java时出错。所有细节如下。
{
"series": "COR",
"vehicleCondition": "N",
"selectedOptions": {
"snowplowBizUse": "N",
"snowplowPersonalUse": "Y",
"customSuspensionPkg": "Y"
}
}
下面给出了弹簧控制器的输入模型,
package com.cnanational.productservice.model;
import java.util.List;
import javax.validation.constraints.Pattern;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
@JsonIgnoreProperties(ignoreUnknown = true)
public class PsSeriesSelectedOptions {
@Pattern(regexp = "\\p{Alnum}{1,30}")
private String series;
@Pattern(regexp = "\\p{Alnum}{1,30}")
private String vehicleCondition;
@JsonIgnoreProperties(ignoreUnknown = true)
private List<selectedOptions> selectedOptions;
public String getSeries() {
return series;
}
public void setSeries(String series) {
this.series = series;
}
public String getVehicleCondition() {
return vehicleCondition;
}
public void setVehicleCondition(String vehicleCondition) {
this.vehicleCondition = vehicleCondition;
}
public List<selectedOptions> getSelectedOptions() {
return selectedOptions;
}
public void setSelectedOptions(List<selectedOptions> selectedOptions) {
this.selectedOptions = selectedOptions;
}
public static class selectedOptions {
private String snowplowBizUse;
private String snowplowPersonalUse;
private String customSuspensionPkg;
public selectedOptions(
String snowplowBizUse,
String snowplowPersonalUse,
String customSuspensionPkg) {
this.snowplowBizUse = snowplowBizUse;
this.snowplowPersonalUse = snowplowPersonalUse;
this.customSuspensionPkg = customSuspensionPkg;
}
public String getSnowplowBizUse() {
return snowplowBizUse;
}
public void setSnowplowBizUse(String snowplowBizUse) {
this.snowplowBizUse = snowplowBizUse;
}
public String getSnowplowPersonalUse() {
return snowplowPersonalUse;
}
public void setSnowplowPersonalUse(String snowplowPersonalUse) {
this.snowplowPersonalUse = snowplowPersonalUse;
}
public String getCustomSuspensionPkg() {
return customSuspensionPkg;
}
public void setCustomSuspensionPkg(String customSuspensionPkg) {
this.customSuspensionPkg = customSuspensionPkg;
}
}
}
以下是控制器的方法,
@RequestMapping(value = PATH_GET_SURCHARGES, method=RequestMethod.POST)
public ResponseEntity<?> getSurcharges(
@RequestBody final PsSeriesSelectedOptions stdOptions)
{
log.debug("getSurcharges: entering, searchParams={}", stdOptions);
System.out.println("one = "+stdOptions.getSeries());
System.out.println("two = "+stdOptions.getVehicleCondition());
System.out.println("six = "+stdOptions.getVehicleCondition());
return this.productService.getSurcharges(
stdOptions);
}
}
以下是我在部署时遇到的错误。
Caused by: com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of java.util.ArrayList out of START_OBJECT token
at [Source: java.io.PushbackInputStream@667e3422; line: 4, column: 26] (through reference chain: com.cnanational.productservice.model.PsSeriesSelectedOptions["selectedOptions"])
at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:270)
at com.fasterxml.jackson.databind.DeserializationContext.reportMappingException(DeserializationContext.java:1234)
at com.fasterxml.jackson.databind.DeserializationContext.handleUnexpectedToken(DeserializationContext.java:1122)
at com.fasterxml.jackson.databind.DeserializationContext.handleUnexpectedToken(DeserializationContext.java:1075)
at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.handleNonArray(CollectionDeserializer.java:338)
at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:269)
at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:259)
at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:26)
at com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:504)
at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:104)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:357)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:148)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3798)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2922)
at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.readJavaType(AbstractJackson2HttpMessageConverter.java:241)
... 109 common frames omitted
2017-11-30 20:41:28:541 - WARN - Correlation-Id = 1434383293 - AppName = product-service - Server-IP = 127.0.0.1:8100 - RequestorApp = UNKNOWN - RequestorIp = 127.0.0.1 - UserId = WEB_BKAUR - Total-Time = -1 - Resolved exception caused by Handler execution: org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Can not deserialize instance of java.util.ArrayList out of START_OBJECT token; nested exception is com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of java.util.ArrayList out of START_OBJECT token
答案 0 :(得分:3)
问题是您的JSON与POJO的类型签名不匹配。 Jackson希望JSON 数组能够匹配Java List
,Set
和Collection
接口类型。您需要将JSON架构更新为:
{
"series": "COR",
"vehicleCondition": "N",
"selectedOptions": [
{
"snowplowBizUse": "N",
"snowplowPersonalUse": "Y",
"customSuspensionPkg": "Y"
}
]
}
这样,Jackson会将selectionOptions
属性反序列化为对象的列表,其属性可以反序列化为selectedOptions
的属性类。这是另一个问题,可以帮助您了解此处发生的事情:How to use Jackson to deserialise an array of objects