Introduce "server.servlet" configuration prefix

This commit refactors the `ServerProperties` property keys and
introduces a separate "server.servlet" namespace to isolate
servlet-specific properties from the rest.

Closes gh-8066
This commit is contained in:
Brian Clozel 2017-01-26 21:43:04 +01:00
parent a31a792192
commit 12d883f6b9
37 changed files with 239 additions and 195 deletions

View File

@ -337,7 +337,7 @@ public class ManagementWebSecurityAutoConfiguration {
String path = management.getContextPath();
if (StringUtils.hasText(path)) {
AntPathRequestMatcher matcher = new AntPathRequestMatcher(
server.getPath(path) + "/**");
server.getServlet().getPath(path) + "/**");
return matcher;
}
// Match everything, including the sensitive and non-sensitive paths
@ -364,7 +364,7 @@ public class ManagementWebSecurityAutoConfiguration {
List<RequestMatcher> matchers = new ArrayList<RequestMatcher>();
EndpointHandlerMapping endpointHandlerMapping = getRequiredEndpointHandlerMapping();
for (String path : this.endpointPaths.getPaths(endpointHandlerMapping)) {
matchers.add(new AntPathRequestMatcher(server.getPath(path)));
matchers.add(new AntPathRequestMatcher(server.getServlet().getPath(path)));
}
return (matchers.isEmpty() ? MATCH_NONE : new OrRequestMatcher(matchers));
}

View File

