Skip to content

Commit 83683a1

Browse files
bclozelrstoyanchev
authored andcommitted
Allow ExchangeStrategies customizations in WebClient
Backport of d420939 and acfeb77 Closes gh-23961
1 parent 59165dd commit 83683a1

File tree

21 files changed

+498
-46
lines changed

21 files changed

+498
-46
lines changed

spring-test/src/main/java/org/springframework/test/web/reactive/server/DefaultWebTestClientBuilder.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2018 the original author or authors.
2+
* Copyright 2002-2019 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -142,6 +142,12 @@ public WebTestClient.Builder exchangeStrategies(ExchangeStrategies strategies) {
142142
return this;
143143
}
144144

145+
@Override
146+
public WebTestClient.Builder exchangeStrategies(Consumer<ExchangeStrategies.Builder> configurer) {
147+
this.webClientBuilder.exchangeStrategies(configurer);
148+
return this;
149+
}
150+
145151
@Override
146152
public WebTestClient.Builder responseTimeout(Duration timeout) {
147153
this.responseTimeout = timeout;

spring-test/src/main/java/org/springframework/test/web/reactive/server/WebTestClient.java

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@
7777
* and Spring Kotlin extensions to perform integration tests on an embedded WebFlux server.
7878
*
7979
* @author Rossen Stoyanchev
80+
* @author Brian Clozel
8081
* @since 5.0
8182
* @see StatusAssertions
8283
* @see HeaderAssertions
@@ -436,11 +437,25 @@ interface Builder {
436437

437438
/**
438439
* Configure the {@link ExchangeStrategies} to use.
439-
* <p>By default {@link ExchangeStrategies#withDefaults()} is used.
440+
* <p>Note that in a scenario where the builder is configured by
441+
* multiple parties, it is preferable to use
442+
* {@link #exchangeStrategies(Consumer)} in order to customize the same
443+
* {@code ExchangeStrategies}. This method here sets the strategies that
444+
* everyone else then can customize.
445+
* <p>By default this is {@link ExchangeStrategies#withDefaults()}.
440446
* @param strategies the strategies to use
441447
*/
442448
Builder exchangeStrategies(ExchangeStrategies strategies);
443449

450+
/**
451+
* Customize the strategies configured via
452+
* {@link #exchangeStrategies(ExchangeStrategies)}. This method is
453+
* designed for use in scenarios where multiple parties wish to update
454+
* the {@code ExchangeStrategies}.
455+
* @since 5.1.12
456+
*/
457+
Builder exchangeStrategies(Consumer<ExchangeStrategies.Builder> configurer);
458+
444459
/**
445460
* Max amount of time to wait for responses.
446461
* <p>By default 5 seconds.
@@ -877,7 +892,7 @@ interface BodyContentSpec {
877892
* @since 5.1
878893
* @see #xpath(String, Map, Object...)
879894
*/
880-
default XpathAssertions xpath(String expression, Object... args){
895+
default XpathAssertions xpath(String expression, Object... args) {
881896
return xpath(expression, null, args);
882897
}
883898

@@ -891,7 +906,7 @@ default XpathAssertions xpath(String expression, Object... args){
891906
* @param args arguments to parameterize the expression
892907
* @since 5.1
893908
*/
894-
XpathAssertions xpath(String expression, @Nullable Map<String, String> namespaces, Object... args);
909+
XpathAssertions xpath(String expression, @Nullable Map<String, String> namespaces, Object... args);
895910

896911
/**
897912
* Assert the response body content with the given {@link Consumer}.

spring-web/src/main/java/org/springframework/http/codec/ClientCodecConfigurer.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2018 the original author or authors.
2+
* Copyright 2002-2019 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -63,6 +63,12 @@ public interface ClientCodecConfigurer extends CodecConfigurer {
6363
@Override
6464
ClientDefaultCodecs defaultCodecs();
6565

66+
/**
67+
* {@inheritDoc}.
68+
*/
69+
@Override
70+
ClientCodecConfigurer clone();
71+
6672

6773
/**
6874
* Static factory method for a {@code ClientCodecConfigurer}.

spring-web/src/main/java/org/springframework/http/codec/CodecConfigurer.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,15 @@ public interface CodecConfigurer {
8787
*/
8888
List<HttpMessageWriter<?>> getWriters();
8989

90+
/**
91+
* Create a copy of this {@link CodecConfigurer}. The returned clone has its
92+
* own lists of default and custom codecs and generally can be configured
93+
* independently. Keep in mind however that codec instances (if any are
94+
* configured) are themselves not cloned.
95+
* @since 5.1.12
96+
*/
97+
CodecConfigurer clone();
98+
9099

91100
/**
92101
* Customize or replace the HTTP message readers and writers registered by

spring-web/src/main/java/org/springframework/http/codec/ServerCodecConfigurer.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,12 @@ public interface ServerCodecConfigurer extends CodecConfigurer {
6262
@Override
6363
ServerDefaultCodecs defaultCodecs();
6464

65+
/**
66+
* {@inheritDoc}.
67+
*/
68+
@Override
69+
ServerCodecConfigurer clone();
70+
6571

6672
/**
6773
* Static factory method for a {@code ServerCodecConfigurer}.

spring-web/src/main/java/org/springframework/http/codec/support/BaseCodecConfigurer.java

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,14 @@
3434
* client and server specific variants.
3535
*
3636
* @author Rossen Stoyanchev
37+
* @author Brian Clozel
3738
* @since 5.0
3839
*/
39-
class BaseCodecConfigurer implements CodecConfigurer {
40+
abstract class BaseCodecConfigurer implements CodecConfigurer {
4041

41-
private final BaseDefaultCodecs defaultCodecs;
42+
protected final BaseDefaultCodecs defaultCodecs;
4243

43-
private final DefaultCustomCodecs customCodecs = new DefaultCustomCodecs();
44+
protected final DefaultCustomCodecs customCodecs;
4445

4546

4647
/**
@@ -50,8 +51,25 @@ class BaseCodecConfigurer implements CodecConfigurer {
5051
BaseCodecConfigurer(BaseDefaultCodecs defaultCodecs) {
5152
Assert.notNull(defaultCodecs, "'defaultCodecs' is required");
5253
this.defaultCodecs = defaultCodecs;
54+
this.customCodecs = new DefaultCustomCodecs();
5355
}
5456

57+
/**
58+
* Create a deep copy of the given {@link BaseCodecConfigurer}.
59+
* @since 5.1.12
60+
*/
61+
protected BaseCodecConfigurer(BaseCodecConfigurer other) {
62+
this.defaultCodecs = other.cloneDefaultCodecs();
63+
this.customCodecs = new DefaultCustomCodecs(other.customCodecs);
64+
}
65+
66+
/**
67+
* Sub-classes should override this to create deep copy of
68+
* {@link BaseDefaultCodecs} which can can be client or server specific.
69+
* @since 5.1.12
70+
*/
71+
protected abstract BaseDefaultCodecs cloneDefaultCodecs();
72+
5573

5674
@Override
5775
public DefaultCodecs defaultCodecs() {
@@ -87,6 +105,7 @@ public List<HttpMessageWriter<?>> getWriters() {
87105
return getWritersInternal(false);
88106
}
89107

108+
90109
/**
91110
* Internal method that returns the configured writers.
92111
* @param forMultipart whether to returns writers for general use ("false"),
@@ -106,11 +125,14 @@ protected List<HttpMessageWriter<?>> getWritersInternal(boolean forMultipart) {
106125
return result;
107126
}
108127

128+
@Override
129+
public abstract CodecConfigurer clone();
130+
109131

110132
/**
111133
* Default implementation of {@code CustomCodecs}.
112134
*/
113-
private static final class DefaultCustomCodecs implements CustomCodecs {
135+
protected static final class DefaultCustomCodecs implements CustomCodecs {
114136

115137
private final List<HttpMessageReader<?>> typedReaders = new ArrayList<>();
116138

@@ -121,6 +143,20 @@ private static final class DefaultCustomCodecs implements CustomCodecs {
121143
private final List<HttpMessageWriter<?>> objectWriters = new ArrayList<>();
122144

123145

146+
DefaultCustomCodecs() {
147+
}
148+
149+
/**
150+
* Create a deep copy of the given {@link DefaultCustomCodecs}.
151+
* @since 5.1.12
152+
*/
153+
DefaultCustomCodecs(DefaultCustomCodecs other) {
154+
other.typedReaders.addAll(this.typedReaders);
155+
other.typedWriters.addAll(this.typedWriters);
156+
other.objectReaders.addAll(this.objectReaders);
157+
other.objectWriters.addAll(this.objectWriters);
158+
}
159+
124160
@Override
125161
public void decoder(Decoder<?> decoder) {
126162
reader(new DecoderHttpMessageReader<>(decoder));

spring-web/src/main/java/org/springframework/http/codec/support/BaseDefaultCodecs.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,24 @@ class BaseDefaultCodecs implements CodecConfigurer.DefaultCodecs {
105105
private boolean registerDefaults = true;
106106

107107

108+
BaseDefaultCodecs() {
109+
}
110+
111+
/**
112+
* Create a deep copy of the given {@link BaseDefaultCodecs}.
113+
*/
114+
protected BaseDefaultCodecs(BaseDefaultCodecs other) {
115+
this.jackson2JsonDecoder = other.jackson2JsonDecoder;
116+
this.jackson2JsonEncoder = other.jackson2JsonEncoder;
117+
this.protobufDecoder = other.protobufDecoder;
118+
this.protobufEncoder = other.protobufEncoder;
119+
this.jaxb2Decoder = other.jaxb2Decoder;
120+
this.jaxb2Encoder = other.jaxb2Encoder;
121+
this.maxInMemorySize = other.maxInMemorySize;
122+
this.enableLoggingRequestDetails = other.enableLoggingRequestDetails;
123+
this.registerDefaults = other.registerDefaults;
124+
}
125+
108126
@Override
109127
public void jackson2JsonDecoder(Decoder<?> decoder) {
110128
this.jackson2JsonDecoder = decoder;

spring-web/src/main/java/org/springframework/http/codec/support/ClientDefaultCodecsImpl.java

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2018 the original author or authors.
2+
* Copyright 2002-2019 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -49,6 +49,17 @@ class ClientDefaultCodecsImpl extends BaseDefaultCodecs implements ClientCodecCo
4949
private Supplier<List<HttpMessageWriter<?>>> partWritersSupplier;
5050

5151

52+
ClientDefaultCodecsImpl() {
53+
}
54+
55+
ClientDefaultCodecsImpl(ClientDefaultCodecsImpl other) {
56+
super(other);
57+
this.multipartCodecs = new DefaultMultipartCodecs(other.multipartCodecs);
58+
this.sseDecoder = other.sseDecoder;
59+
this.partWritersSupplier = other.partWritersSupplier;
60+
}
61+
62+
5263
/**
5364
* Set a supplier for part writers to use when
5465
* {@link #multipartCodecs()} are not explicitly configured.
@@ -73,6 +84,14 @@ public void serverSentEventDecoder(Decoder<?> decoder) {
7384
this.sseDecoder = decoder;
7485
}
7586

87+
@Override
88+
public ClientDefaultCodecsImpl clone() {
89+
ClientDefaultCodecsImpl codecs = new ClientDefaultCodecsImpl();
90+
codecs.multipartCodecs = this.multipartCodecs;
91+
codecs.sseDecoder = this.sseDecoder;
92+
codecs.partWritersSupplier = this.partWritersSupplier;
93+
return codecs;
94+
}
7695

7796
@Override
7897
protected void extendObjectReaders(List<HttpMessageReader<?>> objectReaders) {
@@ -116,6 +135,17 @@ private static class DefaultMultipartCodecs implements ClientCodecConfigurer.Mul
116135

117136
private final List<HttpMessageWriter<?>> writers = new ArrayList<>();
118137

138+
139+
DefaultMultipartCodecs() {
140+
}
141+
142+
DefaultMultipartCodecs(@Nullable DefaultMultipartCodecs other) {
143+
if (other != null) {
144+
this.writers.addAll(other.writers);
145+
}
146+
}
147+
148+
119149
@Override
120150
public ClientCodecConfigurer.MultipartCodecs encoder(Encoder<?> encoder) {
121151
writer(new EncoderHttpMessageWriter<>(encoder));

spring-web/src/main/java/org/springframework/http/codec/support/DefaultClientCodecConfigurer.java

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2018 the original author or authors.
2+
* Copyright 2002-2019 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -26,14 +26,30 @@
2626
*/
2727
public class DefaultClientCodecConfigurer extends BaseCodecConfigurer implements ClientCodecConfigurer {
2828

29+
2930
public DefaultClientCodecConfigurer() {
3031
super(new ClientDefaultCodecsImpl());
3132
((ClientDefaultCodecsImpl) defaultCodecs()).setPartWritersSupplier(() -> getWritersInternal(true));
3233
}
3334

35+
private DefaultClientCodecConfigurer(DefaultClientCodecConfigurer other) {
36+
super(other);
37+
}
38+
39+
3440
@Override
3541
public ClientDefaultCodecs defaultCodecs() {
3642
return (ClientDefaultCodecs) super.defaultCodecs();
3743
}
3844

45+
@Override
46+
public DefaultClientCodecConfigurer clone() {
47+
return new DefaultClientCodecConfigurer(this);
48+
}
49+
50+
@Override
51+
protected BaseDefaultCodecs cloneDefaultCodecs() {
52+
return new ClientDefaultCodecsImpl((ClientDefaultCodecsImpl) defaultCodecs());
53+
}
54+
3955
}

spring-web/src/main/java/org/springframework/http/codec/support/DefaultServerCodecConfigurer.java

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2018 the original author or authors.
2+
* Copyright 2002-2019 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -26,13 +26,28 @@
2626
*/
2727
public class DefaultServerCodecConfigurer extends BaseCodecConfigurer implements ServerCodecConfigurer {
2828

29+
2930
public DefaultServerCodecConfigurer() {
3031
super(new ServerDefaultCodecsImpl());
3132
}
3233

34+
private DefaultServerCodecConfigurer(BaseCodecConfigurer other) {
35+
super(other);
36+
}
37+
38+
3339
@Override
3440
public ServerDefaultCodecs defaultCodecs() {
3541
return (ServerDefaultCodecs) super.defaultCodecs();
3642
}
3743

44+
@Override
45+
public DefaultServerCodecConfigurer clone() {
46+
return new DefaultServerCodecConfigurer(this);
47+
}
48+
49+
@Override
50+
protected BaseDefaultCodecs cloneDefaultCodecs() {
51+
return new ServerDefaultCodecsImpl((ServerDefaultCodecsImpl) defaultCodecs());
52+
}
3853
}

0 commit comments

Comments
 (0)