diff --git a/src/main/java/org/springframework/hateoas/config/WebClientConfigurer.java b/src/main/java/org/springframework/hateoas/config/WebClientConfigurer.java index 7910c709c..47c783f67 100644 --- a/src/main/java/org/springframework/hateoas/config/WebClientConfigurer.java +++ b/src/main/java/org/springframework/hateoas/config/WebClientConfigurer.java @@ -15,17 +15,19 @@ */ package org.springframework.hateoas.config; -import lombok.RequiredArgsConstructor; - import java.util.ArrayList; import java.util.List; +import java.util.function.Consumer; import org.springframework.context.annotation.Configuration; import org.springframework.core.codec.Decoder; import org.springframework.core.codec.Encoder; import org.springframework.hateoas.config.EnableHypermediaSupport.HypermediaType; +import org.springframework.http.codec.ClientCodecConfigurer; +import org.springframework.http.codec.CodecConfigurer.CustomCodecs; import org.springframework.http.codec.json.Jackson2JsonDecoder; import org.springframework.http.codec.json.Jackson2JsonEncoder; +import org.springframework.util.Assert; import org.springframework.util.MimeType; import org.springframework.web.reactive.function.client.ExchangeStrategies; import org.springframework.web.reactive.function.client.WebClient; @@ -36,40 +38,57 @@ * Assembles {@link ExchangeStrategies} needed to wire a {@link WebClient} with hypermedia support. * * @author Greg Turnquist + * @author Oliver Drotbohm * @since 1.0 */ @Configuration -@RequiredArgsConstructor public class WebClientConfigurer { - private final ObjectMapper mapper; - private final List hypermediaTypes; + Consumer configurer; /** - * Return a set of {@link ExchangeStrategies} driven by registered {@link HypermediaType}s. + * Creates a new {@link WebClientConfigurer} for the given {@link ObjectMapper} and + * {@link HypermediaMappingInformation}s. * - * @return a collection of {@link Encoder}s and {@link Decoder} assembled into a {@link ExchangeStrategies}. + * @param mapper must not be {@literal null}. + * @param hypermediaTypes must not be {@literal null}. */ - public ExchangeStrategies hypermediaExchangeStrategies() { + public WebClientConfigurer(ObjectMapper mapper, List hypermediaTypes) { + + Assert.notNull(mapper, "ObjectMapper must not be null!"); + Assert.notNull(hypermediaTypes, "HypermediaMappingInformations must not be null!"); List> encoders = new ArrayList<>(); List> decoders = new ArrayList<>(); - this.hypermediaTypes.forEach(hypermedia -> { + hypermediaTypes.forEach(hypermedia -> { - ObjectMapper objectMapper = hypermedia.configureObjectMapper(this.mapper.copy()); + ObjectMapper objectMapper = hypermedia.configureObjectMapper(mapper.copy()); MimeType[] mimeTypes = hypermedia.getMediaTypes().toArray(new MimeType[0]); encoders.add(new Jackson2JsonEncoder(objectMapper, mimeTypes)); decoders.add(new Jackson2JsonDecoder(objectMapper, mimeTypes)); }); - return ExchangeStrategies.builder().codecs(clientCodecConfigurer -> { + this.configurer = it -> { - encoders.forEach(encoder -> clientCodecConfigurer.customCodecs().encoder(encoder)); - decoders.forEach(decoder -> clientCodecConfigurer.customCodecs().decoder(decoder)); + CustomCodecs codecs = it.customCodecs(); - }).build(); + encoders.forEach(codecs::encoder); + decoders.forEach(codecs::decoder); + }; + } + + /** + * Return a set of {@link ExchangeStrategies} driven by registered {@link HypermediaType}s. + * + * @return a collection of {@link Encoder}s and {@link Decoder} assembled into a {@link ExchangeStrategies}. + */ + public ExchangeStrategies hypermediaExchangeStrategies() { + + return ExchangeStrategies.builder() // + .codecs(configurer) // + .build(); } /** @@ -79,6 +98,9 @@ public ExchangeStrategies hypermediaExchangeStrategies() { * @return mutated webClient with hypermedia support. */ public WebClient registerHypermediaTypes(WebClient webClient) { - return webClient.mutate().exchangeStrategies(hypermediaExchangeStrategies()).build(); + + return webClient.mutate() // + .exchangeStrategies(it -> it.codecs(configurer)) // + .build(); } } diff --git a/src/test/java/org/springframework/hateoas/config/CustomHypermediaWebFluxTest.java b/src/test/java/org/springframework/hateoas/config/CustomHypermediaWebFluxTest.java index 34e9b5f12..39d0b74cc 100644 --- a/src/test/java/org/springframework/hateoas/config/CustomHypermediaWebFluxTest.java +++ b/src/test/java/org/springframework/hateoas/config/CustomHypermediaWebFluxTest.java @@ -19,11 +19,12 @@ import static org.springframework.hateoas.support.CustomHypermediaType.*; import static org.springframework.hateoas.support.MappingUtils.*; +import reactor.core.publisher.Mono; + import java.io.IOException; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import reactor.core.publisher.Mono; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -55,7 +56,7 @@ void setUp() { this.testClient = WebTestClient.bindToApplicationContext(ctx).build() // .mutate() // - .exchangeStrategies(webClientConfigurer.hypermediaExchangeStrategies()) // + .exchangeStrategies(it -> it.codecs(webClientConfigurer.configurer)) // .build(); }