@ -56,7 +56,7 @@ public class BootCuriesHrefIntegrationTests {
@Test
public void curiesHrefWithCustomContextPath() {
int port = load("endpoints.docs.curies.enabled:true", "server.port:0",
"server.context-path:/context");
"server.servlet.context-path:/context");
assertThat(getCurieHref("http://localhost:" + port + "/context/actuator"))
.isEqualTo("http://localhost:" + port
+ "/context/docs/#spring_boot_actuator__{rel}");
@ -65,7 +65,7 @@ public class BootCuriesHrefIntegrationTests {
@Test
public void curiesHrefWithCustomServletPath() {
int port = load("endpoints.docs.curies.enabled:true", "server.port:0",
"server.servlet-path:/servlet");
"server.servlet.path:/servlet");
assertThat(getCurieHref("http://localhost:" + port + "/servlet/actuator"))
.isEqualTo("http://localhost:" + port
+ "/servlet/docs/#spring_boot_actuator__{rel}");
@ -74,7 +74,7 @@ public class BootCuriesHrefIntegrationTests {
@Test
public void curiesHrefWithCustomServletAndContextPaths() {
int port = load("endpoints.docs.curies.enabled:true", "server.port:0",
"server.context-path:/context", "server.servlet-path:/servlet");
"server.servlet.context-path:/context", "server.servlet.path:/servlet");
assertThat(getCurieHref("http://localhost:" + port + "/context/servlet/actuator"))
.isEqualTo("http://localhost:" + port
+ "/context/servlet/docs/#spring_boot_actuator__{rel}");
@ -83,7 +83,7 @@ public class BootCuriesHrefIntegrationTests {
@Test
public void curiesHrefWithCustomServletContextAndManagementContextPaths() {
int port = load("endpoints.docs.curies.enabled:true", "server.port:0",
"server.context-path:/context", "server.servlet-path:/servlet",
"server.servlet.context-path:/context", "server.servlet.path:/servlet",
"management.context-path:/management");
assertThat(getCurieHref("http://localhost:" + port
+ "/context/servlet/management/")).isEqualTo("http://localhost:" + port
@ -93,7 +93,7 @@ public class BootCuriesHrefIntegrationTests {
@Test
public void serverPathsAreIgnoredWithSeparateManagementPort() {
int port = load("endpoints.docs.curies.enabled:true", "server.port:0",
"server.context-path:/context", "server.servlet-path:/servlet",
"server.servlet.context-path:/context", "server.servlet.path:/servlet",
"management.port:0");
assertThat(getCurieHref("http://localhost:" + port + "/actuator/")).isEqualTo(
"http://localhost:" + port + "/docs/#spring_boot_actuator__{rel}");

View File

@ -127,7 +127,7 @@ public class EndpointWebMvcAutoConfigurationTests {
EnvironmentTestUtils.addEnvironment(this.applicationContext,
"management.context-path=",
"management.security.enabled=false",
"server.context-path=",
"server.servlet.context-path=",
"server.port=" + ports.get().server);
}
@ -233,7 +233,7 @@ public class EndpointWebMvcAutoConfigurationTests {
@Test
public void onDifferentPortAndMainContext() throws Exception {
EnvironmentTestUtils.addEnvironment(this.applicationContext,
"server.context-path=/spring",
"server.servlet.context-path=/spring",
"management.port=" + ports.get().management,
"management.context-path=/admin");
this.applicationContext.register(RootConfig.class, EndpointConfig.class,

View File

@ -51,7 +51,7 @@ import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo;
*/
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, properties = {
"server.contextPath=/spring" })
"server.servlet.contextPath=/spring" })
@DirtiesContext
public class HalBrowserMvcEndpointServerContextPathIntegrationTests {

View File

@ -51,7 +51,7 @@ import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo;
*/
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, properties = {
"server.servlet-path=/spring" })
"server.servlet.path=/spring" })
@DirtiesContext
public class HalBrowserMvcEndpointServerServletPathIntegrationTests {

View File

@ -200,7 +200,7 @@ public class SpringBootWebSecurityConfiguration {
if (this.errorController != null) {
ignored.add(normalizePath(this.errorController.getErrorPath()));
}
String[] paths = this.server.getPathsArray(ignored);
String[] paths = this.server.getServlet().getPathsArray(ignored);
List<RequestMatcher> matchers = new ArrayList<RequestMatcher>();
if (!ObjectUtils.isEmpty(paths)) {
for (String pattern : paths) {

View File

@ -139,7 +139,7 @@ public class DispatcherServletAutoConfiguration {
public ServletRegistrationBean dispatcherServletRegistration(
DispatcherServlet dispatcherServlet) {
ServletRegistrationBean registration = new ServletRegistrationBean(
dispatcherServlet, this.serverProperties.getServletMapping());
dispatcherServlet, this.serverProperties.getServlet().getServletMapping());
registration.setName(DEFAULT_DISPATCHER_SERVLET_BEAN_NAME);
registration.setLoadOnStartup(
this.webMvcProperties.getServlet().getLoadOnStartup());

View File

@ -309,7 +309,7 @@ public class ErrorMvcAutoConfiguration {
@Override
public void registerErrorPages(ErrorPageRegistry errorPageRegistry) {
ErrorPage errorPage = new ErrorPage(this.properties.getServletPrefix()
ErrorPage errorPage = new ErrorPage(this.properties.getServlet().getServletPrefix()
+ this.properties.getError().getPath());
errorPageRegistry.addErrorPages(errorPage);
}

View File

@ -20,10 +20,7 @@ import java.io.File;
import java.net.InetAddress;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.servlet.ServletContext;
@ -57,7 +54,7 @@ import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomi
import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizerBeanPostProcessor;
import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory;
import org.springframework.boot.context.embedded.InitParameterConfiguringServletContextInitializer;
import org.springframework.boot.context.embedded.JspServlet;
import org.springframework.boot.context.embedded.Servlet;
import org.springframework.boot.context.embedded.Ssl;
import org.springframework.boot.context.embedded.jetty.JettyEmbeddedServletContainerFactory;
import org.springframework.boot.context.embedded.jetty.JettyServerCustomizer;
@ -73,7 +70,6 @@ import org.springframework.boot.web.servlet.ServletContextInitializer;
import org.springframework.context.EnvironmentAware;
import org.springframework.core.Ordered;
import org.springframework.core.env.Environment;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
@ -106,11 +102,6 @@ public class ServerProperties
*/
private InetAddress address;
/**
* Context path of the application.
*/
private String contextPath;
/**
* Display name of the application.
*/
@ -119,16 +110,6 @@ public class ServerProperties
@NestedConfigurationProperty
private ErrorProperties error = new ErrorProperties();
/**
* Path of the main dispatcher servlet.
*/
private String servletPath = "/";
/**
* ServletContext parameters.
*/
private final Map<String, String> contextParameters = new HashMap<String, String>();
/**
* If X-Forwarded-* headers should be applied to the HttpRequest.
*/
@ -160,7 +141,7 @@ public class ServerProperties
private Compression compression = new Compression();
@NestedConfigurationProperty
private JspServlet jspServlet;
private Servlet servlet = new Servlet();
private final Tomcat tomcat = new Tomcat();
@ -188,8 +169,8 @@ public class ServerProperties
if (getAddress() != null) {
container.setAddress(getAddress());
}
if (getContextPath() != null) {
container.setContextPath(getContextPath());
if (getServlet().getContextPath() != null) {
container.setContextPath(getServlet().getContextPath());
}
if (getDisplayName() != null) {
container.setDisplayName(getDisplayName());
@ -202,8 +183,8 @@ public class ServerProperties
if (getSsl() != null) {
container.setSsl(getSsl());
}
if (getJspServlet() != null) {
container.setJspServlet(getJspServlet());
if (getServlet().getJsp() != null) {
container.setJsp(getServlet().getJsp());
}
if (getCompression() != null) {
container.setCompression(getCompression());
@ -224,57 +205,7 @@ public class ServerProperties
}
container.addInitializers(new SessionConfiguringInitializer(this.session));
container.addInitializers(new InitParameterConfiguringServletContextInitializer(
getContextParameters()));
}
public String getServletMapping() {
if (this.servletPath.equals("") || this.servletPath.equals("/")) {
return "/";
}
if (this.servletPath.contains("*")) {
return this.servletPath;
}
if (this.servletPath.endsWith("/")) {
return this.servletPath + "*";
}
return this.servletPath + "/*";
}
public String getPath(String path) {
String prefix = getServletPrefix();
if (!path.startsWith("/")) {
path = "/" + path;
}
return prefix + path;
}
public String getServletPrefix() {
String result = this.servletPath;
if (result.contains("*")) {
result = result.substring(0, result.indexOf("*"));
}
if (result.endsWith("/")) {
result = result.substring(0, result.length() - 1);
}
return result;
}
public String[] getPathsArray(Collection<String> paths) {
String[] result = new String[paths.size()];
int i = 0;
for (String path : paths) {
result[i++] = getPath(path);
}
return result;
}
public String[] getPathsArray(String[] paths) {
String[] result = new String[paths.length];
int i = 0;
for (String path : paths) {
result[i++] = getPath(path);
}
return result;
getServlet().getContextParameters()));
}
public void setLoader(String value) {
@ -297,21 +228,6 @@ public class ServerProperties
this.address = address;
}
public String getContextPath() {
return this.contextPath;
}
public void setContextPath(String contextPath) {
this.contextPath = cleanContextPath(contextPath);
}
private String cleanContextPath(String contextPath) {
if (StringUtils.hasText(contextPath) && contextPath.endsWith("/")) {
return contextPath.substring(0, contextPath.length() - 1);
}
return contextPath;
}
public String getDisplayName() {
return this.displayName;
}
@ -320,19 +236,6 @@ public class ServerProperties
this.displayName = displayName;
}
public String getServletPath() {
return this.servletPath;
}
public void setServletPath(String servletPath) {
Assert.notNull(servletPath, "ServletPath must not be null");
this.servletPath = servletPath;
}
public Map<String, String> getContextParameters() {
return this.contextParameters;
}
public Boolean isUseForwardHeaders() {
return this.useForwardHeaders;
}
@ -397,12 +300,12 @@ public class ServerProperties
return this.compression;
}
public JspServlet getJspServlet() {
return this.jspServlet;
public Servlet getServlet() {
return this.servlet;
}
public void setJspServlet(JspServlet jspServlet) {
this.jspServlet = jspServlet;
public void setServlet(Servlet servlet) {
this.servlet = servlet;
}
public Tomcat getTomcat() {

View File

@ -372,7 +372,7 @@
]
},
{
"name": "server.jsp-servlet.class-name",
"name": "server.servlet.jsp.class-name",
"providers": [
{
"name": "class-reference",

View File

@ -54,7 +54,7 @@ import static org.assertj.core.api.Assertions.assertThat;
*/
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, properties = {
"spring.jersey.type=filter", "server.contextPath=/app" })
"spring.jersey.type=filter", "server.servlet.contextPath=/app" })
@DirtiesContext
public class JerseyAutoConfigurationCustomFilterContextPathTests {

View File

@ -54,7 +54,7 @@ import static org.assertj.core.api.Assertions.assertThat;
*/
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, properties = "server.contextPath=/app")
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, properties = "server.servlet.contextPath=/app")
@DirtiesContext
public class JerseyAutoConfigurationCustomServletContextPathTests {

View File

@ -122,7 +122,8 @@ public class EmbeddedServletContainerAutoConfigurationTests {
public void initParametersAreConfiguredOnTheServletContext() {
this.context = new AnnotationConfigEmbeddedWebApplicationContext();
EnvironmentTestUtils.addEnvironment(this.context,
"server.context_parameters.a:alpha", "server.context_parameters.b:bravo");
"server.servlet.context_parameters.a:alpha",
"server.servlet.context_parameters.b:bravo");
this.context.register(BaseConfiguration.class);
this.context.refresh();

View File

@ -43,7 +43,7 @@ import static org.assertj.core.api.Assertions.assertThat;
* @author Dave Syer
*/
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, properties = "server.servletPath:/spring/*")
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, properties = "server.servlet.path:/spring/*")
@DirtiesContext
public class RemappedErrorViewIntegrationTests {
@ -89,7 +89,7 @@ public class RemappedErrorViewIntegrationTests {
// For manual testing
public static void main(String[] args) {
new SpringApplicationBuilder(TestConfiguration.class)
.properties("server.servletPath:spring/*").run(args);
.properties("server.servlet.path:spring/*").run(args);
}
}

View File

@ -125,20 +125,20 @@ public class ServerPropertiesTests {
public void testServletPathAsMapping() throws Exception {
RelaxedDataBinder binder = new RelaxedDataBinder(this.properties, "server");
binder.bind(new MutablePropertyValues(
Collections.singletonMap("server.servletPath", "/foo/*")));
Collections.singletonMap("server.servlet.path", "/foo/*")));
assertThat(binder.getBindingResult().hasErrors()).isFalse();
assertThat(this.properties.getServletMapping()).isEqualTo("/foo/*");
assertThat(this.properties.getServletPrefix()).isEqualTo("/foo");
assertThat(this.properties.getServlet().getServletMapping()).isEqualTo("/foo/*");
assertThat(this.properties.getServlet().getServletPrefix()).isEqualTo("/foo");
}
@Test
public void testServletPathAsPrefix() throws Exception {
RelaxedDataBinder binder = new RelaxedDataBinder(this.properties, "server");
binder.bind(new MutablePropertyValues(
Collections.singletonMap("server.servletPath", "/foo")));
Collections.singletonMap("server.servlet.path", "/foo")));
assertThat(binder.getBindingResult().hasErrors()).isFalse();
assertThat(this.properties.getServletMapping()).isEqualTo("/foo/*");
assertThat(this.properties.getServletPrefix()).isEqualTo("/foo");
assertThat(this.properties.getServlet().getServletMapping()).isEqualTo("/foo/*");
assertThat(this.properties.getServlet().getServletPrefix()).isEqualTo("/foo");
}
@Test
@ -238,15 +238,15 @@ public class ServerPropertiesTests {
@Test
public void testTrailingSlashOfContextPathIsRemoved() {
new RelaxedDataBinder(this.properties, "server").bind(new MutablePropertyValues(
Collections.singletonMap("server.contextPath", "/foo/")));
assertThat(this.properties.getContextPath()).isEqualTo("/foo");
Collections.singletonMap("server.servlet.contextPath", "/foo/")));
assertThat(this.properties.getServlet().getContextPath()).isEqualTo("/foo");
}
@Test
public void testSlashOfContextPathIsDefaultValue() {
new RelaxedDataBinder(this.properties, "server").bind(new MutablePropertyValues(
Collections.singletonMap("server.contextPath", "/")));
assertThat(this.properties.getContextPath()).isEqualTo("");
Collections.singletonMap("server.servlet.contextPath", "/")));
assertThat(this.properties.getServlet().getContextPath()).isEqualTo("");
}
@Test

View File

@ -95,8 +95,8 @@ public class RemoteDevToolsAutoConfiguration {
@Bean
public HandlerMapper remoteDevToolsHealthCheckHandlerMapper() {
Handler handler = new HttpStatusHandler();
return new UrlHandlerMapper((this.serverProperties.getContextPath() == null ? ""
: this.serverProperties.getContextPath())
return new UrlHandlerMapper((this.serverProperties.getServlet().getContextPath() == null ? ""
: this.serverProperties.getServlet().getContextPath())
+ this.properties.getRemote().getContextPath(), handler);
}
@ -136,8 +136,8 @@ public class RemoteDevToolsAutoConfiguration {
@Bean
@ConditionalOnMissingBean(name = "remoteRestartHandlerMapper")
public UrlHandlerMapper remoteRestartHandlerMapper(HttpRestartServer server) {
String url = (this.serverProperties.getContextPath() == null ? ""
: this.serverProperties.getContextPath())
String url = (this.serverProperties.getServlet().getContextPath() == null ? ""
: this.serverProperties.getServlet().getContextPath())
+ this.properties.getRemote().getContextPath() + "/restart";
logger.warn("Listening for remote restart updates on " + url);
Handler handler = new HttpRestartServerHandler(server);
@ -162,8 +162,8 @@ public class RemoteDevToolsAutoConfiguration {
@ConditionalOnMissingBean(name = "remoteDebugHandlerMapper")
public UrlHandlerMapper remoteDebugHandlerMapper(
@Qualifier("remoteDebugHttpTunnelServer") HttpTunnelServer server) {
String url = (this.serverProperties.getContextPath() == null ? ""
: this.serverProperties.getContextPath())
String url = (this.serverProperties.getServlet().getContextPath() == null ? ""
: this.serverProperties.getServlet().getContextPath())
+ this.properties.getRemote().getContextPath() + "/debug";
logger.warn("Listening for remote debug traffic on " + url);
Handler handler = new HttpTunnelServerHandler(server);

View File

@ -56,7 +56,7 @@ public class DevToolsPropertyDefaultsPostProcessor implements EnvironmentPostPro
properties.put("spring.resources.chain.cache", "false");
properties.put("spring.template.provider.cache", "false");
properties.put("spring.mvc.log-resolved-exception", "true");
properties.put("server.jsp-servlet.init-parameters.development", "true");
properties.put("server.servlet.jsp.init-parameters.development", "true");
properties.put("spring.reactor.stacktrace-mode.enabled", "true");
PROPERTIES = Collections.unmodifiableMap(properties);
}

View File

@ -138,7 +138,7 @@ public class RemoteDevToolsAutoConfigurationTests {
@Test
public void invokeRestartWithCustomServerContextPath() throws Exception {
loadContext("spring.devtools.remote.secret:supersecret",
"server.context-path:/test");
"server.servlet.context-path:/test");
DispatcherFilter filter = this.context.getBean(DispatcherFilter.class);
this.request.setRequestURI("/test" + DEFAULT_CONTEXT_PATH + "/restart");
this.request.addHeader(DEFAULT_SECRET_HEADER_NAME, "supersecret");
@ -167,7 +167,7 @@ public class RemoteDevToolsAutoConfigurationTests {
@Test
public void invokeTunnelWithCustomServerContextPath() throws Exception {
loadContext("spring.devtools.remote.secret:supersecret",
"server.context-path:/test");
"server.servlet.context-path:/test");
DispatcherFilter filter = this.context.getBean(DispatcherFilter.class);
this.request.setRequestURI("/test" + DEFAULT_CONTEXT_PATH + "/debug");
this.request.addHeader(DEFAULT_SECRET_HEADER_NAME, "supersecret");
@ -208,7 +208,7 @@ public class RemoteDevToolsAutoConfigurationTests {
@Test
public void devToolsHealthWithCustomServerContextPathReturns200() throws Exception {
loadContext("spring.devtools.remote.secret:supersecret",
"server.context-path:/test");
"server.servlet.context-path:/test");
DispatcherFilter filter = this.context.getBean(DispatcherFilter.class);
this.request.setRequestURI("/test" + DEFAULT_CONTEXT_PATH);
this.request.addHeader(DEFAULT_SECRET_HEADER_NAME, "supersecret");

View File

@ -152,8 +152,6 @@ content into your application; rather pick only the properties that you need.
server.compression.mime-types= # Comma-separated list of MIME types that should be compressed. For instance `text/html,text/css,application/json`
server.compression.min-response-size= # Minimum response size that is required for compression to be performed. For instance 2048
server.connection-timeout= # Time in milliseconds that connectors will wait for another HTTP request before closing the connection. When not set, the connector's container-specific default will be used. Use a value of -1 to indicate no (i.e. infinite) timeout.
server.context-parameters.*= # Servlet context init parameters. For instance `server.context-parameters.a=alpha`
server.context-path= # Context path of the application.
server.display-name=application # Display name of the application.
server.max-http-header-size=0 # Maximum size in bytes of the HTTP message header.
server.error.include-stacktrace=never # When to include a "stacktrace" attribute.
@ -162,12 +160,14 @@ content into your application; rather pick only the properties that you need.
server.jetty.acceptors= # Number of acceptor threads to use.
server.jetty.max-http-post-size=0 # Maximum size in bytes of the HTTP post or put content.
server.jetty.selectors= # Number of selector threads to use.
server.jsp-servlet.class-name=org.apache.jasper.servlet.JspServlet # The class name of the JSP servlet.
server.jsp-servlet.init-parameters.*= # Init parameters used to configure the JSP servlet
server.jsp-servlet.registered=true # Whether or not the JSP servlet is registered
server.port=8080 # Server HTTP port.
server.server-header= # Value to use for the Server response header (no header is sent if empty)
server.servlet-path=/ # Path of the main dispatcher servlet.
server.servlet.context-parameters.*= # Servlet context init parameters. For instance `server.servlet.context-parameters.a=alpha`
server.servlet.context-path= # Context path of the application.
server.servlet.jsp.class-name=org.apache.jasper.servlet.JspServlet # The class name of the JSP servlet.
server.servlet.jsp.init-parameters.*= # Init parameters used to configure the JSP servlet
server.servlet.jsp.registered=true # Whether or not the JSP servlet is registered
server.servlet.path=/ # Path of the main dispatcher servlet.
server.use-forward-headers= # If X-Forwarded-* headers should be applied to the HttpRequest.
server.session.cookie.comment= # Comment for the session cookie.
server.session.cookie.domain= # Domain for the session cookie.

View File

@ -42,7 +42,7 @@ categorized under "hints":
"sourceType": "org.springframework.boot.autoconfigure.web.ServerProperties"
},
{
"name": "server.servlet-path",
"name": "server.servlet.path",
"type": "java.lang.String",
"sourceType": "org.springframework.boot.autoconfigure.web.ServerProperties",
"defaultValue": "/"
@ -84,18 +84,18 @@ categorized under "hints":
----
Each "`property`" is a configuration item that the user specifies with a given value.
For example `server.port` and `server.servlet-path` might be specified in
For example `server.port` and `server.servlet.path` might be specified in
`application.properties` as follows:
[source,properties,indent=0]
----
server.port=9090
server.servlet-path=/home
server.servlet.path=/home
----
The "`groups`" are higher level items that don't themselves specify a value, but instead
provide a contextual grouping for properties. For example the `server.port` and
`server.servlet-path` properties are part of the `server` group.
`server.servlet.path` properties are part of the `server` group.
NOTE: It is not required that every "`property`" has a "`group`", some properties might
just exist in their own right.
@ -160,7 +160,7 @@ The JSON object contained in the `properties` array can contain the following at
|`name`
| String
| The full name of the property. Names are in lowercase dashed form (e.g.
`server.servlet-path`). This attribute is mandatory.
`server.servlet.path`). This attribute is mandatory.
|`type`
| String
@ -270,7 +270,7 @@ The JSON object contained in the `hints` array can contain the following attribu
|`name`
| String
| The full name of the property that this hint refers to. Names are in lowercase dashed
form (e.g. `server.servlet-path`). If the property refers to a map (e.g.
form (e.g. `server.servlet.path`). If the property refers to a map (e.g.
`system.contexts`) the hint either applies to the _keys_ of the map (`system.context.keys`)
or the values (`system.context.values`). This attribute is mandatory.
@ -495,14 +495,14 @@ provider supports these parameters:
|===
The meta-data snippet below corresponds to the standard `server.jsp-servlet.class-name`
The meta-data snippet below corresponds to the standard `server.servlet.jsp.class-name`
property that defines the `JspServlet` class name to use:
[source,json,indent=0]
----
{"hints": [
{
"name": "server.jsp-servlet.class-name",
"name": "server.servlet.jsp.class-name",
"providers": [
{
"name": "class-reference",

View File

@ -2117,9 +2117,9 @@ Actuator HTTP endpoints are only available for Spring MVC-based applications. If
to use Jersey and still use the actuator you will need to enable Spring MVC (by depending
on `spring-boot-starter-web`, for example). By default, both Jersey and the Spring MVC
dispatcher servlet are mapped to the same path (`/`). You will need to change the path for
one of them (by configuring `server.servlet-path` for Spring MVC or
one of them (by configuring `server.servlet.path` for Spring MVC or
`spring.jersey.application-path` for Jersey). For example, if you add
`server.servlet-path=/system` into `application.properties`, the actuator HTTP endpoints
`server.servlet.path=/system` into `application.properties`, the actuator HTTP endpoints
will be available under `/system`.

View File

@ -1,5 +1,5 @@
source ./test-functions.sh
install_service
start_service --server.port=8081 --server.context-path=/test
start_service --server.port=8081 --server.servlet.context-path=/test
await_app http://127.0.0.1:8081/test/
curl -s http://127.0.0.1:8081/test/

View File

@ -1,6 +1,6 @@
source ./test-functions.sh
install_service
echo 'JAVA_OPTS="-Dserver.port=8081 -Dserver.context-path=/test"' > /test-service/spring-boot-app.conf
echo 'JAVA_OPTS="-Dserver.port=8081 -Dserver.servlet.context-path=/test"' > /test-service/spring-boot-app.conf
start_service
await_app http://127.0.0.1:8081/test/
curl -s http://127.0.0.1:8081/test/

View File

@ -1,6 +1,6 @@
source ./test-functions.sh
install_service
echo 'RUN_ARGS="--server.port=8081 --server.context-path=/test"' > /test-service/spring-boot-app.conf
echo 'RUN_ARGS="--server.port=8081 --server.servlet.context-path=/test"' > /test-service/spring-boot-app.conf
start_service
await_app http://127.0.0.1:8081/test/
curl -s http://127.0.0.1:8081/test/

View File

@ -40,7 +40,7 @@ import static org.assertj.core.api.Assertions.assertThat;
*/
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, properties = {
"security.basic.enabled:false", "server.servletPath:/spring" })
"security.basic.enabled:false", "server.servlet.path:/spring" })
@DirtiesContext
public class ServletPathInsecureSampleActuatorApplicationTests {

View File

@ -39,7 +39,7 @@ import static org.assertj.core.api.Assertions.assertThat;
*/
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT, properties = {
"server.servletPath=/spring" })
"server.servlet.path=/spring" })
@DirtiesContext
public class ServletPathSampleActuatorApplicationTests {

View File

@ -1 +1 @@
server.servlet-path=/home/*
server.servlet.path=/home/*

View File

@ -38,7 +38,7 @@ public class LocalHostUriTemplateHandler extends RootUriTemplateHandler {
private final String scheme;
private RelaxedPropertyResolver serverPropertyResolver;
private RelaxedPropertyResolver servletPropertyResolver;
/**
* Create a new {@code LocalHostUriTemplateHandler} that will generate {@code http}
@ -63,13 +63,13 @@ public class LocalHostUriTemplateHandler extends RootUriTemplateHandler {
Assert.notNull(scheme, "Scheme must not be null");
this.environment = environment;
this.scheme = scheme;
this.serverPropertyResolver = new RelaxedPropertyResolver(environment, "server.");
this.servletPropertyResolver = new RelaxedPropertyResolver(environment, "server.servlet.");
}
@Override
public String getRootUri() {
String port = this.environment.getProperty("local.server.port", "8080");
String contextPath = this.serverPropertyResolver.getProperty("context-path", "");
String contextPath = this.servletPropertyResolver.getProperty("context-path", "");
return this.scheme + "://localhost:" + port + contextPath;
}

View File

@ -78,7 +78,7 @@ public class LocalHostUriTemplateHandlerTests {
@Test
public void getRootUriShouldUseContextPath() throws Exception {
MockEnvironment environment = new MockEnvironment();
environment.setProperty("server.contextPath", "/foo");
environment.setProperty("server.servlet.context-path", "/foo");
LocalHostUriTemplateHandler handler = new LocalHostUriTemplateHandler(
environment);
assertThat(handler.getRootUri()).isEqualTo("http://localhost:8080/foo");

View File

@ -80,7 +80,7 @@ public abstract class AbstractConfigurableEmbeddedServletContainer
private SslStoreProvider sslStoreProvider;
private JspServlet jspServlet = new JspServlet();
private Jsp jsp = new Jsp();
private Compression compression;
@ -308,12 +308,12 @@ public abstract class AbstractConfigurableEmbeddedServletContainer
}
@Override
public void setJspServlet(JspServlet jspServlet) {
this.jspServlet = jspServlet;
public void setJsp(Jsp jsp) {
this.jsp = jsp;
}
public JspServlet getJspServlet() {
return this.jspServlet;
public Jsp getJsp() {
return this.jsp;
}
public Compression getCompression() {
@ -370,8 +370,8 @@ public abstract class AbstractConfigurableEmbeddedServletContainer
* @return {@code true} if the container should be registered, otherwise {@code false}
*/
protected boolean shouldRegisterJspServlet() {
return this.jspServlet != null && this.jspServlet.getRegistered() && ClassUtils
.isPresent(this.jspServlet.getClassName(), getClass().getClassLoader());
return this.jsp != null && this.jsp.getRegistered() && ClassUtils
.isPresent(this.jsp.getClassName(), getClass().getClassLoader());
}
}

View File

@ -161,9 +161,9 @@ public interface ConfigurableEmbeddedServletContainer extends ErrorPageRegistry
/**
* Sets the configuration that will be applied to the container's JSP servlet.
* @param jspServlet the JSP servlet configuration
* @param jsp the JSP servlet configuration
*/
void setJspServlet(JspServlet jspServlet);
void setJsp(Jsp jsp);
/**
* Sets the compression configuration that will be applied to the container's default

View File

@ -23,9 +23,9 @@ import java.util.Map;
* Configuration for the container's JSP servlet.
*
* @author Andy Wilkinson
* @since 1.3.0
* @since 2.0.0
*/
public class JspServlet {
public class Jsp {
/**
* The class name of the servlet to use for JSPs. If registered is true and this class
@ -46,7 +46,7 @@ public class JspServlet {
*/
private boolean registered = true;
public JspServlet() {
public Jsp() {
this.initParameters.put("development", "false");
}

View File

@ -0,0 +1,140 @@
/*
* Copyright 2012-2017 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;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import org.springframework.boot.context.properties.NestedConfigurationProperty;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
* Configuration for Servlet containers.
*
* @author Brian Clozel
* @since 2.0.0
*/
public class Servlet {
/**
* ServletContext parameters.
*/
private final Map<String, String> contextParameters = new HashMap<String, String>();
/**
* Context path of the application.
*/
private String contextPath;
/**
* Path of the main dispatcher servlet.
*/
private String path = "/";
@NestedConfigurationProperty
private Jsp jsp = new Jsp();
public String getContextPath() {
return this.contextPath;
}
public void setContextPath(String contextPath) {
this.contextPath = cleanContextPath(contextPath);
}
private String cleanContextPath(String contextPath) {
if (StringUtils.hasText(contextPath) && contextPath.endsWith("/")) {
return contextPath.substring(0, contextPath.length() - 1);
}
return contextPath;
}
public String getPath() {
return this.path;
}
public void setPath(String path) {
Assert.notNull(path, "Path must not be null");
this.path = path;
}
public Map<String, String> getContextParameters() {
return this.contextParameters;
}
public Jsp getJsp() {
return this.jsp;
}
public void setJsp(Jsp jsp) {
this.jsp = jsp;
}
public String getServletMapping() {
if (this.path.equals("") || this.path.equals("/")) {
return "/";
}
if (this.path.contains("*")) {
return this.path;
}
if (this.path.endsWith("/")) {
return this.path + "*";
}
return this.path + "/*";
}
public String getPath(String path) {
String prefix = getServletPrefix();
if (!path.startsWith("/")) {
path = "/" + path;
}
return prefix + path;
}
public String getServletPrefix() {
String result = this.path;
if (result.contains("*")) {
result = result.substring(0, result.indexOf("*"));
}
if (result.endsWith("/")) {
result = result.substring(0, result.length() - 1);
}
return result;
}
public String[] getPathsArray(Collection<String> paths) {
String[] result = new String[paths.size()];
int i = 0;
for (String path : paths) {
result[i++] = getPath(path);
}
return result;
}
public String[] getPathsArray(String[] paths) {
String[] result = new String[paths.length];
int i = 0;
for (String path : paths) {
result[i++] = getPath(path);
}
return result;
}
}

View File

@ -423,9 +423,9 @@ public class JettyEmbeddedServletContainerFactory
Assert.notNull(context, "Context must not be null");
ServletHolder holder = new ServletHolder();
holder.setName("jsp");
holder.setClassName(getJspServlet().getClassName());
holder.setClassName(getJsp().getClassName());
holder.setInitParameter("fork", "false");
holder.setInitParameters(getJspServlet().getInitParameters());
holder.setInitParameters(getJsp().getInitParameters());
holder.setInitOrder(3);
context.getServletHandler().addServlet(holder);
ServletMapping mapping = new ServletMapping();

View File

@ -257,9 +257,9 @@ public class TomcatEmbeddedServletContainerFactory
private void addJspServlet(Context context) {
Wrapper jspServlet = context.createWrapper();
jspServlet.setName("jsp");
jspServlet.setServletClass(getJspServlet().getClassName());
jspServlet.setServletClass(getJsp().getClassName());
jspServlet.addInitParameter("fork", "false");
for (Entry<String, String> initParameter : getJspServlet().getInitParameters()
for (Entry<String, String> initParameter : getJsp().getInitParameters()
.entrySet()) {
jspServlet.addInitParameter(initParameter.getKey(), initParameter.getValue());
}

View File

@ -131,7 +131,7 @@ public class UndertowEmbeddedServletContainerFactory
*/
public UndertowEmbeddedServletContainerFactory() {
super();
getJspServlet().setRegistered(false);
getJsp().setRegistered(false);
}
/**
@ -141,7 +141,7 @@ public class UndertowEmbeddedServletContainerFactory
*/
public UndertowEmbeddedServletContainerFactory(int port) {
super(port);
getJspServlet().setRegistered(false);
getJsp().setRegistered(false);
}
/**
@ -152,7 +152,7 @@ public class UndertowEmbeddedServletContainerFactory
*/
public UndertowEmbeddedServletContainerFactory(String contextPath, int port) {
super(contextPath, port);
getJspServlet().setRegistered(false);
getJsp().setRegistered(false);
}
/**

View File

@ -634,7 +634,7 @@ public abstract class AbstractEmbeddedServletContainerFactoryTests {
@Test
public void disableJspServletRegistration() throws Exception {
AbstractEmbeddedServletContainerFactory factory = getFactory();
factory.getJspServlet().setRegistered(false);
factory.getJsp().setRegistered(false);
this.container = factory.getEmbeddedServletContainer();
assertThat(getJspServlet()).isNull();
}
@ -941,7 +941,7 @@ public abstract class AbstractEmbeddedServletContainerFactoryTests {
Map<String, String> initParameters = new HashMap<String, String>();
initParameters.put("a", "alpha");
AbstractEmbeddedServletContainerFactory factory = getFactory();
factory.getJspServlet().setInitParameters(initParameters);
factory.getJsp().setInitParameters(initParameters);
this.container = factory.getEmbeddedServletContainer();
Assume.assumeThat(getJspServlet(), notNullValue());
JspServlet jspServlet = getJspServlet();