Spring реактивный WebClient GET json ответ с Content-Type "text / plain; charset = UTF-8" - PullRequest
0 голосов
/ 16 апреля 2020

У меня проблема с реактивным WebClient Spring 5, когда я запрашиваю конечную точку, которая возвращает правильно отформатированный json ответ с типом содержимого "text / plain; charset = UTF-8". Исключение составляет

org.springframework.web.reactive.function.UnsupportedMediaTypeException:
Content type 'text/plain;charset=UTF-8' not supported for bodyType=MyDTOClass

Вот как я сделал запрос:

webClient.get().uri(endpoint).retrieve().bodyToFlux(MyDTOClass.class)

РЕДАКТИРОВАТЬ : заголовки «правильно» установлены (Accept, Content-Type) , Я пробовал разные типы содержимого (json, json + UTF8, текстовый текст, текстовый текст + UTF8) без успеха. Я думаю, что проблема в .bodyToFlux(MyDTOClass.class) не знает, как перевести "текст" в MyDTOClass объекты. Если я изменю запрос на:

webClient.get().uri(endpoint).retrieve().bodyToFlux(String.class)

, я смогу прочитать строку.

РЕДАКТИРОВАТЬ 2 : Следующая цитата извлечена из документации Spring ( https://docs.spring.io/spring/docs/current/spring-framework-reference/web-reactive.html#webflux -codecs-jackson )

По умолчанию оба Jackson2Encoder и Jackson2Decoder не поддерживают элементы типа String. Вместо этого по умолчанию предполагается, что строка или последовательность строк представляют сериализованное содержимое JSON, которое будет отображаться с помощью CharSequenceEncoder. Если вам нужно визуализировать массив JSON из Flux<String>, используйте Flux#collectToList() и кодируйте Mono<List<String>>.

Я думаю, что решение состоит в том, чтобы определить новый декодер / считыватель по порядку преобразовать строку в MyDTOClass, но я не знаю, как это сделать.

Ответы [ 2 ]

0 голосов
/ 21 апреля 2020

Если кому-то это нужно, вот решение:

Этот ответ ({ ссылка }) является ключевым. Мы должны добавить пользовательский декодер, чтобы указать, что и как десериализовать ответ.

Но мы должны помнить следующее: аннотация на уровне класса @JsonIgnoreProperties по умолчанию настроена на отображение json и не влияет на другие картографы. Поэтому, если ваш DTO не соответствует всем свойствам ответа "json", десериализация завершится неудачей.

Вот как настроить ObjectMapper и WebClient для десериализации json объектов из текстовых ответов:

...
WebClient.builder()
        .baseUrl(url)
        .exchangeStrategies(ExchangeStrategies.builder().codecs(configurer ->{
                ObjectMapper mapper = new ObjectMapper();
                mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
                configurer.customCodecs().decoder(new Jackson2JsonDecoder(mapper, MimeTypeUtils.parseMimeType(MediaType.TEXT_PLAIN_VALUE)));
                }).build())
        .build();
...

Ура!

0 голосов
/ 16 апреля 2020

Установить тип контента для веб-клиента.

webClient.get()
            .uri(endpoint)
           .contentType(MediaType.APPLICATION_JSON_UTF8)
...