diff --git a/spring-boot-autoconfigure/pom.xml b/spring-boot-autoconfigure/pom.xml index cb05053708..c9864fd57f 100755 --- a/spring-boot-autoconfigure/pom.xml +++ b/spring-boot-autoconfigure/pom.xml @@ -512,6 +512,11 @@ spring-social-linkedin true + + org.springframework.ws + spring-ws-core + true + org.thymeleaf thymeleaf diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ws/WsAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ws/WsAutoConfiguration.java new file mode 100644 index 0000000000..36c61b3677 --- /dev/null +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ws/WsAutoConfiguration.java @@ -0,0 +1,79 @@ +/* + * Copyright 2012-2016 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.autoconfigure.ws; + +import java.util.Map; + +import org.springframework.boot.autoconfigure.AutoConfigureAfter; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.boot.autoconfigure.web.EmbeddedServletContainerAutoConfiguration; +import org.springframework.boot.context.embedded.ServletRegistrationBean; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.ws.config.annotation.EnableWs; +import org.springframework.ws.config.annotation.WsConfigurationSupport; +import org.springframework.ws.transport.http.MessageDispatcherServlet; + +/** + * {@link EnableAutoConfiguration Auto-configuration} for Spring Web Services. + * + * @author Vedran Pavic + * @author Stephane Nicoll + * @since 1.4.0 + */ +@Configuration +@ConditionalOnWebApplication +@ConditionalOnClass(MessageDispatcherServlet.class) +@ConditionalOnMissingBean(WsConfigurationSupport.class) +@EnableConfigurationProperties(WsProperties.class) +@AutoConfigureAfter(EmbeddedServletContainerAutoConfiguration.class) +public class WsAutoConfiguration { + + private final WsProperties properties; + + public WsAutoConfiguration(WsProperties properties) { + this.properties = properties; + } + + @Bean + public ServletRegistrationBean messageDispatcherServlet( + ApplicationContext applicationContext) { + MessageDispatcherServlet servlet = new MessageDispatcherServlet(); + servlet.setApplicationContext(applicationContext); + String path = this.properties.getPath(); + String urlMapping = (path.endsWith("/") ? path + "*" : path + "/*"); + ServletRegistrationBean registration = new ServletRegistrationBean( + servlet, urlMapping); + WsProperties.Servlet servletProperties = this.properties.getServlet(); + registration.setLoadOnStartup(servletProperties.getLoadOnStartup()); + for (Map.Entry entry : servletProperties.getInit().entrySet()) { + registration.addInitParameter(entry.getKey(), entry.getValue()); + } + return registration; + } + + @Configuration + @EnableWs + protected static class WsConfiguration { + } + +} diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ws/WsProperties.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ws/WsProperties.java new file mode 100644 index 0000000000..b6dfea612f --- /dev/null +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ws/WsProperties.java @@ -0,0 +1,89 @@ +/* + * Copyright 2012-2016 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.autoconfigure.ws; + +import java.util.HashMap; +import java.util.Map; + +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Pattern; + +import org.springframework.boot.context.properties.ConfigurationProperties; + +/** + * {@link ConfigurationProperties} for Spring Web Services. + * + * @author Vedran Pavic + * @author Stephane Nicoll + * @since 1.4.0 + */ +@ConfigurationProperties("spring.ws") +public class WsProperties { + + /** + * Path that serves as the base URI for the services. + */ + @NotNull + @Pattern(regexp = "/[^?#]*", message = "Path must start with /") + private String path = "/services"; + + private final Servlet servlet = new Servlet(); + + public String getPath() { + return this.path; + } + + public void setPath(String path) { + this.path = path; + } + + public Servlet getServlet() { + return this.servlet; + } + + + public static class Servlet { + + /** + * Servlet init parameters to pass to Spring Web Services. + */ + private Map init = new HashMap(); + + /** + * Load on startup priority of the Spring Web Services servlet. + */ + private int loadOnStartup = -1; + + public Map getInit() { + return this.init; + } + + public void setInit(Map init) { + this.init = init; + } + + public int getLoadOnStartup() { + return this.loadOnStartup; + } + + public void setLoadOnStartup(int loadOnStartup) { + this.loadOnStartup = loadOnStartup; + } + + } + +} diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ws/package-info.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ws/package-info.java new file mode 100644 index 0000000000..c2b9505e88 --- /dev/null +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/ws/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-2016 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. + */ + +/** + * Auto-configuration for Spring Web Services. + */ +package org.springframework.boot.autoconfigure.ws; diff --git a/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories b/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories index 5afd06d3ff..6171b8ebac 100644 --- a/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories +++ b/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories @@ -96,7 +96,8 @@ org.springframework.boot.autoconfigure.web.MultipartAutoConfiguration,\ org.springframework.boot.autoconfigure.web.ServerPropertiesAutoConfiguration,\ org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration,\ org.springframework.boot.autoconfigure.websocket.WebSocketAutoConfiguration,\ -org.springframework.boot.autoconfigure.websocket.WebSocketMessagingAutoConfiguration +org.springframework.boot.autoconfigure.websocket.WebSocketMessagingAutoConfiguration,\ +org.springframework.boot.autoconfigure.ws.WsAutoConfiguration # Template availability providers org.springframework.boot.autoconfigure.template.TemplateAvailabilityProvider=\ diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/ws/WsAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/ws/WsAutoConfigurationTests.java new file mode 100644 index 0000000000..1541aa028d --- /dev/null +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/ws/WsAutoConfigurationTests.java @@ -0,0 +1,110 @@ +/* + * Copyright 2012-2016 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.autoconfigure.ws; + +import org.junit.After; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +import org.springframework.beans.factory.BeanCreationException; +import org.springframework.boot.context.embedded.ServletRegistrationBean; +import org.springframework.boot.test.util.EnvironmentTestUtils; +import org.springframework.mock.web.MockServletContext; +import org.springframework.test.util.ReflectionTestUtils; +import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link WsAutoConfiguration}. + * + * @author Vedran Pavic + * @author Stephane Nicoll + */ +public class WsAutoConfigurationTests { + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + private AnnotationConfigWebApplicationContext context; + + @After + public void close() { + if (this.context != null) { + this.context.close(); + } + } + + @Test + public void defaultConfiguration() { + load(WsAutoConfiguration.class); + + assertThat(this.context.getBeansOfType(ServletRegistrationBean.class)).hasSize(1); + } + + @Test + public void customPathMustBeginWithASlash() { + this.thrown.expect(BeanCreationException.class); + this.thrown.expectMessage("Path must start with /"); + load(WsAutoConfiguration.class, "spring.ws.path=invalid"); + } + + @Test + public void customPathWithTrailingSlash() { + load(WsAutoConfiguration.class, "spring.ws.path=/valid/"); + assertThat(this.context.getBean(ServletRegistrationBean.class).getUrlMappings()) + .contains("/valid/*"); + } + + @Test + public void customPath() { + load(WsAutoConfiguration.class, "spring.ws.path=/valid"); + assertThat(this.context.getBeansOfType(ServletRegistrationBean.class)).hasSize(1); + assertThat(this.context.getBean(ServletRegistrationBean.class).getUrlMappings()) + .contains("/valid/*"); + } + + @Test + public void customLoadOnStartup() { + load(WsAutoConfiguration.class, "spring.ws.servlet.load-on-startup=1"); + ServletRegistrationBean registrationBean = this.context + .getBean(ServletRegistrationBean.class); + assertThat(ReflectionTestUtils.getField(registrationBean, "loadOnStartup")) + .isEqualTo(1); + } + + @Test + public void customInitParameters() { + load(WsAutoConfiguration.class, "spring.ws.servlet.init.key1=value1", + "spring.ws.servlet.init.key2=value2"); + ServletRegistrationBean registrationBean = this.context + .getBean(ServletRegistrationBean.class); + assertThat(registrationBean.getInitParameters()).containsEntry("key1", "value1"); + assertThat(registrationBean.getInitParameters()).containsEntry("key2", "value2"); + } + + private void load(Class config, String... environment) { + AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext(); + ctx.setServletContext(new MockServletContext()); + EnvironmentTestUtils.addEnvironment(ctx, environment); + ctx.register(config); + ctx.refresh(); + this.context = ctx; + } + +} diff --git a/spring-boot-docs/pom.xml b/spring-boot-docs/pom.xml index 30a4b84036..99a5dba842 100644 --- a/spring-boot-docs/pom.xml +++ b/spring-boot-docs/pom.xml @@ -843,6 +843,7 @@ ${spring-boot-repo} ${spring.version} ${spring-security.version} + ${spring-ws.version} ${github-tag} diff --git a/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc b/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc index d54cce9ee3..50f5aaa543 100644 --- a/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc +++ b/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc @@ -406,6 +406,11 @@ content into your application; rather pick only the properties that you need. spring.velocity.toolbox-config-location= # Velocity Toolbox config location. For instance `/WEB-INF/toolbox.xml` spring.velocity.view-names= # White list of view names that can be resolved. + # WEB SERVICES ({sc-spring-boot-autoconfigure}/ws/WsProperties.{sc-ext}[WsProperties]) + spring.ws.path=/services # Path that serves as the base URI for the services. + spring.ws.servlet.init= # Servlet init parameters to pass to Spring Web Services. + spring.ws.servlet.load-on-startup=-1 # Load on startup priority of the Spring Web Services servlet. + [[common-application-properties-security]] # ---------------------------------------- diff --git a/spring-boot-docs/src/main/asciidoc/index.adoc b/spring-boot-docs/src/main/asciidoc/index.adoc index 99e0526a29..6a8b7c2047 100644 --- a/spring-boot-docs/src/main/asciidoc/index.adoc +++ b/spring-boot-docs/src/main/asciidoc/index.adoc @@ -37,6 +37,7 @@ Phillip Webb; Dave Syer; Josh Long; Stéphane Nicoll; Rob Winch; Andy Wilkinson; :spring-boot-maven-plugin-site: http://docs.spring.io/spring-boot/docs/{spring-boot-docs-version}/maven-plugin :spring-reference: http://docs.spring.io/spring/docs/{spring-docs-version}/spring-framework-reference/htmlsingle :spring-security-reference: http://docs.spring.io/spring-security/site/docs/{spring-security-docs-version}/reference/htmlsingle +:spring-ws-reference: http://docs.spring.io/spring-ws/docs/{spring-ws-docs-version}/reference/htmlsingle :spring-javadoc: http://docs.spring.io/spring/docs/{spring-docs-version}/javadoc-api/org/springframework :spring-amqp-javadoc: http://docs.spring.io/spring-amqp/docs/current/api/org/springframework/amqp :spring-data-javadoc: http://docs.spring.io/spring-data/jpa/docs/current/api/org/springframework/data/jpa diff --git a/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc b/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc index 72f7d00615..f92a98a4f6 100644 --- a/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc +++ b/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc @@ -4990,6 +4990,28 @@ public class MyTest { +[[boot-features-websockets]] +== WebSockets +Spring Boot provides WebSockets auto-configuration for embedded Tomcat (8 and 7), Jetty 9 +and Undertow. If you're deploying a war file to a standalone container, Spring Boot +assumes that the container will be responsible for the configuration of its WebSocket +support. + +Spring Framework provides {spring-reference}/#websocket[rich WebSocket support] that can +be easily accessed via the `spring-boot-starter-websocket` module. + + + +[[boot-features-ws]] +== Web Services +Spring Boot provides Web Services auto-configuration so that all is required is defining +your `Endpoints`. + +The {spring-ws-reference}[Spring Web Services features] can be easily accessed via the +`spring-boot-starter-ws` module. + + + [[boot-features-developing-auto-configuration]] == Creating your own auto-configuration If you work in a company that develops shared libraries, or if you work on an open-source @@ -5198,18 +5220,6 @@ library. -[[boot-features-websockets]] -== WebSockets -Spring Boot provides WebSockets auto-configuration for embedded Tomcat (8 and 7), Jetty 9 -and Undertow. If you're deploying a war file to a standalone container, Spring Boot -assumes that the container will be responsible for the configuration of its WebSocket -support. - -Spring Framework provides {spring-reference}/#websocket[rich WebSocket support] that can -be easily accessed via the `spring-boot-starter-websocket` module. - - - [[boot-features-whats-next]] == What to read next If you want to learn more about any of the classes discussed in this section you can diff --git a/spring-boot-samples/spring-boot-sample-ws/src/main/java/sample/ws/WebServiceConfig.java b/spring-boot-samples/spring-boot-sample-ws/src/main/java/sample/ws/WebServiceConfig.java index 3850c6efd2..4b8fa33b8e 100644 --- a/spring-boot-samples/spring-boot-sample-ws/src/main/java/sample/ws/WebServiceConfig.java +++ b/spring-boot-samples/spring-boot-sample-ws/src/main/java/sample/ws/WebServiceConfig.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2014 the original author or authors. + * Copyright 2012-2016 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. @@ -16,30 +16,17 @@ package sample.ws; -import org.springframework.boot.context.embedded.ServletRegistrationBean; -import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.ClassPathResource; -import org.springframework.ws.config.annotation.EnableWs; import org.springframework.ws.config.annotation.WsConfigurerAdapter; -import org.springframework.ws.transport.http.MessageDispatcherServlet; import org.springframework.ws.wsdl.wsdl11.DefaultWsdl11Definition; import org.springframework.xml.xsd.SimpleXsdSchema; import org.springframework.xml.xsd.XsdSchema; -@EnableWs @Configuration public class WebServiceConfig extends WsConfigurerAdapter { - @Bean - public ServletRegistrationBean dispatcherServlet( - ApplicationContext applicationContext) { - MessageDispatcherServlet servlet = new MessageDispatcherServlet(); - servlet.setApplicationContext(applicationContext); - return new ServletRegistrationBean(servlet, "/services/*"); - } - @Bean(name = "holiday") public DefaultWsdl11Definition defaultWsdl11Definition(XsdSchema countriesSchema) { DefaultWsdl11Definition wsdl11Definition = new DefaultWsdl11Definition();