簡體   English   中英

Spring 解碼時啟動 Webflux 處理程序錯誤 XML 將正文內容請求到 Mono 或 Flux object

[英]Spring Boot Webflux Handler errors when decoding XML request body content to Mono or Flux object

我一直在嘗試實現 Spring 反應式路由器和處理程序而不是 MVC 控制器。 看起來很簡單,但我的 WebTestClient 測試一直失敗並出現 500 Internal Server Error。 測試的短代碼版本。

@ContextConfiguration(classes = {FooRouter.class, FooServiceConfig.class, FoonHandler.class})
@WebFluxTest
public class FooHandlerTest {

@Test
public void testFooPost()  {
    webTestClient.post()
            .uri("/foot")
            .contentType(MediaType.APPLICATION_XML)
            .accept(MediaType.APPLICATION_XML)
            .body(Mono.just(foo), Foo.class)
            .exchange()
            .expectStatus().isCreated()
            .expectBody(Bar.class)
            .isEqualTo(bar);
}

在測試期間,路由器工作正常並調用處理程序。 當處理程序嘗試從請求主體創建 Mono 時:

Mono<Foo> fooMono = request.bodyToMono(Foo.class);

該行終止單元測試並且 WebTestClient 收到 500 狀態代碼。 在調試過程中,雖然 mime 類型是 application/xml 並且它做了 map Java class,但 BodyExtractor 正在過濾解碼器並匹配 class 和 mime 類型。 對於 Json,它正在查看 Java class 並在比較 MIME 類型之前嘗試從中獲取映射。 在調試的深處,當它仍在嘗試 map class 到 object 映射器時,它崩潰了。

我目前正在使用 Spring 引導版本 2.3.4-RELEASE 和 Java8。 文檔提到如果您的類路徑中有 JaxB,那么對於 XML,它應該使用 Jaxb2XmlDecoder 和 Endoder 作為默認編解碼器。 如果您的類路徑中有 Jackson,它也會使用它。 我確實碰巧都減去了 jackson-dataformat-xml 依賴項。 我很確定它要么是我的測試配置,要么是 WebFluxConfigurer,我嘗試為 jaxb2Decoder 和編碼器設置默認編解碼器。 我也確實嘗試添加 jackson-dataformat-xml 依賴項,但這也不起作用。 這是我嘗試使用的 webconfig,但在嘗試使用 Json 解碼器解碼 mime 類型的 application/xml 時仍然崩潰。 這是網絡配置:

@Configuration
@EnableWebFlux
public class WebConfig implements WebFluxConfigurer {

    @Override
    public void configureHttpMessageCodecs(ServerCodecConfigurer configurer) {
        configurer.registerDefaults(false);
        configurer.defaultCodecs().jaxb2Decoder(new Jaxb2XmlDecoder(MediaType.APPLICATION_XML));
        configurer.defaultCodecs().jaxb2Encoder(new Jaxb2XmlEncoder());
    }
}

我一直在調試並打印出請求對象消息閱讀器,而 Jaxb2XmlEncoder 是 xml mime 類型的編解碼器之一。 這是 JSON 和 XML 解碼器的打印消息:

Message Reader: org.springframework.http.codec.DecoderHttpMessageReader@5b2cea27
    DecoderHttpMessageReader Decoder: org.springframework.http.codec.json.Jackson2JsonDecoder@87b7472
        Mime Type: application/json
        Mime Type: application/*+json
Message Reader: org.springframework.http.codec.DecoderHttpMessageReader@198a86e1
    DecoderHttpMessageReader Decoder: org.springframework.http.codec.xml.Jaxb2XmlDecoder@50cb41d0
        Mime Type: application/xml
        Mime Type: text/xml
        Mime Type: application/*+xml

當在 BodyExtractors class 的 readWithMessageReaders 方法中時,function 中有一個過濾器會遍歷消息閱讀器和解碼器。 當它到達 DecoderHttpMessageReader,Jackson2JsonDecoder 時,它開始嘗試解碼請求。 不確定為什么,因為調試器中的 mime 類型顯示 application/xml。

有沒有人對如何調試這段代碼有任何建議:

Mono<Foo> fooMono = request.bodyToMono(Foo.class);

這是它在使用上面的代碼進行單元測試期間死掉的地方。 我試過調試,但當我太深入時它只會停止測試。 我只知道它在嘗試匹配編解碼器時正在通過 Java 類型。 大多數編解碼器立即返回,但 Json 和 XML 解碼器正在嘗試獲取 Java class 屬性並且令人窒息。 class 是帶有所有正確注釋的 JaxB class。 WebTestClient 將 class 編碼為 XML 進行測試沒有問題。 那么為什么處理程序不能將正文轉換為 mono? 該代碼語句沒有拋出任何內容。

我知道這是我的設置中的問題,單元測試沒有顯示正確的問題。

在獲取正文內容時,實際上是我的返回語句導致了錯誤。

舊的退貨聲明:

return created(URI.create(response.getDocument().getPath()))
    .bodyValue(Mono.just(response));

新的退貨聲明:

return created(URI.create(response.getDocument().getPath()))
    .body(Mono.just(response), Response.class);

看到 bodyValue 和 just body 的區別了嗎? 這導致請求正文無法轉換為 Mono。

暫無
暫無

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

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