簡體   English   中英

org.springframework.web.reactive.function.UnsupportedMediaTypeException:bodyType 不支持內容類型“text/xml;charset=UTF-8”

[英]org.springframework.web.reactive.function.UnsupportedMediaTypeException: Content type 'text/xml;charset=UTF-8' not supported for bodyType

使用 Java 11、SpringBoot 2、WebFlux、WebClient 和 Jackson

嘗試使用 Spring WebClient 來使用返回 XML 的 Web 服務端點,內容類型:'text/xml;charset=UTF-8'

項目的 pom.xml 中的 Jackson XML 依賴項:

<dependency>
    <groupId>com.fasterxml.jackson.dataformat</groupId>
    <artifactId>jackson-dataformat-xml</artifactId>
    <version>2.9.9</version>
</dependency>

觸發對外部 API 的請求並構建響應的 WebClient 代碼:

        WebClient.builder()
                .baseUrl(url)
                .build()
                .get()
                .uri(builder.toUriString(), 1L)
                .accept(TEXT_XML)
                .header(HttpHeaders.CONTENT_TYPE, MediaType.TEXT_XML_VALUE)
                .acceptCharset(Charset.forName("UTF-8"))
                .exchange()
                .flatMap(x -> x.bodyToMono(ServiceResponse.class))
                .flatMap(x -> buildResponse(x));

ServiceResponse 類(一個簡單的 POJO):

public class ServiceResponse {

    private String ack;
    private String version;
    private String timestamp;
// .. getters and setters

結果錯誤:

org.springframework.web.reactive.function.UnsupportedMediaTypeException:在 org.springframework.web.reactive.function 的 bodyType=com.sample.service.model.ServiceResponse不支持內容類型 'text/xml;charset=UTF-8' 。 BodyExtractors.lambda$readWithMessageReaders$12(BodyExtractors.java:201) ~[spring-webflux-5.1.8.RELEASE.jar:5.1.8.RELEASE] 在 java.base/java.util.Optional.orElseGet(Optional.java: 369) ~[na:na] 在 org.springframework.web.reactive.function.BodyExtractors.readWithMessageReaders(BodyExtractors.java:197) ~[spring-webflux-5.1.8.RELEASE.jar:5.1.8.RELEASE] 在org.springframework.web.reactive.function.BodyExtractors.lambda$toMono$2(BodyExtractors.java:85) ~[spring-webflux-5.1.8.RELEASE.jar:5.1.8.RELEASE] 在 org.springframework.web。 react.function.client.DefaultClientResponse.body(DefaultClientResponse.java:95) ~[spring-webflux-5.1.8.RELEASE.jar:5.1.8.RELEASE] 在 org.springframework.web.reactive.function.client.DefaultClientResponse .bodyToMono(DefaultClientResponse.java:113 ) ~[spring-webflux-5.1.8.RELEASE.jar:5.1.8.RELEASE]

如何正確使用響應類型: Content-type 'text/xml;charset=UTF-8'

Spring Framework 目前不支持 Jackson XML - 請參閱專用問題 同時,您可以將 Jaxb 與Jaxb2XmlEncoderJaxb2XmlDecoder

添加

.accept(MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML) 

為我工作。 MediaType 表示 HTTP 規范中定義的 Internet 媒體類型。 供參考: https : //docs.spring.io/spring/docs/current/javadoc-api/org/springframework/http/MediaType.html

當我嘗試在 spring webflux 中使用 WebTestClient 編寫 tc 時,我遇到了這個錯誤。 單元測試在以下部分:

@Test
 public void testGetJobSummariesResBody() throws Exception{
 List<JobSummary> responseBody =
                testClient
                .get().uri("<uri-name>")
                .accept(MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML)
                .header(APPNAME_HEADER, "<header-name>")
                .exchange()
                .expectStatus().isOk()
                .expectBodyList(JobSummary.class)
                .returnResult()
                .getResponseBody();

        assertNotNull(responseBody.get(0).getJobType());
        assertNotEquals(0,responseBody.size());
    }

我有一個類似的情況,當我嘗試返回“純文本/文本”但對象被解析為 json 格式時(所以不是真正的文本)。 我想 spring 正在對你設置的響應 contenty-type 和 body 進行一些驗證。 我的實際反應是這樣的:

Mono.just(quote.getQuote())
                .flatMap(s -> ServerResponse.ok()
                        .contentType(MediaType.TEXT_PLAIN)
                        .syncBody(s)
                );

但也可以接受的是:

Mono.just(jsonQuote)
                .flatMap(s -> ServerResponse.ok()
                        .contentType(MediaType.APPLICATION_JSON)
                        .syncBody(s)
                );

就我而言,問題是我忘記設置Accept標頭,服務器的默認行為是返回 XML。
將其設置為MediaType.APPLICATION_JSON解決了該問題,服務器開始返回 JSON。

引發混淆 UnsupportedMediaTypeException 的另一種情況。 讓我們假設有生產 api 監聽 http/80 和 https/443。 然而,它的配置使得沒有內容通過 http 提供。 相反,這會返回 HTTP 301 重定向消息,其中包含一些內容類型為 text/html 的 html 內容。 默認情況下,WebClient 不遵循 301 重定向,而是嘗試將返回的 html 消息解析為假定的類。 這顯然失敗並產生 UnsupportedMediaTypeException 異常。 Postman 默認遵循 301 重定向並以完全透明的方式執行,這可能會進一步混淆這一事實。 留下的印象是您通過 http 請求獲得了預期的內容。

解決方法:使用https請求。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM