Skip to content

Commit 7587af3

Browse files
committed
Merge pull request spring-projects#16342 Pascal Zwick
* pr/16342: Polish "Simplify the configuration of the ProtocolHandler" Simplify the configuration of the ProtocolHandler
2 parents 4440c30 + ad767ca commit 7587af3

File tree

10 files changed

+299
-2
lines changed

10 files changed

+299
-2
lines changed

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/ReactiveWebServerFactoryConfiguration.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import org.springframework.boot.web.embedded.netty.NettyReactiveWebServerFactory;
2929
import org.springframework.boot.web.embedded.tomcat.TomcatConnectorCustomizer;
3030
import org.springframework.boot.web.embedded.tomcat.TomcatContextCustomizer;
31+
import org.springframework.boot.web.embedded.tomcat.TomcatProtocolHandlerCustomizer;
3132
import org.springframework.boot.web.embedded.tomcat.TomcatReactiveWebServerFactory;
3233
import org.springframework.boot.web.embedded.undertow.UndertowReactiveWebServerFactory;
3334
import org.springframework.boot.web.reactive.server.ReactiveWebServerFactory;
@@ -76,12 +77,16 @@ static class EmbeddedTomcat {
7677
@Bean
7778
public TomcatReactiveWebServerFactory tomcatReactiveWebServerFactory(
7879
ObjectProvider<TomcatConnectorCustomizer> connectorCustomizers,
79-
ObjectProvider<TomcatContextCustomizer> contextCustomizers) {
80+
ObjectProvider<TomcatContextCustomizer> contextCustomizers,
81+
ObjectProvider<TomcatProtocolHandlerCustomizer<?>> protocolHandlerCustomizers) {
8082
TomcatReactiveWebServerFactory factory = new TomcatReactiveWebServerFactory();
8183
factory.getTomcatConnectorCustomizers().addAll(
8284
connectorCustomizers.orderedStream().collect(Collectors.toList()));
8385
factory.getTomcatContextCustomizers().addAll(
8486
contextCustomizers.orderedStream().collect(Collectors.toList()));
87+
factory.getTomcatProtocolHandlerCustomizers()
88+
.addAll(protocolHandlerCustomizers.orderedStream()
89+
.collect(Collectors.toList()));
8590
return factory;
8691
}
8792

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/ServletWebServerFactoryConfiguration.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory;
3636
import org.springframework.boot.web.embedded.tomcat.TomcatConnectorCustomizer;
3737
import org.springframework.boot.web.embedded.tomcat.TomcatContextCustomizer;
38+
import org.springframework.boot.web.embedded.tomcat.TomcatProtocolHandlerCustomizer;
3839
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
3940
import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory;
4041
import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
@@ -66,12 +67,16 @@ public static class EmbeddedTomcat {
6667
@Bean
6768
public TomcatServletWebServerFactory tomcatServletWebServerFactory(
6869
ObjectProvider<TomcatConnectorCustomizer> connectorCustomizers,
69-
ObjectProvider<TomcatContextCustomizer> contextCustomizers) {
70+
ObjectProvider<TomcatContextCustomizer> contextCustomizers,
71+
ObjectProvider<TomcatProtocolHandlerCustomizer<?>> protocolHandlerCustomizers) {
7072
TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();
7173
factory.getTomcatConnectorCustomizers().addAll(
7274
connectorCustomizers.orderedStream().collect(Collectors.toList()));
7375
factory.getTomcatContextCustomizers().addAll(
7476
contextCustomizers.orderedStream().collect(Collectors.toList()));
77+
factory.getTomcatProtocolHandlerCustomizers()
78+
.addAll(protocolHandlerCustomizers.orderedStream()
79+
.collect(Collectors.toList()));
7580
return factory;
7681
}
7782

spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/ReactiveWebServerFactoryAutoConfigurationTests.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner;
2424
import org.springframework.boot.web.embedded.tomcat.TomcatConnectorCustomizer;
2525
import org.springframework.boot.web.embedded.tomcat.TomcatContextCustomizer;
26+
import org.springframework.boot.web.embedded.tomcat.TomcatProtocolHandlerCustomizer;
2627
import org.springframework.boot.web.embedded.tomcat.TomcatReactiveWebServerFactory;
2728
import org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebApplicationContext;
2829
import org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext;
@@ -131,6 +132,21 @@ public void tomcatContextCustomizerBeanIsAddedToFactory() {
131132
});
132133
}
133134

