尝试通过Springs RestTemplate执行POST请求时获取RestClientException

时间:2018-11-24 23:20:03

标签: java spring resttemplate

我想开发一个小功能,该功能使用Springs RestTemplates将ISIN转换为符号。我遇到一个错误,指出以下内容:

java.lang.IllegalStateException: Failed to execute ApplicationRunner
    at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:812) [spring-boot-2.0.5.RELEASE.jar:2.0.5.RELEASE]
    at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:799) [spring-boot-2.0.5.RELEASE.jar:2.0.5.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:341) [spring-boot-2.0.5.RELEASE.jar:2.0.5.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1277) [spring-boot-2.0.5.RELEASE.jar:2.0.5.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1265) [spring-boot-2.0.5.RELEASE.jar:2.0.5.RELEASE]
    at app.Service.main(Service.java:14) [classes/:na]
Caused by: org.springframework.web.client.RestClientException: Error while extracting response for type [class app.model.OpenFigiResponse] and content type [application/json;charset=utf-8]; nested exception is org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot deserialize instance of `app.model.OpenFigiResponse` out of START_ARRAY token; nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `app.model.OpenFigiResponse` out of START_ARRAY token
at [Source: (PushbackInputStream); line: 1, column: 1]
    at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:115) ~[spring-web-5.0.9.RELEASE.jar:5.0.9.RELEASE]
    at org.springframework.web.client.RestTemplate$ResponseEntityResponseExtractor.extractData(RestTemplate.java:959) ~[spring-web-5.0.9.RELEASE.jar:5.0.9.RELEASE]
    at org.springframework.web.client.RestTemplate$ResponseEntityResponseExtractor.extractData(RestTemplate.java:942) ~[spring-web-5.0.9.RELEASE.jar:5.0.9.RELEASE]
    at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:689) ~[spring-web-5.0.9.RELEASE.jar:5.0.9.RELEASE]
    at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:644) ~[spring-web-5.0.9.RELEASE.jar:5.0.9.RELEASE]
    at org.springframework.web.client.RestTemplate.postForEntity(RestTemplate.java:430) ~[spring-web-5.0.9.RELEASE.jar:5.0.9.RELEASE]
    at app.Service.run(Service.java:37) [classes/:na]
    at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:809) [spring-boot-2.0.5.RELEASE.jar:2.0.5.RELEASE]
    ... 5 common frames omitted
Caused by: org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot deserialize instance of `app.model.OpenFigiResponse` out of START_ARRAY token; nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `app.model.OpenFigiResponse` out of START_ARRAY token
at [Source: (PushbackInputStream); line: 1, column: 1]
    at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.readJavaType(AbstractJackson2HttpMessageConverter.java:243) ~[spring-web-5.0.9.RELEASE.jar:5.0.9.RELEASE]
    at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.read(AbstractJackson2HttpMessageConverter.java:225) ~[spring-web-5.0.9.RELEASE.jar:5.0.9.RELEASE]
    at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:100) ~[spring-web-5.0.9.RELEASE.jar:5.0.9.RELEASE]
    ... 12 common frames omitted
Caused by: com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `app.model.OpenFigiResponse` out of START_ARRAY token
at [Source: (PushbackInputStream); line: 1, column: 1]
    at com.fasterxml.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:63) ~[jackson-databind-2.9.6.jar:2.9.6]
    at com.fasterxml.jackson.databind.DeserializationContext.reportInputMismatch(DeserializationContext.java:1342) ~[jackson-databind-2.9.6.jar:2.9.6]
    at com.fasterxml.jackson.databind.DeserializationContext.handleUnexpectedToken(DeserializationContext.java:1138) ~[jackson-databind-2.9.6.jar:2.9.6]
    at com.fasterxml.jackson.databind.DeserializationContext.handleUnexpectedToken(DeserializationContext.java:1092) ~[jackson-databind-2.9.6.jar:2.9.6]
    at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromArray(BeanDeserializerBase.java:1461) ~[jackson-databind-2.9.6.jar:2.9.6]
    at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeOther(BeanDeserializer.java:185) ~[jackson-databind-2.9.6.jar:2.9.6]
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:161) ~[jackson-databind-2.9.6.jar:2.9.6]
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4013) ~[jackson-databind-2.9.6.jar:2.9.6]
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3084) ~[jackson-databind-2.9.6.jar:2.9.6]
    at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.readJavaType(AbstractJackson2HttpMessageConverter.java:237) ~[spring-web-5.0.9.RELEASE.jar:5.0.9.RELEASE]
    ... 14 common frames omitted

当我使用String.class作为响应类而不是自定义类OpenFigiResponse时,打印响应没有问题。

作为参考,来自API的JSON响应如下所示:

[
    {
        "data": [
            {
                [...],
                "name": "APPLE INC",
                "ticker": "AAPL",
                "exchCode": "US",
                [...]
            }
        ]
    }
]

我的主要方法,该方法引发错误:

final String uri = "https://api.openfigi.com/v1/mapping";

HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setContentType(MediaType.APPLICATION_JSON_UTF8);

String requestBody = "[{\n" +
        "\t\"idType\": \"ID_ISIN\",\n" +
        "\t\"idValue\": \"US0378331005\",\n" +
        "\t\"exchCode\":\"US\"\n" +
        "}]";

HttpEntity<String> request = new HttpEntity<>(requestBody, httpHeaders);

RestTemplate restTemplate = new RestTemplate();
HttpEntity<OpenFigiResponse> response = restTemplate.postForEntity(uri, request, OpenFigiResponse.class);

我的回答课:

package app.model;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonRootName;

@JsonIgnoreProperties(ignoreUnknown = true)
@JsonRootName(value = "data")
public class OpenFigiResponse {
    @JsonProperty("ticker")
    private String ticker;

    public String getTicker() {
        return ticker;
    }

    public void setTicker(String ticker) {
        this.ticker = ticker;
    }
}

我尝试将消息转换器添加到restTemplate,但没有实际进展。

1 个答案:

答案 0 :(得分:0)

您的JSON data在JSON数组中,因此请使用包装器类OpenFigiListResponse

public class OpenFigiListResponse {
  List<OpenFigiResponse> openFigiResponse;
  //public getter and setter
}

并使用它:

HttpEntity<OpenFigiResponse> response = restTemplate.postForEntity(uri, request, OpenFigiListResponse.class);