Spring Boot: как разрешить Content-Type при неправильном получении с сервера - PullRequest
0 голосов
/ 06 марта 2019

У меня есть следующий класс в Java.Я ожидаю, что он выдаст запрос GET к URL, вернет полезную нагрузку JSON и преобразует эту полезную нагрузку в List<LocationData>.

package ...
import ...

@Repository
public class ProxiedLocationRepo {

    public List<LocationData> findAll() throws Exception {
        RestTemplate restTemplate = new RestTemplate();

        String url = UriComponentsBuilder
                .fromUriString("https://my-host/path")
                .queryParams("some", "queryParams")
                .toUriString();

        ResponseEntity<List<LocationData>> res = restTemplate.exchange(
                                                     url,
                                                     HttpMethod.GET,
                                                     null,
                                                     new ParameterizedTypeReference<List<LocationData>>(){});

        if (res.getStatusCode() == HttpStatus.ACCEPTED) {
            return res.getBody();
        } else {
            throw new ResponseStatusException(res.getStatusCode(), "Did not receive a 200 response from Server.");
        }
    }
}

Однако я получаю эту ошибку:

org.springframework.http.InvalidMediaTypeException: Invalid mime type "charset=UTF-8": does not contain '/'

Что ожидается, потому что, если я делаю тот же запрос от curl и проверяю заголовки, я получаю это (обратите внимание на строку Content-Type):

$ curl -sfi 'https://my-host/path?some=queryParams'
HTTP/1.1 200 OK
Server: nginx
Date: Wed, 06 Mar 2019 13:58:58 GMT
Content-Type: charset=UTF-8
Content-Length: 1821
Connection: keep-alive
Vary: Accept-Encoding
Strict-Transport-Security: max-age=31536000; includeSubDomains
X-Frame-Options: SAMEORIGIN

... # perfectly formatted JSON payload here

Я знаю, что ContentТип возвращаемого с этого сервера будет application/json, но он мне его не предоставляет.

Есть ли способ сообщить RestTemplate#exchange о типе содержимого ответа?Если нет, есть ли какая-либо другая методология, которую я мог бы использовать для решения этой проблемы, кроме того, чтобы заставить владельцев сервера правильно задать тип контента?

РЕДАКТИРОВАТЬ: Я также попытался добавитьЗаголовок «Принять», но получил те же результаты:

$ curl -sfi 'https://my-host/path?some=queryParams' \
    -H 'Accept: application/json'

1 Ответ

0 голосов
/ 07 марта 2019

К сожалению, я не думаю, что есть какой-то способ исправить это, используя среду Spring. Даже если вы создадите пользовательский JsonbHttpMessageConverter, который принимает MIME-тип ANY, Spring все равно не сможет проанализировать неверный Content-Type, полученный из запроса (поскольку он не может найти "/" в строке Content-Type ).

Таким образом, здесь было разрешено использовать java.net.HttpURLConnection для создания сети, а затем использовать com.fasterxml.jackson.databind.ObjectMapper для сопоставления JSON с POJO.

Это работает, но за счет того, что мы больше не можем использовать какую-либо обработку Spring в HTTP, которая, вероятно, намного более надежна, чем все, что я могу реализовать в одиночку.

...