135+
@Test
136+
public void tomcatProtocolHandlerCustomizerBeanIsAddedToFactory() {
137+
ReactiveWebApplicationContextRunner runner = new ReactiveWebApplicationContextRunner(
138+
AnnotationConfigReactiveWebApplicationContext::new)
139+
.withConfiguration(AutoConfigurations
140+
.of(ReactiveWebServerFactoryAutoConfiguration.class))
141+
.withUserConfiguration(
142+
TomcatProtocolHandlerCustomizerConfiguration.class);
143+
runner.run((context) -> {
144+
TomcatReactiveWebServerFactory factory = context
145+
.getBean(TomcatReactiveWebServerFactory.class);
146+
assertThat(factory.getTomcatProtocolHandlerCustomizers()).hasSize(1);
147+
});
148+
}
149+
134150
@Configuration(proxyBeanMethods = false)
135151
protected static class HttpHandlerConfiguration {
136152

@@ -193,4 +209,15 @@ public TomcatContextCustomizer contextCustomizer() {
193209

194210
}
195211

212+
@Configuration(proxyBeanMethods = false)
213+
static class TomcatProtocolHandlerCustomizerConfiguration {
214+
215+
@Bean
216+
public TomcatProtocolHandlerCustomizer protocolHandlerCustomizer() {
217+
return (protocolHandler) -> {
218+
};
219+
}
220+
221+
}
222+
196223
}

spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/ServletWebServerFactoryAutoConfigurationTests.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
3333
import org.springframework.boot.web.embedded.tomcat.TomcatConnectorCustomizer;
3434
import org.springframework.boot.web.embedded.tomcat.TomcatContextCustomizer;
35+
import org.springframework.boot.web.embedded.tomcat.TomcatProtocolHandlerCustomizer;
3536
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
3637
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
3738
import org.springframework.boot.web.servlet.ServletRegistrationBean;
@@ -170,6 +171,21 @@ public void tomcatContextCustomizerBeanIsAddedToFactory() {
170171
});
171172
}
172173

174+
@Test
175+
public void tomcatProtocolHandlerCustomizerBeanIsAddedToFactory() {
176+
WebApplicationContextRunner runner = new WebApplicationContextRunner(
177+
AnnotationConfigServletWebServerApplicationContext::new)
178+
.withConfiguration(AutoConfigurations
179+
.of(ServletWebServerFactoryAutoConfiguration.class))
180+
.withUserConfiguration(
181+
TomcatProtocolHandlerCustomizerConfiguration.class);
182+
runner.run((context) -> {
183+
TomcatServletWebServerFactory factory = context
184+
.getBean(TomcatServletWebServerFactory.class);
185+
assertThat(factory.getTomcatProtocolHandlerCustomizers()).hasSize(1);
186+
});
187+
}
188+
173189
private ContextConsumer<AssertableWebApplicationContext> verifyContext() {
174190
return this::verifyContext;
175191
}
@@ -308,4 +324,15 @@ public TomcatContextCustomizer contextCustomizer() {
308324

309325
}
310326

327+
@Configuration(proxyBeanMethods = false)
328+
static class TomcatProtocolHandlerCustomizerConfiguration {
329+
330+
@Bean
331+
public TomcatProtocolHandlerCustomizer protocolHandlerCustomizer() {
332+
return (protocolHandler) -> {
333+
};
334+
}
335+
336+
}
337+
311338
}

spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/ConfigurableTomcatWebServerFactory.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,14 @@ public interface ConfigurableTomcatWebServerFactory extends ConfigurableWebServe
6868
*/
6969
void addContextCustomizers(TomcatContextCustomizer... tomcatContextCustomizers);
7070

71+
/**
72+
* Add {@link TomcatProtocolHandlerCustomizer}s that should be added to the Tomcat
73+
* {@link Connector}.
74+
* @param tomcatProtocolHandlerCustomizers the customizers to add
75+
*/
76+
void addProtocolHandlerCustomizers(
77+
TomcatProtocolHandlerCustomizer<?>... tomcatProtocolHandlerCustomizers);
78+
7179
/**
7280
* Set the character encoding to use for URL decoding. If not specified 'UTF-8' will
7381
* be used.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
* Copyright 2012-2019 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.web.embedded.tomcat;
18+
19+
import org.apache.catalina.connector.Connector;
20+
import org.apache.coyote.ProtocolHandler;
21+
22+
/**
23+
* Callback interface that can be used to customize the {@link ProtocolHandler} on the
24+
* {@link Connector}.
25+
*
26+
* @param <T> specified type for customization based on {@link ProtocolHandler}
27+
* @author Pascal Zwick
28+
* @see ConfigurableTomcatWebServerFactory
29+
* @since 2.2.0
30+
*/
31+
@FunctionalInterface
32+
public interface TomcatProtocolHandlerCustomizer<T extends ProtocolHandler> {
33+
34+
/**
35+
* Customize the protocol handler.
36+
* @param protocolHandler the protocol handler to customize
37+
*/
38+
void customize(T protocolHandler);
39+
40+
}

spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/TomcatReactiveWebServerFactory.java

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,11 @@
3434
import org.apache.catalina.loader.WebappLoader;
3535
import org.apache.catalina.startup.Tomcat;
3636
import org.apache.coyote.AbstractProtocol;
37+
import org.apache.coyote.ProtocolHandler;
3738
import org.apache.coyote.http2.Http2Protocol;
3839
import org.apache.tomcat.util.scan.StandardJarScanFilter;
3940

41+
import org.springframework.boot.util.LambdaSafe;
4042
import org.springframework.boot.web.reactive.server.AbstractReactiveWebServerFactory;
4143
import org.springframework.boot.web.reactive.server.ReactiveWebServerFactory;
4244
import org.springframework.boot.web.server.WebServer;
@@ -72,6 +74,8 @@ public class TomcatReactiveWebServerFactory extends AbstractReactiveWebServerFac
7274

7375
private List<TomcatConnectorCustomizer> tomcatConnectorCustomizers = new ArrayList<>();
7476

77+
private List<TomcatProtocolHandlerCustomizer<?>> tomcatProtocolHandlerCustomizers = new ArrayList<>();
78+
7579
private String protocol = DEFAULT_PROTOCOL;
7680

7781
private Charset uriEncoding = DEFAULT_CHARSET;
@@ -168,6 +172,7 @@ protected void customizeConnector(Connector connector) {
168172
if (connector.getProtocolHandler() instanceof AbstractProtocol) {
169173
customizeProtocol((AbstractProtocol<?>) connector.getProtocolHandler());
170174
}
175+
invokeProtocolHandlerCustomizers(connector);
171176
if (getUriEncoding() != null) {
172177
connector.setURIEncoding(getUriEncoding().name());
173178
}
@@ -184,6 +189,15 @@ protected void customizeConnector(Connector connector) {
184189
}
185190
}
186191

