首页 > 解决方案 > http.converter.HttpMessageNotReadableException:无法读取文档:无法从 START_OBJECT 令牌中反序列化 java.lang.String 的实例

问题描述

我正在尝试读取 json 请求,然后创建响应。请求属于“Request.java”,响应属于“WsResponse.java”。WsResponse.java 链接到contacts.java。使用邮递员时,可以实现适当的响应。但是当尝试通过客户端调用调用方法时,它给出了异常

"Exception in thread "main" org.springframework.http.converter.HttpMessageNotReadableException: Could not read document: Can not deserialize instance of java.lang.String out of START_OBJECT token
 at [Source: java.io.PushbackInputStream@44c8afef; line: 1, column: 14] (through reference chain: com.websystique.springmvc.model.Request["contacts"]->java.util.ArrayList[0]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of java.lang.String out of START_OBJECT token
 at [Source: java.io.PushbackInputStream@44c8afef; line: 1, column: 14] (through reference chain: com.websystique.springmvc.model.Request["contacts"]->java.util.ArrayList[0])
    at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.readJavaType(AbstractJackson2HttpMessageConverter.java:227)
    at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.read(AbstractJackson2HttpMessageConverter.java:212)
    at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:95)
    at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:622)
    at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:580)
    at org.springframework.web.client.RestTemplate.postForObject(RestTemplate.java:380)
    at com.websystique.springmvc.Test.main(Test.java:49)
Caused by: com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of java.lang.String out of START_OBJECT token
 at [Source: java.io.PushbackInputStream@44c8afef; line: 1, column: 14] (through reference chain: com.websystique.springmvc.model.Request["contacts"]->java.util.ArrayList[0])
    at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:148)
    at com.fasterxml.jackson.databind.DeserializationContext.mappingException(DeserializationContext.java:835)
    at com.fasterxml.jackson.databind.deser.std.StdDeserializer._parseString(StdDeserializer.java:810)
    at com.fasterxml.jackson.databind.deser.std.StringCollectionDeserializer.deserialize(StringCollectionDeserializer.java:190)
    at com.fasterxml.jackson.databind.deser.std.StringCollectionDeserializer.deserialize(StringCollectionDeserializer.java:161)
    at com.fasterxml.jackson.databind.deser.std.StringCollectionDeserializer.deserialize(StringCollectionDeserializer.java:19)
    at com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:523)
    at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:95)
    at com.fasterxml.jackson.databind.deser.impl.BeanPropertyMap.findDeserializeAndSet(BeanPropertyMap.java:285)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:335)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:142)
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3562)
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2662)
    at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.readJavaType(AbstractJackson2HttpMessageConverter.java:224)
    ... 6 more"

给出以下类:

public class Request {
        @JsonProperty
        private String blocking;
        @JsonProperty
        private String module;
        @JsonProperty("contacts")
        private List<String> contacts;

        public Request(){

        }

        public String getBlocking() {
            return blocking;
        }

        public void setBlocking(String blocking) {
            this.blocking = blocking;
        }

        public String getModule() {
            return module;
        }

        public void setModule(String module) {
            this.module = module;
        }

        public List<String> getContacts() {
            return contacts;
        }

        public void setContacts(List<String> contacts) {
            this.contacts = contacts;
        }

        @Override
        public String toString() {
            return "Request [blocking=" + blocking + ", module=" + module + ", contacts=" + contacts + "]";
        }
    } 



public class WsResponse {

    @JsonProperty("contacts")
    private List<contacts> contacts;

    public WsResponse() {
    }

    public List<contacts> getContacts() {
        return contacts;
    }

    public void setContacts(List<contacts> contacts) {
        this.contacts = contacts;
    }

    @Override
    public String toString() {
        return "[contacts:" + contacts + "]";
    }


public class contacts {
        private String input;
        private String status;
        private String wa_id;

        public contacts() {
        }

        public String getInput() {
            return input;
        }

        public void setInput(String input) {
            this.input = input;
        }

        public String getStatus() {
            return status;
        }

        public void setStatus(String status) {
            this.status = status;
        }

        public String getWa_id() {
            return wa_id;
        }

        public void setWa_id(String wa_id) {
            this.wa_id = wa_id;
        }

        @Override
        public String toString() {
            return "{input=" + input + ", status=" + status + ", wa_id=" + wa_id + "}";
        }
    }

public class Test {

    public static void main(String[] args) throws JSONException {
        final String uriForPost = "http://localhost:8080/Spring4MVCCRUDRestService/getContactDetails/";

        ArrayList<String> contactList = new ArrayList<String>();
        contactList.add("9315551000");
        contactList.add("9315551002");
        contactList.add("931-555-1005");
        contactList.add("031-555-1005");

        Request req = new Request();
        req.setBlocking("wait");
        req.setModule("Model_A");
        req.setContacts(contactList);

        RestTemplate restTemplate = new RestTemplate();
        restTemplate.postForObject(uriForPost, req, Request.class);
    }
}

这是我的请求 JSON:

  {
        "blocking": "wait",
        "module":"Model_A",
        "contacts": [    
            "7855222121",
            "988542d1222",
            "9029674116",
            "5252525252",
            "213123123123"
        ]
    }

响应(从邮递员调用后):

{
    "contacts": [
        {
            "input": "7855222121",
            "status": "valid",
            "wa_id": "7855222121"
        },
        {
            "input": "988542d1222",
            "status": "valid",
            "wa_id": "988542d1222"
        },
        {
            "input": "9029674116",
            "status": "valid",
            "wa_id": "9029674116"
        },
        {
            "input": "5252525252",
            "status": "valid",
            "wa_id": "5252525252"
        },
        {
            "input": "213123123123",
            "status": "valid",
            "wa_id": "213123123123"
        }
    ]
}

在 Stackoverflow 和其他可用网站上尝试了以下解决方案:

1. using @JsonProperty on fields
2. Passing JSON object instead of Request class object


JSONObject json = new JSONObject();
    json.put("blocking", "wait");
    json.put("module", "Model_A");

    ArrayList<String> contactList = new ArrayList<String>();
    contactList.add("6315551000");
    contactList.add("6315551002");
    contactList.add("631-555-1005");
    json.put("contacts", contactList);

3.Adding below code for convertor

    List<HttpMessageConverter<?>> messageConverters = new ArrayList<HttpMessageConverter<?>>();
            messageConverters.add(new FormHttpMessageConverter());
            messageConverters.add(new StringHttpMessageConverter());
            //messageConverters.add(new MappingJacksonHttpMessageConverter());
            restTemplate.setMessageConverters(messageConverters);

4.

    MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();
            mappingJackson2HttpMessageConverter.setSupportedMediaTypes(Arrays.asList(MediaType.APPLICATION_JSON, MediaType.APPLICATION_OCTET_STREAM));
            restTemplate.getMessageConverters().add(mappingJackson2HttpMessageConverter);

任何提示或线索都会有所帮助。

谢谢

标签: javajsonrestweb-services

解决方案


您的代码中有一个错字(我认为),您期望响应为Request.class,而是必须将其映射到WsResponse.class

// wrong mapping of response to Request.class
restTemplate.postForObject(uriForPost, req, Request.class);

// correct mapping
WsResponse res = restTemplate.postForObject(uriForPost, req, WsResponse.class);

由于请求和响应中存在的联系人字段而出现异常,但在请求中它是字符串数组,作为响应它是对象数组(联系人类),因此当杰克逊尝试将响应 json 反序列化为Request#contacts时,它找到一个起始对象令牌{但它需要一个字符串。


推荐阅读