mirror of
https://github.com/spring-projects/spring-boot.git
synced 2024-07-15 01:07:30 +08:00
Polish Undertow contribution
Closes gh-1779
This commit is contained in:
parent
c501b889af
commit
1864d79077
3
.gitignore
vendored
3
.gitignore
vendored
@ -28,5 +28,4 @@ overridedb.*
|
||||
*.ipr
|
||||
*.iws
|
||||
.idea
|
||||
*.jar
|
||||
.DS_Store
|
||||
*.jar
|
@ -54,6 +54,7 @@ import org.springframework.util.ObjectUtils;
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @author Dave Syer
|
||||
* @author Ivan Sopov
|
||||
*/
|
||||
@Order(Ordered.HIGHEST_PRECEDENCE)
|
||||
@Configuration
|
||||
@ -90,7 +91,7 @@ public class EmbeddedServletContainerAutoConfiguration {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Nested configuration if Undertow is being used.
|
||||
*/
|
||||
@ -105,7 +106,6 @@ public class EmbeddedServletContainerAutoConfiguration {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Registers a {@link EmbeddedServletContainerCustomizerBeanPostProcessor}. Registered
|
||||
|
@ -53,6 +53,7 @@ import org.springframework.util.StringUtils;
|
||||
* @author Dave Syer
|
||||
* @author Stephane Nicoll
|
||||
* @author Andy Wilkinson
|
||||
* @author Ivan Sopov
|
||||
*/
|
||||
@ConfigurationProperties(prefix = "server", ignoreUnknownFields = false)
|
||||
public class ServerProperties implements EmbeddedServletContainerCustomizer {
|
||||
@ -72,7 +73,7 @@ public class ServerProperties implements EmbeddedServletContainerCustomizer {
|
||||
private String servletPath = "/";
|
||||
|
||||
private final Tomcat tomcat = new Tomcat();
|
||||
|
||||
|
||||
private final Undertow undertow = new Undertow();
|
||||
|
||||
private final Map<String, String> contextParameters = new HashMap<String, String>();
|
||||
@ -220,62 +221,6 @@ public class ServerProperties implements EmbeddedServletContainerCustomizer {
|
||||
return prefix + path;
|
||||
}
|
||||
|
||||
public static class Undertow {
|
||||
private Integer bufferSize;
|
||||
private Integer buffersPerRegion;
|
||||
private Integer ioThreads;
|
||||
private Integer workerThreads;
|
||||
private Boolean directBuffers;
|
||||
|
||||
public Integer getBufferSize() {
|
||||
return this.bufferSize;
|
||||
}
|
||||
|
||||
public void setBufferSize(Integer bufferSize) {
|
||||
this.bufferSize = bufferSize;
|
||||
}
|
||||
|
||||
public Integer getBuffersPerRegion() {
|
||||
return this.buffersPerRegion;
|
||||
}
|
||||
|
||||
public void setBuffersPerRegion(Integer buffersPerRegion) {
|
||||
this.buffersPerRegion = buffersPerRegion;
|
||||
}
|
||||
|
||||
public Integer getIoThreads() {
|
||||
return this.ioThreads;
|
||||
}
|
||||
|
||||
public void setIoThreads(Integer ioThreads) {
|
||||
this.ioThreads = ioThreads;
|
||||
}
|
||||
|
||||
public Integer getWorkerThreads() {
|
||||
return this.workerThreads;
|
||||
}
|
||||
|
||||
public void setWorkerThreads(Integer workerThreads) {
|
||||
this.workerThreads = workerThreads;
|
||||
}
|
||||
|
||||
public Boolean getDirectBuffers() {
|
||||
return this.directBuffers;
|
||||
}
|
||||
|
||||
public void setDirectBuffers(Boolean directBuffers) {
|
||||
this.directBuffers = directBuffers;
|
||||
}
|
||||
|
||||
void customizeUndertow(UndertowEmbeddedServletContainerFactory factory) {
|
||||
factory.setBufferSize(bufferSize);
|
||||
factory.setBuffersPerRegion(buffersPerRegion);
|
||||
factory.setIoThreads(ioThreads);
|
||||
factory.setWorkerThreads(workerThreads);
|
||||
factory.setDirectBuffers(directBuffers);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Tomcat {
|
||||
|
||||
private String accessLogPattern;
|
||||
@ -462,4 +407,66 @@ public class ServerProperties implements EmbeddedServletContainerCustomizer {
|
||||
|
||||
}
|
||||
|
||||
public static class Undertow {
|
||||
|
||||
private Integer bufferSize;
|
||||
|
||||
private Integer buffersPerRegion;
|
||||
|
||||
private Integer ioThreads;
|
||||
|
||||
private Integer workerThreads;
|
||||
|
||||
private Boolean directBuffers;
|
||||
|
||||
public Integer getBufferSize() {
|
||||
return this.bufferSize;
|
||||
}
|
||||
|
||||
public void setBufferSize(Integer bufferSize) {
|
||||
this.bufferSize = bufferSize;
|
||||
}
|
||||
|
||||
public Integer getBuffersPerRegion() {
|
||||
return this.buffersPerRegion;
|
||||
}
|
||||
|
||||
public void setBuffersPerRegion(Integer buffersPerRegion) {
|
||||
this.buffersPerRegion = buffersPerRegion;
|
||||
}
|
||||
|
||||
public Integer getIoThreads() {
|
||||
return this.ioThreads;
|
||||
}
|
||||
|
||||
public void setIoThreads(Integer ioThreads) {
|
||||
this.ioThreads = ioThreads;
|
||||
}
|
||||
|
||||
public Integer getWorkerThreads() {
|
||||
return this.workerThreads;
|
||||
}
|
||||
|
||||
public void setWorkerThreads(Integer workerThreads) {
|
||||
this.workerThreads = workerThreads;
|
||||
}
|
||||
|
||||
public Boolean getDirectBuffers() {
|
||||
return this.directBuffers;
|
||||
}
|
||||
|
||||
public void setDirectBuffers(Boolean directBuffers) {
|
||||
this.directBuffers = directBuffers;
|
||||
}
|
||||
|
||||
void customizeUndertow(UndertowEmbeddedServletContainerFactory factory) {
|
||||
factory.setBufferSize(this.bufferSize);
|
||||
factory.setBuffersPerRegion(this.buffersPerRegion);
|
||||
factory.setIoThreads(this.ioThreads);
|
||||
factory.setWorkerThreads(this.workerThreads);
|
||||
factory.setDirectBuffers(this.directBuffers);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -16,9 +16,7 @@
|
||||
|
||||
package org.springframework.boot.autoconfigure.web;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
import javax.servlet.MultipartConfigElement;
|
||||
|
||||
@ -65,6 +63,7 @@ import static org.mockito.Mockito.mock;
|
||||
* @author Greg Turnquist
|
||||
* @author Dave Syer
|
||||
* @author Josh Long
|
||||
* @author Ivan Sopov
|
||||
*/
|
||||
public class MultipartAutoConfigurationTests {
|
||||
|
||||
|
@ -47,6 +47,7 @@ import static org.mockito.Mockito.verify;
|
||||
* Tests for {@link ServerPropertiesAutoConfiguration}.
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @author Ivan Sopov
|
||||
*/
|
||||
public class ServerPropertiesAutoConfigurationTests {
|
||||
|
||||
@ -112,8 +113,7 @@ public class ServerPropertiesAutoConfigurationTests {
|
||||
// factory should take precedence...
|
||||
assertEquals(3000, containerFactory.getPort());
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void customizeWithUndertowContainerFactory() throws Exception {
|
||||
this.context = new AnnotationConfigEmbeddedWebApplicationContext();
|
||||
@ -127,7 +127,6 @@ public class ServerPropertiesAutoConfigurationTests {
|
||||
assertNotNull(server);
|
||||
assertEquals(3000, containerFactory.getPort());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void customizeTomcatWithCustomizer() throws Exception {
|
||||
@ -186,7 +185,7 @@ public class ServerPropertiesAutoConfigurationTests {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Configuration
|
||||
protected static class CustomUndertowContainerConfig {
|
||||
|
||||
@ -203,9 +202,6 @@ public class ServerPropertiesAutoConfigurationTests {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Configuration
|
||||
protected static class CustomizeConfig {
|
||||
|
@ -127,10 +127,10 @@
|
||||
<thymeleaf-layout-dialect.version>1.2.7</thymeleaf-layout-dialect.version>
|
||||
<thymeleaf-extras-data-attribute.version>1.3</thymeleaf-extras-data-attribute.version>
|
||||
<tomcat.version>8.0.15</tomcat.version>
|
||||
<undertow.version>1.1.0.Final</undertow.version>
|
||||
<velocity.version>1.7</velocity.version>
|
||||
<velocity-tools.version>2.0</velocity-tools.version>
|
||||
<wsdl4j.version>1.6.3</wsdl4j.version>
|
||||
<undertow.version>1.1.0.Final</undertow.version>
|
||||
</properties>
|
||||
<prerequisites>
|
||||
<maven>3.0.2</maven>
|
||||
@ -540,6 +540,16 @@
|
||||
<artifactId>metrics-servlets</artifactId>
|
||||
<version>${dropwizard-metrics.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.undertow</groupId>
|
||||
<artifactId>undertow-core</artifactId>
|
||||
<version>${undertow.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.undertow</groupId>
|
||||
<artifactId>undertow-servlet</artifactId>
|
||||
<version>${undertow.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.cache</groupId>
|
||||
<artifactId>cache-api</artifactId>
|
||||
@ -707,11 +717,6 @@
|
||||
<artifactId>tomcat-jsp-api</artifactId>
|
||||
<version>${tomcat.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.undertow</groupId>
|
||||
<artifactId>undertow-servlet</artifactId>
|
||||
<version>${undertow.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.velocity</groupId>
|
||||
<artifactId>velocity</artifactId>
|
||||
|
@ -158,8 +158,8 @@ for our starter REST application:
|
||||
|
||||
Spring Boot makes `-D` arguments available as properties accessible from a Spring
|
||||
`Environment` instance. The `server.port` configuration property is fed to the embedded
|
||||
Tomcat or Jetty instance which then uses it when it starts up. The `$PORT` environment
|
||||
variable is assigned to us by the Heroku PaaS.
|
||||
Tomcat, Jetty or Undertow instance which then uses it when it starts up. The `$PORT`
|
||||
environment variable is assigned to us by the Heroku PaaS.
|
||||
|
||||
Heroku by default will use Java 1.6. This is fine as long as your Maven or Gradle build
|
||||
is set to use the same version (Maven users can use the `java.version` property). If you
|
||||
|
@ -556,6 +556,61 @@ of ways. Or the nuclear option is to add your own `JettyEmbeddedServletContainer
|
||||
|
||||
|
||||
|
||||
[[howto-use-undertow-instead-of-tomcat]]
|
||||
=== Use Undertow instead of Tomcat
|
||||
Using Undertow instead of Tomcat is very similar to <<howto-use-jetty-instead-of-tomcat,
|
||||
using Jetty instead of Tomcat>>. You need to exclude the Tomcat dependencies and include
|
||||
the Undertow starter instead.
|
||||
|
||||
Example in Maven:
|
||||
|
||||
[source,xml,indent=0,subs="verbatim,quotes,attributes"]
|
||||
----
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-tomcat</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-undertow</artifactId>
|
||||
</dependency>
|
||||
----
|
||||
|
||||
Example in Gradle:
|
||||
|
||||
[source,groovy,indent=0,subs="verbatim,quotes,attributes"]
|
||||
----
|
||||
configurations {
|
||||
compile.exclude module: "spring-boot-starter-tomcat"
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile("org.springframework.boot:spring-boot-starter-web:{spring-boot-version}")
|
||||
compile("org.springframework.boot:spring-boot-starter-undertow:{spring-boot-version}")
|
||||
// ...
|
||||
}
|
||||
----
|
||||
|
||||
|
||||
[[howto-configure-undertow]]
|
||||
=== Configure Undertow
|
||||
Generally you can follow the advice from
|
||||
_<<howto-discover-build-in-options-for-external-properties>>_ about
|
||||
`@ConfigurationProperties` (`ServerProperties` and `ServerProperties.Undertow are the
|
||||
main ones here), but also look at
|
||||
`EmbeddedServletContainerCustomizer`. Once you have access to the
|
||||
`UndertowEmbeddedServletContainerFactory` you can use an `UndertowBuilderCustomizer` to
|
||||
modify Undertow's configuration to meet your needs. Or the nuclear option is to add your
|
||||
own `UndertowEmbeddedServletContainerFactory`.
|
||||
|
||||
|
||||
|
||||
[[howto-use-tomcat-8]]
|
||||
=== Use Tomcat 8
|
||||
Tomcat 8 works with Spring Boot, but the default is to use Tomcat 7 (so we can support
|
||||
|
@ -810,8 +810,8 @@ possible.
|
||||
[[boot-features-developing-web-applications]]
|
||||
== Developing web applications
|
||||
Spring Boot is well suited for web application development. You can easily create a
|
||||
self-contained HTTP server using embedded Tomcat or Jetty. Most web applications will
|
||||
use the `spring-boot-starter-web` module to get up and running quickly.
|
||||
self-contained HTTP server using embedded Tomcat, Jetty, or Undertow. Most web
|
||||
applications will use the `spring-boot-starter-web` module to get up and running quickly.
|
||||
|
||||
If you haven't yet developed a Spring Boot web application you can follow the
|
||||
"Hello World!" example in the
|
||||
@ -1093,9 +1093,9 @@ asks for them to be scanned in its `Filter` registration).
|
||||
|
||||
[[boot-features-embedded-container]]
|
||||
=== Embedded servlet container support
|
||||
Spring Boot includes support for embedded Tomcat and Jetty servers. Most developers will
|
||||
simply use the appropriate '`Starter POM`' to obtain a fully configured instance. By
|
||||
default both Tomcat and Jetty will listen for HTTP requests on port `8080`.
|
||||
Spring Boot includes support for embedded Tomcat, Jetty, and Undertow servers. Most
|
||||
developers will simply use the appropriate '`Starter POM`' to obtain a fully configured
|
||||
instance. By default the embedded server will listen for HTTP requests on port `8080`.
|
||||
|
||||
|
||||
|
||||
@ -1121,8 +1121,9 @@ interface.
|
||||
Under the hood Spring Boot uses a new type of `ApplicationContext` for embedded
|
||||
servlet container support. The `EmbeddedWebApplicationContext` is a special
|
||||
type of `WebApplicationContext` that bootstraps itself by searching for a single
|
||||
`EmbeddedServletContainerFactory` bean. Usually a `TomcatEmbeddedServletContainerFactory`
|
||||
or `JettyEmbeddedServletContainerFactory` will have been auto-configured.
|
||||
`EmbeddedServletContainerFactory` bean. Usually a `TomcatEmbeddedServletContainerFactory`,
|
||||
`JettyEmbeddedServletContainerFactory`, or `UndertowEmbeddedServletContainerFactory` will
|
||||
have been auto-configured.
|
||||
|
||||
NOTE: You usually won't need to be aware of these implementation classes. Most
|
||||
applications will be auto-configured and the appropriate `ApplicationContext` and
|
||||
@ -1176,8 +1177,8 @@ methods.
|
||||
[[boot-features-customizing-configurableembeddedservletcontainerfactory-directly]]
|
||||
===== Customizing ConfigurableEmbeddedServletContainer directly
|
||||
If the above customization techniques are too limited, you can register the
|
||||
`TomcatEmbeddedServletContainerFactory` or `JettyEmbeddedServletContainerFactory` bean
|
||||
yourself.
|
||||
`TomcatEmbeddedServletContainerFactory`, `JettyEmbeddedServletContainerFactory` or
|
||||
`UndertowEmbeddedServletContainerFactory` bean yourself.
|
||||
|
||||
[source,java,indent=0]
|
||||
----
|
||||
@ -1208,6 +1209,8 @@ packaged as an executable archive), there are some limitations in the JSP suppor
|
||||
|
||||
* Jetty does not currently work as an embedded container with JSPs.
|
||||
|
||||
* Undertow does not support JSPs
|
||||
|
||||
There is a {github-code}/spring-boot-samples/spring-boot-sample-web-jsp[JSP sample] so
|
||||
you can see how to set things up.
|
||||
|
||||
|
@ -348,6 +348,9 @@ swap specific technical facets.
|
||||
|
||||
|`spring-boot-starter-tomcat`
|
||||
|Import Spring Boot's default HTTP engine (Tomcat).
|
||||
|
||||
|`spring-boot-starter-undertow`
|
||||
|Imports the Undertow HTTP engine (to be used as an alternative to Tomcat)
|
||||
|===
|
||||
|
||||
TIP: For a list of additional community contributed starter POMs, see the
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2013 the original author or authors.
|
||||
* Copyright 2012-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2013 the original author or authors.
|
||||
* Copyright 2012-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2013 the original author or authors.
|
||||
* Copyright 2012-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -39,7 +39,7 @@ import static org.junit.Assert.assertEquals;
|
||||
/**
|
||||
* Basic integration tests for demo application.
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @author Ivan Sopov
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@SpringApplicationConfiguration(classes = SampleUndertowSslApplication.class)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2013 the original author or authors.
|
||||
* Copyright 2012-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2013 the original author or authors.
|
||||
* Copyright 2012-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2013 the original author or authors.
|
||||
* Copyright 2012-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -19,9 +19,23 @@
|
||||
<main.basedir>${basedir}/../..</main.basedir>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>io.undertow</groupId>
|
||||
<artifactId>undertow-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.undertow</groupId>
|
||||
<artifactId>undertow-servlet</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.jboss.spec.javax.servlet</groupId>
|
||||
<artifactId>jboss-servlet-api_3.1_spec</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>javax.servlet-api</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 2012-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.context.embedded.undertow;
|
||||
|
||||
import io.undertow.Undertow.Builder;
|
||||
|
||||
/**
|
||||
* Callback interface that can be used to customize an Undertow {@link Builder}.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
* @since 1.2.0
|
||||
* @see UndertowEmbeddedServletContainerFactory
|
||||
*/
|
||||
public interface UndertowBuilderCustomizer {
|
||||
|
||||
/**
|
||||
* @param builder the {@code Builder} to customize
|
||||
*/
|
||||
void customize(Builder builder);
|
||||
|
||||
}
|
@ -1,3 +1,19 @@
|
||||
/*
|
||||
* Copyright 2012-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.context.embedded.undertow;
|
||||
|
||||
import io.undertow.Handlers;
|
||||
@ -14,16 +30,29 @@ import org.springframework.boot.context.embedded.EmbeddedServletContainerExcepti
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* {@link EmbeddedServletContainer} that can be used to control an embedded Undertow
|
||||
* server. Typically this class should be created using
|
||||
* {@link UndertowEmbeddedServletContainerFactory} and not directly.
|
||||
*
|
||||
* @author Ivan Sopov
|
||||
* @author Andy Wilkinson
|
||||
* @since 1.2.0
|
||||
* @see UndertowEmbeddedServletContainer
|
||||
*/
|
||||
public class UndertowEmbeddedServletContainer implements EmbeddedServletContainer {
|
||||
|
||||
private final DeploymentManager manager;
|
||||
|
||||
private final Builder builder;
|
||||
|
||||
private final String contextPath;
|
||||
|
||||
private final int port;
|
||||
|
||||
private final boolean autoStart;
|
||||
|
||||
private Undertow undertow;
|
||||
|
||||
private boolean started = false;
|
||||
|
||||
public UndertowEmbeddedServletContainer(Builder builder, DeploymentManager manager,
|
||||
@ -40,38 +69,39 @@ public class UndertowEmbeddedServletContainer implements EmbeddedServletContaine
|
||||
if (!this.autoStart) {
|
||||
return;
|
||||
}
|
||||
if (undertow == null) {
|
||||
if (this.undertow == null) {
|
||||
try {
|
||||
HttpHandler servletHandler = manager.start();
|
||||
if (StringUtils.isEmpty(contextPath)) {
|
||||
builder.setHandler(servletHandler);
|
||||
HttpHandler servletHandler = this.manager.start();
|
||||
if (StringUtils.isEmpty(this.contextPath)) {
|
||||
this.builder.setHandler(servletHandler);
|
||||
}
|
||||
else {
|
||||
PathHandler pathHandler = Handlers.path().addPrefixPath(contextPath,
|
||||
servletHandler);
|
||||
builder.setHandler(pathHandler);
|
||||
PathHandler pathHandler = Handlers.path().addPrefixPath(
|
||||
this.contextPath, servletHandler);
|
||||
this.builder.setHandler(pathHandler);
|
||||
}
|
||||
undertow = builder.build();
|
||||
this.undertow = this.builder.build();
|
||||
}
|
||||
catch (ServletException ex) {
|
||||
throw new EmbeddedServletContainerException(
|
||||
"Unable to start embdedded Undertow", ex);
|
||||
}
|
||||
}
|
||||
undertow.start();
|
||||
started = true;
|
||||
this.undertow.start();
|
||||
this.started = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void stop() throws EmbeddedServletContainerException {
|
||||
if (started) {
|
||||
started = false;
|
||||
undertow.stop();
|
||||
if (this.started) {
|
||||
this.started = false;
|
||||
this.undertow.stop();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPort() {
|
||||
return port;
|
||||
return this.port;
|
||||
}
|
||||
|
||||
}
|
@ -1,12 +1,21 @@
|
||||
/*
|
||||
* Copyright 2012-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.context.embedded.undertow;
|
||||
|
||||
import static io.undertow.servlet.Servlets.defaultContainer;
|
||||
import static io.undertow.servlet.Servlets.deployment;
|
||||
import static io.undertow.servlet.Servlets.servlet;
|
||||
import static org.xnio.Options.SSL_CLIENT_AUTH_MODE;
|
||||
import static org.xnio.SslClientAuthMode.NOT_REQUESTED;
|
||||
import static org.xnio.SslClientAuthMode.REQUESTED;
|
||||
import static org.xnio.SslClientAuthMode.REQUIRED;
|
||||
import io.undertow.Undertow;
|
||||
import io.undertow.Undertow.Builder;
|
||||
import io.undertow.UndertowMessages;
|
||||
@ -27,12 +36,15 @@ import io.undertow.servlet.handlers.DefaultServlet;
|
||||
import io.undertow.servlet.util.ImmediateInstanceHandle;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.security.KeyManagementException;
|
||||
import java.security.KeyStore;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import javax.net.ssl.KeyManager;
|
||||
import javax.net.ssl.KeyManagerFactory;
|
||||
@ -45,6 +57,7 @@ import javax.servlet.ServletException;
|
||||
|
||||
import org.springframework.boot.context.embedded.AbstractEmbeddedServletContainerFactory;
|
||||
import org.springframework.boot.context.embedded.EmbeddedServletContainer;
|
||||
import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory;
|
||||
import org.springframework.boot.context.embedded.ErrorPage;
|
||||
import org.springframework.boot.context.embedded.MimeMappings.Mapping;
|
||||
import org.springframework.boot.context.embedded.ServletContextInitializer;
|
||||
@ -52,176 +65,178 @@ import org.springframework.boot.context.embedded.Ssl;
|
||||
import org.springframework.boot.context.embedded.Ssl.ClientAuth;
|
||||
import org.springframework.context.ResourceLoaderAware;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ResourceUtils;
|
||||
import org.springframework.util.SocketUtils;
|
||||
|
||||
import static io.undertow.servlet.Servlets.defaultContainer;
|
||||
import static io.undertow.servlet.Servlets.deployment;
|
||||
import static io.undertow.servlet.Servlets.servlet;
|
||||
import static org.xnio.Options.SSL_CLIENT_AUTH_MODE;
|
||||
import static org.xnio.SslClientAuthMode.NOT_REQUESTED;
|
||||
import static org.xnio.SslClientAuthMode.REQUESTED;
|
||||
import static org.xnio.SslClientAuthMode.REQUIRED;
|
||||
|
||||
/**
|
||||
* {@link EmbeddedServletContainerFactory} that can be used to create
|
||||
* {@link UndertowEmbeddedServletContainer}s.
|
||||
* <p>
|
||||
* Unless explicitly configured otherwise, the factory will create containers that listen
|
||||
* for HTTP requests on port 8080.
|
||||
*
|
||||
* @author Ivan Sopov
|
||||
* @author Andy Wilkinson
|
||||
* @since 1.2.0
|
||||
* @see UndertowEmbeddedServletContainer
|
||||
*/
|
||||
public class UndertowEmbeddedServletContainerFactory extends
|
||||
AbstractEmbeddedServletContainerFactory implements ResourceLoaderAware {
|
||||
|
||||
private List<UndertowBuilderCustomizer> undertowBuilderCustomizers = new ArrayList<UndertowBuilderCustomizer>();
|
||||
|
||||
private ResourceLoader resourceLoader;
|
||||
|
||||
private Integer bufferSize;
|
||||
|
||||
private Integer buffersPerRegion;
|
||||
|
||||
private Integer ioThreads;
|
||||
|
||||
private Integer workerThreads;
|
||||
|
||||
private Boolean directBuffers;
|
||||
|
||||
/**
|
||||
* Create a new
|
||||
* {@link org.springframework.boot.context.embedded.undertow.UndertowEmbeddedServletContainerFactory}
|
||||
* instance.
|
||||
* Create a new {@link UndertowEmbeddedServletContainerFactory} instance.
|
||||
*/
|
||||
public UndertowEmbeddedServletContainerFactory() {
|
||||
super();
|
||||
setRegisterJspServlet(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new
|
||||
* {@link org.springframework.boot.context.embedded.undertow.UndertowEmbeddedServletContainerFactory}
|
||||
* that listens for requests using the specified port.
|
||||
*
|
||||
* Create a new {@link UndertowEmbeddedServletContainerFactory} that listens for
|
||||
* requests using the specified port.
|
||||
* @param port the port to listen on
|
||||
*/
|
||||
public UndertowEmbeddedServletContainerFactory(int port) {
|
||||
super(port);
|
||||
setRegisterJspServlet(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new
|
||||
* {@link org.springframework.boot.context.embedded.undertow.UndertowEmbeddedServletContainerFactory}
|
||||
* with the specified context path and port.
|
||||
*
|
||||
* Create a new {@link UndertowEmbeddedServletContainerFactory} with the specified
|
||||
* context path and port.
|
||||
* @param contextPath root the context path
|
||||
* @param port the port to listen on
|
||||
*/
|
||||
public UndertowEmbeddedServletContainerFactory(String contextPath, int port) {
|
||||
super(contextPath, port);
|
||||
setRegisterJspServlet(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set {@link UndertowBuilderCustomizer}s that should be applied to the Undertow
|
||||
* {@link Builder}. Calling this method will replace any existing customizers.
|
||||
* @param undertowBuilderCustomizers the customizers to set
|
||||
*/
|
||||
public void setUndertowBuilderCustomizers(
|
||||
Collection<? extends UndertowBuilderCustomizer> undertowBuilderCustomizers) {
|
||||
Assert.notNull(undertowBuilderCustomizers,
|
||||
"undertowBuilderCustomizers must not be null");
|
||||
this.undertowBuilderCustomizers = new ArrayList<UndertowBuilderCustomizer>(
|
||||
undertowBuilderCustomizers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a mutable collection of the {@link UndertowBuilderCustomizer}s that will be
|
||||
* applied to the Undertow {@link Builder} .
|
||||
* @return the customizers that will be applied
|
||||
*/
|
||||
public Collection<UndertowBuilderCustomizer> getUndertowBuilderCustomizers() {
|
||||
return this.undertowBuilderCustomizers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add {@link UndertowBuilderCustomizer}s that should be used to customize the
|
||||
* Undertow {@link Builder}.
|
||||
* @param undertowBuilderCustomizers the customizers to add
|
||||
*/
|
||||
public void addUndertowBuilderCustomizers(
|
||||
UndertowBuilderCustomizer... undertowBuilderCustomizers) {
|
||||
Assert.notNull(undertowBuilderCustomizers,
|
||||
"undertowBuilderCustomizers must not be null");
|
||||
this.undertowBuilderCustomizers.addAll(Arrays.asList(undertowBuilderCustomizers));
|
||||
}
|
||||
|
||||
@Override
|
||||
public EmbeddedServletContainer getEmbeddedServletContainer(
|
||||
ServletContextInitializer... initializers) {
|
||||
DeploymentInfo servletBuilder = deployment();
|
||||
DeploymentManager manager = createDeploymentManager(initializers);
|
||||
|
||||
servletBuilder.addListener(new ListenerInfo(
|
||||
UndertowSpringServletContextListener.class,
|
||||
new UndertowSpringServletContextListenerFactory(
|
||||
new UndertowSpringServletContextListener(
|
||||
mergeInitializers(initializers)))));
|
||||
int port = getPort();
|
||||
if (port == 0) {
|
||||
port = SocketUtils.findAvailableTcpPort(40000);
|
||||
}
|
||||
|
||||
if (resourceLoader != null) {
|
||||
servletBuilder.setClassLoader(resourceLoader.getClassLoader());
|
||||
Builder builder = createBuilder(port);
|
||||
|
||||
return new UndertowEmbeddedServletContainer(builder, manager, getContextPath(),
|
||||
port, port >= 0);
|
||||
}
|
||||
|
||||
private Builder createBuilder(int port) {
|
||||
Builder builder = Undertow.builder();
|
||||
if (this.bufferSize != null) {
|
||||
builder.setBufferSize(this.bufferSize);
|
||||
}
|
||||
if (this.buffersPerRegion != null) {
|
||||
builder.setBuffersPerRegion(this.buffersPerRegion);
|
||||
}
|
||||
if (this.ioThreads != null) {
|
||||
builder.setIoThreads(this.ioThreads);
|
||||
}
|
||||
if (this.workerThreads != null) {
|
||||
builder.setWorkerThreads(this.workerThreads);
|
||||
}
|
||||
if (this.directBuffers != null) {
|
||||
builder.setDirectBuffers(this.directBuffers);
|
||||
}
|
||||
|
||||
if (getSsl() == null) {
|
||||
builder.addHttpListener(port, "0.0.0.0");
|
||||
}
|
||||
else {
|
||||
servletBuilder.setClassLoader(getClass().getClassLoader());
|
||||
configureSsl(port, builder);
|
||||
}
|
||||
servletBuilder.setContextPath(getContextPath());
|
||||
servletBuilder.setDeploymentName("spring-boot");
|
||||
if (isRegisterDefaultServlet()) {
|
||||
servletBuilder.addServlet(servlet("default", DefaultServlet.class));
|
||||
for (UndertowBuilderCustomizer customizer : this.undertowBuilderCustomizers) {
|
||||
customizer.customize(builder);
|
||||
}
|
||||
if (isRegisterJspServlet()) {
|
||||
logger.error("JSPs are not supported with Undertow");
|
||||
}
|
||||
for (ErrorPage springErrorPage : getErrorPages()) {
|
||||
if (springErrorPage.getStatus() != null) {
|
||||
io.undertow.servlet.api.ErrorPage undertowErrorpage = new io.undertow.servlet.api.ErrorPage(
|
||||
springErrorPage.getPath(), springErrorPage.getStatusCode());
|
||||
servletBuilder.addErrorPage(undertowErrorpage);
|
||||
return builder;
|
||||
}
|
||||
|
||||
private void configureSsl(int port, Builder builder) {
|
||||
try {
|
||||
Ssl ssl = getSsl();
|
||||
SSLContext sslContext = SSLContext.getInstance(ssl.getProtocol());
|
||||
sslContext.init(getKeyManagers(), getTrustManagers(), null);
|
||||
builder.addHttpsListener(port, "0.0.0.0", sslContext);
|
||||
if (ssl.getClientAuth() == ClientAuth.NEED) {
|
||||
builder.setSocketOption(SSL_CLIENT_AUTH_MODE, REQUIRED);
|
||||
}
|
||||
else if (springErrorPage.getException() != null) {
|
||||
io.undertow.servlet.api.ErrorPage undertowErrorpage = new io.undertow.servlet.api.ErrorPage(
|
||||
springErrorPage.getPath(), springErrorPage.getException());
|
||||
servletBuilder.addErrorPage(undertowErrorpage);
|
||||
else if (ssl.getClientAuth() == ClientAuth.WANT) {
|
||||
builder.setSocketOption(SSL_CLIENT_AUTH_MODE, REQUESTED);
|
||||
}
|
||||
else {
|
||||
io.undertow.servlet.api.ErrorPage undertowErrorpage = new io.undertow.servlet.api.ErrorPage(
|
||||
springErrorPage.getPath());
|
||||
servletBuilder.addErrorPage(undertowErrorpage);
|
||||
builder.setSocketOption(SSL_CLIENT_AUTH_MODE, NOT_REQUESTED);
|
||||
}
|
||||
}
|
||||
servletBuilder.setServletStackTraces(ServletStackTraces.NONE);
|
||||
|
||||
File root = getValidDocumentRoot();
|
||||
if (root != null && root.isDirectory()) {
|
||||
servletBuilder.setResourceManager(new FileResourceManager(root, 0));
|
||||
catch (NoSuchAlgorithmException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
else if (root != null && root.isFile()) {
|
||||
servletBuilder.setResourceManager(new JarResourcemanager(root));
|
||||
catch (KeyManagementException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
else if (resourceLoader != null) {
|
||||
servletBuilder.setResourceManager(new ClassPathResourceManager(resourceLoader
|
||||
.getClassLoader(), ""));
|
||||
}
|
||||
else {
|
||||
servletBuilder.setResourceManager(new ClassPathResourceManager(getClass()
|
||||
.getClassLoader(), ""));
|
||||
}
|
||||
for (Mapping mimeMapping : getMimeMappings()) {
|
||||
servletBuilder.addMimeMapping(new MimeMapping(mimeMapping.getExtension(),
|
||||
mimeMapping.getMimeType()));
|
||||
}
|
||||
|
||||
DeploymentManager manager = defaultContainer().addDeployment(servletBuilder);
|
||||
|
||||
manager.deploy();
|
||||
|
||||
manager.getDeployment().getSessionManager()
|
||||
.setDefaultSessionTimeout(getSessionTimeout());
|
||||
|
||||
Builder builder = Undertow.builder();
|
||||
if (bufferSize != null) {
|
||||
builder.setBufferSize(bufferSize);
|
||||
}
|
||||
if (buffersPerRegion != null) {
|
||||
builder.setBuffersPerRegion(buffersPerRegion);
|
||||
}
|
||||
if (ioThreads != null) {
|
||||
builder.setIoThreads(ioThreads);
|
||||
}
|
||||
if (workerThreads != null) {
|
||||
builder.setWorkerThreads(workerThreads);
|
||||
}
|
||||
if (directBuffers != null) {
|
||||
builder.setDirectBuffers(directBuffers);
|
||||
}
|
||||
|
||||
int realPort = getPort();
|
||||
if (realPort == 0) {
|
||||
realPort = SocketUtils.findAvailableTcpPort(40000);
|
||||
}
|
||||
if (getSsl() == null) {
|
||||
builder.addHttpListener(realPort, "0.0.0.0");
|
||||
}
|
||||
else {
|
||||
try {
|
||||
Ssl ssl = getSsl();
|
||||
SSLContext sslContext = SSLContext.getInstance(ssl.getProtocol());
|
||||
sslContext.init(getKeyManagers(), getTrustManagers(), null);
|
||||
builder.addHttpsListener(realPort, "0.0.0.0", sslContext);
|
||||
if (ssl.getClientAuth() == ClientAuth.NEED) {
|
||||
builder.setSocketOption(SSL_CLIENT_AUTH_MODE, REQUIRED);
|
||||
}
|
||||
else if (ssl.getClientAuth() == ClientAuth.WANT) {
|
||||
builder.setSocketOption(SSL_CLIENT_AUTH_MODE, REQUESTED);
|
||||
}
|
||||
else {
|
||||
builder.setSocketOption(SSL_CLIENT_AUTH_MODE, NOT_REQUESTED);
|
||||
}
|
||||
}
|
||||
catch (NoSuchAlgorithmException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
catch (KeyManagementException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
return new UndertowEmbeddedServletContainer(builder, manager, getContextPath(),
|
||||
realPort, realPort > 0);
|
||||
|
||||
}
|
||||
|
||||
private KeyManager[] getKeyManagers() {
|
||||
@ -244,8 +259,8 @@ public class UndertowEmbeddedServletContainerFactory extends
|
||||
keyManagerFactory.init(keyStore, keyPassword);
|
||||
return keyManagerFactory.getKeyManagers();
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
catch (Exception ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@ -271,10 +286,100 @@ public class UndertowEmbeddedServletContainerFactory extends
|
||||
trustManagerFactory.init(trustedKeyStore);
|
||||
return trustManagerFactory.getTrustManagers();
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
catch (Exception ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private DeploymentManager createDeploymentManager(
|
||||
ServletContextInitializer... initializers) {
|
||||
DeploymentInfo servletBuilder = deployment();
|
||||
|
||||
servletBuilder.addListener(new ListenerInfo(
|
||||
UndertowSpringServletContextListener.class,
|
||||
new UndertowSpringServletContextListenerFactory(
|
||||
new UndertowSpringServletContextListener(
|
||||
mergeInitializers(initializers)))));
|
||||
|
||||
if (this.resourceLoader != null) {
|
||||
servletBuilder.setClassLoader(this.resourceLoader.getClassLoader());
|
||||
}
|
||||
else {
|
||||
servletBuilder.setClassLoader(getClass().getClassLoader());
|
||||
}
|
||||
servletBuilder.setContextPath(getContextPath());
|
||||
servletBuilder.setDeploymentName("spring-boot");
|
||||
if (isRegisterDefaultServlet()) {
|
||||
servletBuilder.addServlet(servlet("default", DefaultServlet.class));
|
||||
}
|
||||
|
||||
configureErrorPages(servletBuilder);
|
||||
servletBuilder.setServletStackTraces(ServletStackTraces.NONE);
|
||||
|
||||
File root = getValidDocumentRoot();
|
||||
if (root != null && root.isDirectory()) {
|
||||
servletBuilder.setResourceManager(new FileResourceManager(root, 0));
|
||||
}
|
||||
else if (root != null && root.isFile()) {
|
||||
servletBuilder.setResourceManager(new JarResourcemanager(root));
|
||||
}
|
||||
else if (this.resourceLoader != null) {
|
||||
servletBuilder.setResourceManager(new ClassPathResourceManager(
|
||||
this.resourceLoader.getClassLoader(), ""));
|
||||
}
|
||||
else {
|
||||
servletBuilder.setResourceManager(new ClassPathResourceManager(getClass()
|
||||
.getClassLoader(), ""));
|
||||
}
|
||||
for (Mapping mimeMapping : getMimeMappings()) {
|
||||
servletBuilder.addMimeMapping(new MimeMapping(mimeMapping.getExtension(),
|
||||
mimeMapping.getMimeType()));
|
||||
}
|
||||
|
||||
DeploymentManager manager = defaultContainer().addDeployment(servletBuilder);
|
||||
|
||||
manager.deploy();
|
||||
|
||||
manager.getDeployment().getSessionManager()
|
||||
.setDefaultSessionTimeout(getSessionTimeout());
|
||||
return manager;
|
||||
}
|
||||
|
||||
private void configureErrorPages(DeploymentInfo servletBuilder) {
|
||||
for (ErrorPage errorPage : getErrorPages()) {
|
||||
if (errorPage.getStatus() != null) {
|
||||
io.undertow.servlet.api.ErrorPage undertowErrorpage = new io.undertow.servlet.api.ErrorPage(
|
||||
errorPage.getPath(), errorPage.getStatusCode());
|
||||
servletBuilder.addErrorPage(undertowErrorpage);
|
||||
}
|
||||
else if (errorPage.getException() != null) {
|
||||
io.undertow.servlet.api.ErrorPage undertowErrorpage = new io.undertow.servlet.api.ErrorPage(
|
||||
errorPage.getPath(), errorPage.getException());
|
||||
servletBuilder.addErrorPage(undertowErrorpage);
|
||||
}
|
||||
else {
|
||||
io.undertow.servlet.api.ErrorPage undertowErrorpage = new io.undertow.servlet.api.ErrorPage(
|
||||
errorPage.getPath());
|
||||
servletBuilder.addErrorPage(undertowErrorpage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory method called to create the {@link UndertowEmbeddedServletContainer}.
|
||||
* Subclasses can override this method to return a different
|
||||
* {@link UndertowEmbeddedServletContainer} or apply additional processing to the
|
||||
* {@link Builder} and {@link DeploymentManager} used to bootstrap Undertow
|
||||
*
|
||||
* @param builder the builder
|
||||
* @param manager the deployment manager
|
||||
* @param port the port that Undertow should listen on
|
||||
* @return a new {@link UndertowEmbeddedServletContainer} instance
|
||||
*/
|
||||
protected UndertowEmbeddedServletContainer getUndertowEmbeddedServletContainer(
|
||||
Builder builder, DeploymentManager manager, int port) {
|
||||
return new UndertowEmbeddedServletContainer(builder, manager, getContextPath(),
|
||||
port, port >= 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -302,6 +407,12 @@ public class UndertowEmbeddedServletContainerFactory extends
|
||||
this.directBuffers = directBuffers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setRegisterJspServlet(boolean registerJspServlet) {
|
||||
Assert.isTrue(!registerJspServlet, "Undertow does not support JSPs");
|
||||
super.setRegisterJspServlet(registerJspServlet);
|
||||
}
|
||||
|
||||
private static class JarResourcemanager implements ResourceManager {
|
||||
private final String jarPath;
|
||||
|
||||
@ -320,7 +431,7 @@ public class UndertowEmbeddedServletContainerFactory extends
|
||||
|
||||
@Override
|
||||
public Resource getResource(String path) throws IOException {
|
||||
URL url = new URL("jar:file:" + jarPath + "!" + path);
|
||||
URL url = new URL("jar:file:" + this.jarPath + "!" + path);
|
||||
URLResource resource = new URLResource(url, url.openConnection(), path);
|
||||
if (resource.getContentLength() < 0) {
|
||||
return null;
|
||||
@ -361,7 +472,7 @@ public class UndertowEmbeddedServletContainerFactory extends
|
||||
public InstanceHandle<UndertowSpringServletContextListener> createInstance()
|
||||
throws InstantiationException {
|
||||
return new ImmediateInstanceHandle<UndertowSpringServletContextListener>(
|
||||
listener);
|
||||
this.listener);
|
||||
}
|
||||
|
||||
}
|
||||
@ -376,14 +487,14 @@ public class UndertowEmbeddedServletContainerFactory extends
|
||||
}
|
||||
|
||||
@Override
|
||||
public void contextInitialized(ServletContextEvent sce) {
|
||||
public void contextInitialized(ServletContextEvent event) {
|
||||
try {
|
||||
for (ServletContextInitializer initializer : initializers) {
|
||||
initializer.onStartup(sce.getServletContext());
|
||||
for (ServletContextInitializer initializer : this.initializers) {
|
||||
initializer.onStartup(event.getServletContext());
|
||||
}
|
||||
}
|
||||
catch (ServletException e) {
|
||||
throw new RuntimeException(e);
|
||||
catch (ServletException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright 2012-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Support for Undertow {@link org.springframework.boot.context.embedded.EmbeddedServletContainer EmbeddedServletContainers}.
|
||||
*
|
||||
* @see org.springframework.boot.context.embedded.undertow.UndertowEmbeddedServletContainerFactory
|
||||
*/
|
||||
package org.springframework.boot.context.embedded.undertow;
|
||||
|
@ -49,6 +49,7 @@ import static org.junit.Assert.assertThat;
|
||||
* {@link EmbeddedServletContainer}s running Spring MVC.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @author Ivan Sopov
|
||||
*/
|
||||
public class EmbeddedServletContainerMvcIntegrationTests {
|
||||
|
||||
@ -69,7 +70,7 @@ public class EmbeddedServletContainerMvcIntegrationTests {
|
||||
TomcatConfig.class);
|
||||
doTest(this.context, "/hello");
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void jetty() throws Exception {
|
||||
this.context = new AnnotationConfigEmbeddedWebApplicationContext(
|
||||
@ -83,9 +84,6 @@ public class EmbeddedServletContainerMvcIntegrationTests {
|
||||
UndertowConfig.class);
|
||||
doTest(this.context, "/hello");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void advancedConfig() throws Exception {
|
||||
@ -128,7 +126,7 @@ public class EmbeddedServletContainerMvcIntegrationTests {
|
||||
return new JettyEmbeddedServletContainerFactory(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Configuration
|
||||
@Import(Config.class)
|
||||
public static class UndertowConfig {
|
||||
|
@ -1,34 +1,96 @@
|
||||
/*
|
||||
* Copyright 2012-2014 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.context.embedded.undertow;
|
||||
|
||||
import io.undertow.Undertow.Builder;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.boot.context.embedded.*;
|
||||
import org.mockito.InOrder;
|
||||
import org.springframework.boot.context.embedded.AbstractEmbeddedServletContainerFactory;
|
||||
import org.springframework.boot.context.embedded.AbstractEmbeddedServletContainerFactoryTests;
|
||||
import org.springframework.boot.context.embedded.ErrorPage;
|
||||
import org.springframework.boot.context.embedded.ExampleServlet;
|
||||
import org.springframework.boot.context.embedded.ServletRegistrationBean;
|
||||
import org.springframework.http.HttpStatus;
|
||||
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import static org.mockito.Matchers.anyObject;
|
||||
import static org.mockito.Mockito.inOrder;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Tests for {@link org.springframework.boot.context.embedded.undertow.UndertowEmbeddedServletContainerFactory} and
|
||||
* {@link org.springframework.boot.context.embedded.undertow.UndertowEmbeddedServletContainer}.
|
||||
* Tests for {@link UndertowEmbeddedServletContainerFactory} and
|
||||
* {@link UndertowEmbeddedServletContainer} .
|
||||
*
|
||||
* @author Ivan Sopov
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
public class UndertowEmbeddedServletContainerFactoryTests extends AbstractEmbeddedServletContainerFactoryTests
|
||||
{
|
||||
public class UndertowEmbeddedServletContainerFactoryTests extends
|
||||
AbstractEmbeddedServletContainerFactoryTests {
|
||||
|
||||
@Override
|
||||
protected UndertowEmbeddedServletContainerFactory getFactory()
|
||||
{
|
||||
return new UndertowEmbeddedServletContainerFactory();
|
||||
}
|
||||
@Override
|
||||
protected UndertowEmbeddedServletContainerFactory getFactory() {
|
||||
return new UndertowEmbeddedServletContainerFactory(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void errorPage404() throws Exception {
|
||||
AbstractEmbeddedServletContainerFactory factory = getFactory();
|
||||
factory.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND, "/hello"));
|
||||
this.container = factory.getEmbeddedServletContainer(new ServletRegistrationBean(new ExampleServlet(), "/hello"));
|
||||
this.container.start();
|
||||
assertThat(getResponse("http://localhost:8080/hello"), equalTo("Hello World"));
|
||||
assertThat(getResponse("http://localhost:8080/not-found"), equalTo("Hello World"));
|
||||
}
|
||||
@Test
|
||||
public void errorPage404() throws Exception {
|
||||
AbstractEmbeddedServletContainerFactory factory = getFactory();
|
||||
factory.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND, "/hello"));
|
||||
this.container = factory.getEmbeddedServletContainer(new ServletRegistrationBean(
|
||||
new ExampleServlet(), "/hello"));
|
||||
this.container.start();
|
||||
assertThat(getResponse(getLocalUrl("/hello")), equalTo("Hello World"));
|
||||
assertThat(getResponse(getLocalUrl("/not-found")), equalTo("Hello World"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setNullUndertowBuilderCustomizersThrows() {
|
||||
UndertowEmbeddedServletContainerFactory factory = getFactory();
|
||||
this.thrown.expect(IllegalArgumentException.class);
|
||||
this.thrown.expectMessage("undertowBuilderCustomizers must not be null");
|
||||
factory.setUndertowBuilderCustomizers(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void addNullContextCustomizersThrows() {
|
||||
UndertowEmbeddedServletContainerFactory factory = getFactory();
|
||||
this.thrown.expect(IllegalArgumentException.class);
|
||||
this.thrown.expectMessage("undertowBuilderCustomizers must not be null");
|
||||
factory.addUndertowBuilderCustomizers((UndertowBuilderCustomizer[]) null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void builderCustomizers() throws Exception {
|
||||
UndertowEmbeddedServletContainerFactory factory = getFactory();
|
||||
UndertowBuilderCustomizer[] customizers = new UndertowBuilderCustomizer[4];
|
||||
for (int i = 0; i < customizers.length; i++) {
|
||||
customizers[i] = mock(UndertowBuilderCustomizer.class);
|
||||
}
|
||||
factory.setUndertowBuilderCustomizers(Arrays.asList(customizers[0],
|
||||
customizers[1]));
|
||||
factory.addUndertowBuilderCustomizers(customizers[2], customizers[3]);
|
||||
this.container = factory.getEmbeddedServletContainer();
|
||||
InOrder ordered = inOrder((Object[]) customizers);
|
||||
for (UndertowBuilderCustomizer customizer : customizers) {
|
||||
ordered.verify(customizer).customize((Builder) anyObject());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user