web-dev-qa-db-ja.com

SpringWebFlux WebClient JSON逆シリアル化をカスタマイズする方法?

spring-webflux WebClient (ビルド20170502.221452-172)を使用してEntryのストリームを生成するWebアプリケーションにアクセスしています次のようなオブジェクト(application/stream + json):

final WebClient producerClient = WebClient.create("http://localhost:8080/");

Flux<Entry> entries = producerClient.get().uri("json-stream")
        .accept(MediaType.APPLICATION_STREAM_JSON)
        .exchange()
        .flatMapMany(clientResponse -> clientResponse.bodyToFlux(Entry.class));

Entryオブジェクトの逆シリアル化は、Java time(JSR-310)を含む標準の一般的なタイプを使用するPOJOで正常に機能しますJava.time.Instantのようなデータ型では、カスタムJSONをJava逆シリアル化(たとえば、カスタムJackson ObjectMapper))に追加するために何をしなければならないのでしょうか。

WebClient またはそのビルダーによって生成されたオブジェクトのクラスとそれを行うための流暢なAPIでAPIを見つけることができません。

誰かがカスタマイズされた逆シリアル化でWebClientを使用しましたか?

(おそらくAPIはまだないのでしょうか?)

23
Martin

JSONの(デ)シリアライゼーションのためにObjectMapperをカスタマイズする例を次に示します。ストリーミングの目的で、異なるエンコーダー/デコーダーが使用されていますが、その構成については原則は同じままです。

    ExchangeStrategies strategies = ExchangeStrategies
            .builder()
            .codecs(clientDefaultCodecsConfigurer -> {
                clientDefaultCodecsConfigurer.defaultCodecs().jackson2JsonEncoder(new Jackson2JsonEncoder(new ObjectMapper(), MediaType.APPLICATION_JSON));
                clientDefaultCodecsConfigurer.defaultCodecs().jackson2JsonDecoder(new Jackson2JsonDecoder(new ObjectMapper(), MediaType.APPLICATION_JSON));

            }).build();

    WebClient webClient = WebClient.builder().exchangeStrategies(strategies).build();
16
Brian Clozel

これは、特定のWebクライアントに対して構成できます。

@Autowired
public ItunesAlbumServiceImpl(ObjectMapper mapper) {
    ExchangeStrategies strategies = ExchangeStrategies.builder().codecs(clientCodecConfigurer ->
        clientCodecConfigurer.customCodecs().decoder(
                new Jackson2JsonDecoder(mapper,
                        new MimeType("text", "javascript", StandardCharsets.UTF_8)))
    ).build();

    webClient = WebClient.builder()
            .exchangeStrategies(strategies)
            .baseUrl("https://iTunes.Apple.com")
            .build();
}

しかし、「アプリケーションレベル」でも

CodecCustomizerを構成する:

@Bean
public CodecCustomizer jacksonLegacyJsonCustomizer(ObjectMapper mapper) {
    return (configurer) -> {
        MimeType textJavascript = new MimeType("text", "javascript", StandardCharsets.UTF_8);
        CodecConfigurer.CustomCodecs customCodecs = configurer.customCodecs();
        customCodecs.decoder(
                new Jackson2JsonDecoder(mapper, textJavascript));
        customCodecs.encoder(
                new Jackson2JsonEncoder(mapper, textJavascript));
    };
}

これは、WebClientAutoConfigurationによってWebClient.Builder Beanとして有効になります。

@Autowired
public ItunesAlbumServiceImpl(WebClient.Builder webclientBuilder) {
    webClient = webclientBuilder.baseUrl("https://iTunes.Apple.com").build();
}
3
Ricardo

webflux 5.0.2では、de-registerDefaults `` `

val strategies = ExchangeStrategies.builder()
                .codecs { configurer ->
                    configurer.registerDefaults(false)
                    configurer.customCodecs().encoder(Jackson2JsonEncoder(objectMapper, APPLICATION_JSON))
                    configurer.customCodecs().decoder(Jackson2JsonDecoder(objectMapper, APPLICATION_JSON))
                }.build()

「」

1
Amit Yatagiri

グローバル構成:

@Configuration
public class AppConfig {

    private final ObjectMapper objectMapper;

    @Autowired
    public AppConfig(ObjectMapper objectMapper) {
        this.objectMapper = objectMapper;
        this.webClientBuilder = WebClient.builder()
                .exchangeStrategies(exchangeStrategies());
    }

    private ExchangeStrategies exchangeStrategies() {
        Jackson2JsonEncoder encoder = new Jackson2JsonEncoder(objectMapper);
        Jackson2JsonDecoder decoder = new Jackson2JsonDecoder(objectMapper);
        return ExchangeStrategies
                .builder()
                .codecs(configurer -> {
                    configurer.defaultCodecs().jackson2JsonEncoder(encoder);
                    configurer.defaultCodecs().jackson2JsonDecoder(decoder);
                }).build();
    }
}
0