无法在Spring启动控制器中将JSON对象转换为Java对象

时间:2017-12-01 04:54:56

标签: json spring-boot controller

我将以下输入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

1 个答案:

答案 0 :(得分:3)

问题是您的JSON与POJO的类型签名不匹配。 Jackson希望JSON 数组能够匹配Java ListSetCollection接口类型。您需要将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