192+
@SuppressWarnings("unchecked")
193+
private void invokeProtocolHandlerCustomizers(Connector connector) {
194+
ProtocolHandler protocolHandler = connector.getProtocolHandler();
195+
LambdaSafe
196+
.callbacks(TomcatProtocolHandlerCustomizer.class,
197+
this.tomcatProtocolHandlerCustomizers, protocolHandler)
198+
.invoke((customizer) -> customizer.customize(protocolHandler));
199+
}
200+
187201
private void customizeProtocol(AbstractProtocol<?> protocol) {
188202
if (getAddress() != null) {
189203
protocol.setAddress(getAddress());
@@ -275,6 +289,42 @@ public Collection<TomcatConnectorCustomizer> getTomcatConnectorCustomizers() {
275289
return this.tomcatConnectorCustomizers;
276290
}
277291

292+
/**
293+
* Set {@link TomcatProtocolHandlerCustomizer}s that should be applied to the Tomcat
294+
* {@link Connector}. Calling this method will replace any existing customizers.
295+
* @param tomcatProtocolHandlerCustomizers the customizers to set
296+
*/
297+
public void setTomcatProtocolHandlerCustomizers(
298+
Collection<? extends TomcatProtocolHandlerCustomizer<?>> tomcatProtocolHandlerCustomizers) {
299+
Assert.notNull(tomcatProtocolHandlerCustomizers,
300+
"TomcatProtocolHandlerCustomizers must not be null");
301+
this.tomcatProtocolHandlerCustomizers = new ArrayList<>(
302+
tomcatProtocolHandlerCustomizers);
303+
}
304+
305+
/**
306+
* Add {@link TomcatProtocolHandlerCustomizer}s that should be added to the Tomcat
307+
* {@link Connector}.
308+
* @param tomcatProtocolHandlerCustomizers the customizers to add
309+
*/
310+
@Override
311+
public void addProtocolHandlerCustomizers(
312+
TomcatProtocolHandlerCustomizer<?>... tomcatProtocolHandlerCustomizers) {
313+
Assert.notNull(tomcatProtocolHandlerCustomizers,
314+
"TomcatProtocolHandlerCustomizers must not be null");
315+
this.tomcatProtocolHandlerCustomizers
316+
.addAll(Arrays.asList(tomcatProtocolHandlerCustomizers));
317+
}
318+
319+
/**
320+
* Returns a mutable collection of the {@link TomcatProtocolHandlerCustomizer}s that
321+
* will be applied to the Tomcat {@link Connector}.
322+
* @return the customizers that will be applied
323+
*/
324+
public Collection<TomcatProtocolHandlerCustomizer<?>> getTomcatProtocolHandlerCustomizers() {
325+
return this.tomcatProtocolHandlerCustomizers;
326+
}
327+
278328
@Override
279329
public void addEngineValves(Valve... engineValves) {
280330
Assert.notNull(engineValves, "Valves must not be null");

spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/tomcat/TomcatServletWebServerFactory.java

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,11 @@
5858
import org.apache.catalina.webresources.EmptyResource;
5959
import org.apache.catalina.webresources.StandardRoot;
6060
import org.apache.coyote.AbstractProtocol;
61+
import org.apache.coyote.ProtocolHandler;
6162
import org.apache.coyote.http2.Http2Protocol;
6263
import org.apache.tomcat.util.scan.StandardJarScanFilter;
6364

65+
import org.springframework.boot.util.LambdaSafe;
6466
import org.springframework.boot.web.server.ErrorPage;
6567
import org.springframework.boot.web.server.MimeMappings;
6668
import org.springframework.boot.web.server.WebServer;
@@ -117,6 +119,8 @@ public class TomcatServletWebServerFactory extends AbstractServletWebServerFacto
117119

118120
private List<TomcatConnectorCustomizer> tomcatConnectorCustomizers = new ArrayList<>();
119121

122+
private List<TomcatProtocolHandlerCustomizer<?>> tomcatProtocolHandlerCustomizers = new ArrayList<>();
123+
120124
private List<Connector> additionalTomcatConnectors = new ArrayList<>();
121125

122126
private ResourceLoader resourceLoader;
@@ -303,6 +307,7 @@ protected void customizeConnector(Connector connector) {
303307
if (connector.getProtocolHandler() instanceof AbstractProtocol) {
304308
customizeProtocol((AbstractProtocol<?>) connector.getProtocolHandler());
305309
}
310+
invokeProtocolHandlerCustomizers(connector);
306311
if (getUriEncoding() != null) {
307312
connector.setURIEncoding(getUriEncoding().name());
308313
}
@@ -325,6 +330,15 @@ private void customizeProtocol(AbstractProtocol<?> protocol) {
325330
}
326331
}
327332

333+
@SuppressWarnings("unchecked")
334+
private void invokeProtocolHandlerCustomizers(Connector connector) {
335+
ProtocolHandler protocolHandler = connector.getProtocolHandler();
336+
LambdaSafe
337+
.callbacks(TomcatProtocolHandlerCustomizer.class,
338+
this.tomcatProtocolHandlerCustomizers, protocolHandler)
339+
.invoke((customizer) -> customizer.customize(protocolHandler));
340+
}
341+
328342
private void customizeSsl(Connector connector) {
329343
new SslConnectorCustomizer(getSsl(), getSslStoreProvider()).customize(connector);
330344
if (getHttp2() != null && getHttp2().isEnabled()) {
@@ -619,6 +633,42 @@ public Collection<TomcatConnectorCustomizer> getTomcatConnectorCustomizers() {
619633
return this.tomcatConnectorCustomizers;
620634
}
621635

636+
/**
637+
* Set {@link TomcatProtocolHandlerCustomizer}s that should be applied to the Tomcat
638+
* {@link Connector}. Calling this method will replace any existing customizers.
639+
* @param tomcatProtocolHandlerCustomizer the customizers to set
640+
*/
641+
public void setTomcatProtocolHandlerCustomizers(
642+
Collection<? extends TomcatProtocolHandlerCustomizer<?>> tomcatProtocolHandlerCustomizer) {
643+
Assert.notNull(tomcatProtocolHandlerCustomizer,
644+
"TomcatProtocolHandlerCustomizers must not be null");
645+
this.tomcatProtocolHandlerCustomizers = new ArrayList<>(
646+
tomcatProtocolHandlerCustomizer);
647+
}
648+
649+
/**
650+
* Add {@link TomcatProtocolHandlerCustomizer}s that should be added to the Tomcat
651+
* {@link Connector}.
652+
* @param tomcatProtocolHandlerCustomizers the customizers to add
653+
*/
654+
@Override
655+
public void addProtocolHandlerCustomizers(
656+
TomcatProtocolHandlerCustomizer<?>... tomcatProtocolHandlerCustomizers) {
657+
Assert.notNull(tomcatProtocolHandlerCustomizers,
658+
"TomcatProtocolHandlerCustomizers must not be null");
659+
this.tomcatProtocolHandlerCustomizers
660+
.addAll(Arrays.asList(tomcatProtocolHandlerCustomizers));
661+
}
662+
663+
/**
664+
* Returns a mutable collection of the {@link TomcatProtocolHandlerCustomizer}s that
665+
* will be applied to the Tomcat {@link Connector}.
666+
* @return the customizers that will be applied
667+
*/
668+
public Collection<TomcatProtocolHandlerCustomizer<?>> getTomcatProtocolHandlerCustomizers() {
669+
return this.tomcatProtocolHandlerCustomizers;
670+
}
671+
622672
/**
623673
* Add {@link Connector}s in addition to the default connector, e.g. for SSL or AJP
624674
* @param connectors the connectors to add

0 commit comments

Comments
 (0)