Introduced @Configuration support for Spring-WS
Introduced support for Java @Configuration classes in the form of the @EnableWS annotation, WsConfigurationSupport and WsConfigurer. Overall solution is quite similar to Spring-MVC's @EnableMvc. Also added/uopdated reference documentation for the various @Configuration options. Issue: SWS-836
This commit is contained in:
@@ -15,6 +15,7 @@ configure(allprojects) {
|
||||
ext.axiomVersion = "1.2.14"
|
||||
|
||||
apply plugin: "java"
|
||||
apply plugin: "maven"
|
||||
apply plugin: "propdeps-idea"
|
||||
apply plugin: "propdeps"
|
||||
|
||||
@@ -55,7 +56,6 @@ configure(allprojects) {
|
||||
}
|
||||
|
||||
repositories {
|
||||
mavenLocal()
|
||||
maven { url 'http://repo.spring.io/libs-release' }
|
||||
}
|
||||
|
||||
@@ -176,7 +176,7 @@ project('spring-ws-core') {
|
||||
optional("wsdl4j:wsdl4j:1.6.1")
|
||||
|
||||
// Transport
|
||||
provided("javax.servlet:javax.servlet-api:3.1.0")
|
||||
provided("javax.servlet:javax.servlet-api:3.0.1")
|
||||
optional("org.apache.httpcomponents:httpclient:4.2.5")
|
||||
optional("commons-httpclient:commons-httpclient:3.1")
|
||||
testCompile("org.mortbay.jetty:jetty:6.1.26")
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
package org.springframework.ws.config.annotation;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.ws.server.EndpointInterceptor;
|
||||
import org.springframework.ws.server.endpoint.adapter.method.MethodArgumentResolver;
|
||||
import org.springframework.ws.server.endpoint.adapter.method.MethodReturnValueHandler;
|
||||
|
||||
/**
|
||||
* A sub-class of {@code WsConfigurationSupport} that detects and delegates
|
||||
* to all beans of type {@link WsConfigurer} allowing them to customize the
|
||||
* configuration provided by {@code WsConfigurationSupport}. This is the
|
||||
* class actually imported by {@link EnableWs @EnableWs}.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @since 2.2
|
||||
*/
|
||||
@Configuration
|
||||
public class DelegatingWsConfiguration extends WsConfigurationSupport {
|
||||
|
||||
private final WsConfigurerComposite configurers = new WsConfigurerComposite();
|
||||
|
||||
@Autowired(required = false)
|
||||
public void setConfigurers(List<WsConfigurer> configurers) {
|
||||
if (configurers != null && !configurers.isEmpty()) {
|
||||
this.configurers.addWsConfigurers(configurers);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addInterceptors(List<EndpointInterceptor> interceptors) {
|
||||
this.configurers.addInterceptors(interceptors);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addArgumentResolvers(List<MethodArgumentResolver> argumentResolvers) {
|
||||
this.configurers.addArgumentResolvers(argumentResolvers);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addReturnValueHandlers(
|
||||
List<MethodReturnValueHandler> returnValueHandlers) {
|
||||
this.configurers.addReturnValueHandlers(returnValueHandlers);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright 2005-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.ws.config.annotation;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
/**
|
||||
* Add this annotation to an {@link Configuration @Configuration} class to have the Spring
|
||||
* Web Services configuration defined in {@link WsConfigurationSupport} imported. For
|
||||
* instance:
|
||||
*
|
||||
* <pre class="code">
|
||||
* @Configuration
|
||||
* @EnableWs
|
||||
* @ComponentScan(basePackageClasses = { MyConfiguration.class })
|
||||
* public class MyWsConfiguration {
|
||||
*
|
||||
* }
|
||||
* </pre>
|
||||
* <p>Customize the imported configuration by implementing the
|
||||
* {@link WsConfigurer} interface or more likely by extending the
|
||||
* {@link WsConfigurerAdapter} base class and overriding individual methods:
|
||||
*
|
||||
* <pre class="code">
|
||||
* @Configuration
|
||||
* @EnableWs
|
||||
* @ComponentScan(basePackageClasses = { MyConfiguration.class })
|
||||
* public class MyConfiguration extends WsConfigurerAdapter {
|
||||
*
|
||||
* @Override
|
||||
* public void addInterceptors(List<EndpointInterceptor> interceptors) {
|
||||
* interceptors.add(new MyInterceptor());
|
||||
* }
|
||||
*
|
||||
* @Override
|
||||
* public void addArgumentResolvers(List<MethodArgumentResolver> argumentResolvers) {
|
||||
* argumentResolvers.add(new MyArgumentResolver());
|
||||
* }
|
||||
*
|
||||
* // More overridden methods ...
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* <p>If the customization options of {@link WsConfigurer} do not expose
|
||||
* something you need to configure, consider removing the {@code @EnableWs}
|
||||
* annotation and extending directly from {@link WsConfigurationSupport}
|
||||
* overriding selected {@code @Bean} methods:
|
||||
*
|
||||
* <pre class="code">
|
||||
* @Configuration
|
||||
* @ComponentScan(basePackageClasses = { MyConfiguration.class })
|
||||
* public class MyConfiguration extends WsConfigurationSupport {
|
||||
*
|
||||
* @Override
|
||||
* public void addInterceptors(List<EndpointInterceptor> interceptors) {
|
||||
* interceptors.add(new MyInterceptor());
|
||||
* }
|
||||
*
|
||||
* @Bean
|
||||
* @Override
|
||||
* public DefaultMethodEndpointAdapter defaultMethodEndpointAdapter() {
|
||||
* // Create or delegate to "super" to create and
|
||||
* // customize properties of DefaultMethodEndpointAdapter
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* @see WsConfigurer
|
||||
* @see WsConfigurerAdapter
|
||||
* @see WsConfigurationSupport
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @since 2.2
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.TYPE)
|
||||
@Documented
|
||||
@Import(DelegatingWsConfiguration.class)
|
||||
public @interface EnableWs {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,217 @@
|
||||
/*
|
||||
* Copyright 2005-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.ws.config.annotation;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.ws.server.EndpointAdapter;
|
||||
import org.springframework.ws.server.EndpointExceptionResolver;
|
||||
import org.springframework.ws.server.EndpointInterceptor;
|
||||
import org.springframework.ws.server.EndpointMapping;
|
||||
import org.springframework.ws.server.endpoint.adapter.DefaultMethodEndpointAdapter;
|
||||
import org.springframework.ws.server.endpoint.adapter.method.MethodArgumentResolver;
|
||||
import org.springframework.ws.server.endpoint.adapter.method.MethodReturnValueHandler;
|
||||
import org.springframework.ws.server.endpoint.annotation.PayloadRoot;
|
||||
import org.springframework.ws.server.endpoint.mapping.PayloadRootAnnotationMethodEndpointMapping;
|
||||
import org.springframework.ws.soap.addressing.server.AnnotationActionEndpointMapping;
|
||||
import org.springframework.ws.soap.addressing.server.annotation.Action;
|
||||
import org.springframework.ws.soap.server.endpoint.SimpleSoapExceptionResolver;
|
||||
import org.springframework.ws.soap.server.endpoint.SoapFaultAnnotationExceptionResolver;
|
||||
import org.springframework.ws.soap.server.endpoint.annotation.SoapAction;
|
||||
import org.springframework.ws.soap.server.endpoint.annotation.SoapFault;
|
||||
import org.springframework.ws.soap.server.endpoint.mapping.SoapActionAnnotationMethodEndpointMapping;
|
||||
|
||||
/**
|
||||
* This is the main class providing the configuration behind the Spring Web Services Java
|
||||
* config. It is typically imported by adding {@link EnableWs @EnableWs} to an
|
||||
* application {@link Configuration @Configuration} class. An alternative, more
|
||||
* advanced option is to extend directly from this class and override methods as
|
||||
* necessary remembering to add {@link Configuration @Configuration} to the
|
||||
* subclass and {@link Bean @Bean} to overridden {@link Bean @Bean} methods.
|
||||
* For more details see the Javadoc of {@link EnableWs @EnableWs}.
|
||||
*
|
||||
* <p>This class registers the following {@link EndpointMapping}s:
|
||||
* <ul>
|
||||
* <li>{@link PayloadRootAnnotationMethodEndpointMapping}
|
||||
* ordered at 0 for mapping requests to {@link PayloadRoot @PayloadRoot} annotated
|
||||
* controller methods.
|
||||
* <li>{@link SoapActionAnnotationMethodEndpointMapping}
|
||||
* ordered at 1 for mapping requests to {@link SoapAction @SoapAction} annotated
|
||||
* controller methods.
|
||||
* <li>{@link AnnotationActionEndpointMapping}
|
||||
* ordered at 2 for mapping requests to {@link Action @Action} annotated
|
||||
* controller methods.
|
||||
* </ul>
|
||||
*
|
||||
* <p>Registers one {@link EndpointAdapter}:
|
||||
* <ul>
|
||||
* <li>{@link DefaultMethodEndpointAdapter}
|
||||
* for processing requests with annotated endpoint methods.
|
||||
* </ul>
|
||||
*
|
||||
* <p>Registers the following {@link EndpointExceptionResolver}s:
|
||||
* <ul>
|
||||
* <li>{@link SoapFaultAnnotationExceptionResolver} for handling exceptions
|
||||
* annotated with {@link SoapFault @SoapFault}.
|
||||
* <li>{@link SimpleSoapExceptionResolver} for creating default exceptions.
|
||||
* </ul>
|
||||
*
|
||||
* @see EnableWs
|
||||
* @see WsConfigurer
|
||||
* @see WsConfigurerAdapter
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @since 2.2
|
||||
*/
|
||||
public class WsConfigurationSupport {
|
||||
|
||||
private List<EndpointInterceptor> interceptors;
|
||||
|
||||
/**
|
||||
* Returns a {@link PayloadRootAnnotationMethodEndpointMapping} ordered at 0 for
|
||||
* mapping requests to annotated endpoints.
|
||||
*/
|
||||
@Bean
|
||||
public PayloadRootAnnotationMethodEndpointMapping payloadRootAnnotationMethodEndpointMapping() {
|
||||
PayloadRootAnnotationMethodEndpointMapping endpointMapping =
|
||||
new PayloadRootAnnotationMethodEndpointMapping();
|
||||
endpointMapping.setOrder(0);
|
||||
endpointMapping.setInterceptors(getInterceptors());
|
||||
return endpointMapping;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link SoapActionAnnotationMethodEndpointMapping} ordered at 1 for
|
||||
* mapping requests to annotated endpoints.
|
||||
*/
|
||||
@Bean
|
||||
public SoapActionAnnotationMethodEndpointMapping soapActionAnnotationMethodEndpointMapping() {
|
||||
SoapActionAnnotationMethodEndpointMapping endpointMapping =
|
||||
new SoapActionAnnotationMethodEndpointMapping();
|
||||
endpointMapping.setOrder(1);
|
||||
endpointMapping.setInterceptors(getInterceptors());
|
||||
return endpointMapping;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link AnnotationActionEndpointMapping} ordered at 2 for
|
||||
* mapping requests to annotated endpoints.
|
||||
*/
|
||||
@Bean
|
||||
public AnnotationActionEndpointMapping annotationActionEndpointMapping() {
|
||||
AnnotationActionEndpointMapping endpointMapping =
|
||||
new AnnotationActionEndpointMapping();
|
||||
endpointMapping.setOrder(2);
|
||||
endpointMapping.setPostInterceptors(getInterceptors());
|
||||
return endpointMapping;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide access to the shared handler interceptors used to configure
|
||||
* {@link EndpointMapping} instances with. This method cannot be overridden,
|
||||
* use {@link #addInterceptors(List)} instead.
|
||||
*/
|
||||
protected final EndpointInterceptor[] getInterceptors() {
|
||||
if (interceptors == null) {
|
||||
interceptors = new ArrayList<EndpointInterceptor>();
|
||||
addInterceptors(interceptors);
|
||||
}
|
||||
return interceptors.toArray(new EndpointInterceptor[interceptors.size()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Template method to add endpoint interceptors. Override this method to add Spring-WS
|
||||
* interceptors for pre- and post-processing of endpoint invocation.
|
||||
*/
|
||||
protected void addInterceptors(List<EndpointInterceptor> interceptors) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link DefaultMethodEndpointAdapter} for processing requests
|
||||
* through annotated endpoint methods. Consider overriding one of these
|
||||
* other more fine-grained methods:
|
||||
* <ul>
|
||||
* <li>{@link #addArgumentResolvers(List)} for adding custom argument resolvers.
|
||||
* <li>{@link #addReturnValueHandlers(List)} for adding custom return value handlers.
|
||||
* </ul>
|
||||
*/
|
||||
@Bean
|
||||
public DefaultMethodEndpointAdapter defaultMethodEndpointAdapter() {
|
||||
List<MethodArgumentResolver> argumentResolvers =
|
||||
new ArrayList<MethodArgumentResolver>();
|
||||
addArgumentResolvers(argumentResolvers);
|
||||
|
||||
List<MethodReturnValueHandler> returnValueHandlers =
|
||||
new ArrayList<MethodReturnValueHandler>();
|
||||
addReturnValueHandlers(returnValueHandlers);
|
||||
|
||||
DefaultMethodEndpointAdapter adapter = new DefaultMethodEndpointAdapter();
|
||||
adapter.setCustomMethodArgumentResolvers(argumentResolvers);
|
||||
adapter.setCustomMethodReturnValueHandlers(returnValueHandlers);
|
||||
|
||||
return adapter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add custom {@link MethodArgumentResolver}s to use in addition to
|
||||
* the ones registered by default.
|
||||
* @param argumentResolvers the list of custom converters;
|
||||
* initially an empty list.
|
||||
*/
|
||||
protected void addArgumentResolvers(List<MethodArgumentResolver> argumentResolvers) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Add custom {@link MethodReturnValueHandler}s in addition to the
|
||||
* ones registered by default.
|
||||
* @param returnValueHandlers the list of custom handlers;
|
||||
* initially an empty list.
|
||||
*/
|
||||
protected void addReturnValueHandlers(
|
||||
List<MethodReturnValueHandler> returnValueHandlers) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link SoapFaultAnnotationExceptionResolver} ordered at 0 for handling
|
||||
* endpoint exceptions.
|
||||
*/
|
||||
@Bean
|
||||
public SoapFaultAnnotationExceptionResolver soapFaultAnnotationExceptionResolver() {
|
||||
SoapFaultAnnotationExceptionResolver exceptionResolver = new SoapFaultAnnotationExceptionResolver();
|
||||
exceptionResolver.setOrder(0);
|
||||
|
||||
return exceptionResolver;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link SimpleSoapExceptionResolver} ordered at
|
||||
* {@linkplain Ordered#LOWEST_PRECEDENCE lowest precedence} for handling endpoint
|
||||
* exceptions.
|
||||
*/
|
||||
@Bean
|
||||
public SimpleSoapExceptionResolver simpleSoapExceptionResolver() {
|
||||
SimpleSoapExceptionResolver exceptionResolver = new SimpleSoapExceptionResolver();
|
||||
exceptionResolver.setOrder(Ordered.LOWEST_PRECEDENCE);
|
||||
|
||||
return exceptionResolver;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package org.springframework.ws.config.annotation;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.ws.server.EndpointInterceptor;
|
||||
import org.springframework.ws.server.endpoint.adapter.method.MethodArgumentResolver;
|
||||
import org.springframework.ws.server.endpoint.adapter.method.MethodReturnValueHandler;
|
||||
|
||||
/**
|
||||
* Defines callback methods to customize the Java-based configuration for
|
||||
* Spring Web Services enabled via {@link EnableWs @EnableWs}.
|
||||
*
|
||||
* <p>{@code @EnableWs}-annotated configuration classes may implement
|
||||
* this interface to be called back and given a chance to customize the
|
||||
* default configuration. Consider extending {@link WsConfigurerAdapter},
|
||||
* which provides a stub implementation of all interface methods.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @since 2.2
|
||||
*/
|
||||
public interface WsConfigurer {
|
||||
|
||||
/**
|
||||
* Add {@link EndpointInterceptor}s for pre- and post-processing of
|
||||
* endpoint method invocations.
|
||||
*/
|
||||
void addInterceptors(List<EndpointInterceptor> interceptors);
|
||||
|
||||
/**
|
||||
* Add resolvers to support custom endpoint method argument types.
|
||||
* @param argumentResolvers initially an empty list
|
||||
*/
|
||||
void addArgumentResolvers(List<MethodArgumentResolver> argumentResolvers);
|
||||
|
||||
/**
|
||||
* Add handlers to support custom controller method return value types.
|
||||
* <p>Using this option does not override the built-in support for handling
|
||||
* return values. To customize the built-in support for handling return
|
||||
* values, configure RequestMappingHandlerAdapter directly.
|
||||
* @param returnValueHandlers initially an empty list
|
||||
*/
|
||||
void addReturnValueHandlers(List<MethodReturnValueHandler> returnValueHandlers);
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package org.springframework.ws.config.annotation;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.ws.server.EndpointInterceptor;
|
||||
import org.springframework.ws.server.endpoint.adapter.method.MethodArgumentResolver;
|
||||
import org.springframework.ws.server.endpoint.adapter.method.MethodReturnValueHandler;
|
||||
|
||||
/**
|
||||
* An default implementation of {@link WsConfigurer} with empty methods allowing
|
||||
* sub-classes to override only the methods they're interested in.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @since 2.2
|
||||
*/
|
||||
public class WsConfigurerAdapter implements WsConfigurer {
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* <p>This implementation is empty.
|
||||
*/
|
||||
@Override
|
||||
public void addInterceptors(List<EndpointInterceptor> interceptors) {
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* <p>This implementation is empty.
|
||||
*/
|
||||
@Override
|
||||
public void addArgumentResolvers(List<MethodArgumentResolver> argumentResolvers) {
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* <p>This implementation is empty.
|
||||
*/
|
||||
@Override
|
||||
public void addReturnValueHandlers(
|
||||
List<MethodReturnValueHandler> returnValueHandlers) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package org.springframework.ws.config.annotation;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.ws.server.EndpointInterceptor;
|
||||
import org.springframework.ws.server.endpoint.adapter.method.MethodArgumentResolver;
|
||||
import org.springframework.ws.server.endpoint.adapter.method.MethodReturnValueHandler;
|
||||
|
||||
/**
|
||||
* An {@link WsConfigurer} implementation that delegates to other {@link WsConfigurer} instances.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @since 2.2
|
||||
*/
|
||||
public class WsConfigurerComposite implements WsConfigurer {
|
||||
|
||||
private List<WsConfigurer> delegates = new ArrayList<WsConfigurer>();
|
||||
|
||||
public void addWsConfigurers(List<WsConfigurer> configurers) {
|
||||
if (configurers != null) {
|
||||
this.delegates.addAll(configurers);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addInterceptors(List<EndpointInterceptor> interceptors) {
|
||||
for (WsConfigurer delegate : delegates) {
|
||||
delegate.addInterceptors(interceptors);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addArgumentResolvers(List<MethodArgumentResolver> argumentResolvers) {
|
||||
for (WsConfigurer delegate : delegates) {
|
||||
delegate.addArgumentResolvers(argumentResolvers);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addReturnValueHandlers(
|
||||
List<MethodReturnValueHandler> returnValueHandlers) {
|
||||
for (WsConfigurer delegate : delegates) {
|
||||
delegate.addReturnValueHandlers(returnValueHandlers);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -69,31 +69,77 @@ public class DefaultMethodEndpointAdapter extends AbstractMethodEndpointAdapter
|
||||
|
||||
private List<MethodArgumentResolver> methodArgumentResolvers;
|
||||
|
||||
private List<MethodArgumentResolver> customMethodArgumentResolvers;
|
||||
|
||||
private List<MethodReturnValueHandler> methodReturnValueHandlers;
|
||||
|
||||
private List<MethodReturnValueHandler> customMethodReturnValueHandlers;
|
||||
|
||||
private ClassLoader classLoader;
|
||||
|
||||
/** Returns the list of {@code MethodArgumentResolver}s to use. */
|
||||
public List<MethodArgumentResolver> getMethodArgumentResolvers() {
|
||||
/**
|
||||
* Returns the list of {@code MethodArgumentResolver}s to use.
|
||||
*/
|
||||
public List<MethodArgumentResolver> getMethodArgumentResolvers() {
|
||||
return methodArgumentResolvers;
|
||||
}
|
||||
|
||||
/** Sets the list of {@code MethodArgumentResolver}s to use. */
|
||||
public void setMethodArgumentResolvers(List<MethodArgumentResolver> methodArgumentResolvers) {
|
||||
/**
|
||||
* Sets the list of {@code MethodArgumentResolver}s to use.
|
||||
*/
|
||||
public void setMethodArgumentResolvers(List<MethodArgumentResolver> methodArgumentResolvers) {
|
||||
this.methodArgumentResolvers = methodArgumentResolvers;
|
||||
}
|
||||
|
||||
/** Returns the list of {@code MethodReturnValueHandler}s to use. */
|
||||
public List<MethodReturnValueHandler> getMethodReturnValueHandlers() {
|
||||
/**
|
||||
* Returns the custom argument resolvers.
|
||||
*/
|
||||
public List<MethodArgumentResolver> getCustomMethodArgumentResolvers() {
|
||||
return customMethodArgumentResolvers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the custom handlers for method arguments. Custom handlers are
|
||||
* ordered after built-in ones. To override the built-in support for
|
||||
* return value handling use {@link #setMethodArgumentResolvers(List)}.
|
||||
*/
|
||||
public void setCustomMethodArgumentResolvers(
|
||||
List<MethodArgumentResolver> customMethodArgumentResolvers) {
|
||||
this.customMethodArgumentResolvers = customMethodArgumentResolvers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of {@code MethodReturnValueHandler}s to use.
|
||||
*/
|
||||
public List<MethodReturnValueHandler> getMethodReturnValueHandlers() {
|
||||
return methodReturnValueHandlers;
|
||||
}
|
||||
|
||||
/** Sets the list of {@code MethodReturnValueHandler}s to use. */
|
||||
public void setMethodReturnValueHandlers(List<MethodReturnValueHandler> methodReturnValueHandlers) {
|
||||
/**
|
||||
* Sets the list of {@code MethodReturnValueHandler}s to use.
|
||||
*/
|
||||
public void setMethodReturnValueHandlers(List<MethodReturnValueHandler> methodReturnValueHandlers) {
|
||||
this.methodReturnValueHandlers = methodReturnValueHandlers;
|
||||
}
|
||||
|
||||
private ClassLoader getClassLoader() {
|
||||
/**
|
||||
* Returns the custom return value handlers.
|
||||
*/
|
||||
public List<MethodReturnValueHandler> getCustomMethodReturnValueHandlers() {
|
||||
return customMethodReturnValueHandlers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the handlers for custom return value types. Custom handlers are
|
||||
* ordered after built-in ones. To override the built-in support for
|
||||
* return value handling use {@link #setMethodReturnValueHandlers(List)}.
|
||||
*/
|
||||
public void setCustomMethodReturnValueHandlers(
|
||||
List<MethodReturnValueHandler> customMethodReturnValueHandlers) {
|
||||
this.customMethodReturnValueHandlers = customMethodReturnValueHandlers;
|
||||
}
|
||||
|
||||
private ClassLoader getClassLoader() {
|
||||
return this.classLoader != null ? this.classLoader : DefaultMethodEndpointAdapter.class.getClassLoader();
|
||||
}
|
||||
|
||||
@@ -139,6 +185,9 @@ public class DefaultMethodEndpointAdapter extends AbstractMethodEndpointAdapter
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("No MethodArgumentResolvers set, using defaults: " + methodArgumentResolvers);
|
||||
}
|
||||
if (getCustomMethodArgumentResolvers() != null) {
|
||||
methodArgumentResolvers.addAll(getCustomMethodArgumentResolvers());
|
||||
}
|
||||
setMethodArgumentResolvers(methodArgumentResolvers);
|
||||
}
|
||||
}
|
||||
@@ -180,6 +229,9 @@ public class DefaultMethodEndpointAdapter extends AbstractMethodEndpointAdapter
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("No MethodReturnValueHandlers set, using defaults: " + methodReturnValueHandlers);
|
||||
}
|
||||
if (getCustomMethodReturnValueHandlers() != null) {
|
||||
methodReturnValueHandlers.addAll(getCustomMethodReturnValueHandlers());
|
||||
}
|
||||
setMethodReturnValueHandlers(methodReturnValueHandlers);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,9 @@ import java.io.IOException;
|
||||
import javax.xml.transform.Source;
|
||||
import javax.xml.transform.TransformerException;
|
||||
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.SAXParseException;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.util.Assert;
|
||||
@@ -37,9 +40,6 @@ import org.springframework.xml.validation.XmlValidatorFactory;
|
||||
import org.springframework.xml.xsd.XsdSchema;
|
||||
import org.springframework.xml.xsd.XsdSchemaCollection;
|
||||
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.SAXParseException;
|
||||
|
||||
/**
|
||||
* Abstract base class for <code>EndpointInterceptor</code> implementations that validate part of the message using a
|
||||
* schema. The exact message part is determined by the <code>getValidationRequestSource</code> and
|
||||
@@ -118,7 +118,7 @@ public abstract class AbstractValidatingInterceptor extends TransformerObjectSup
|
||||
* @param schema the xsd schema to use
|
||||
* @throws IOException in case of I/O errors
|
||||
*/
|
||||
public void setXsdSchema(XsdSchema schema) throws IOException {
|
||||
public void setXsdSchema(XsdSchema schema) {
|
||||
this.validator = schema.createValidator();
|
||||
}
|
||||
|
||||
@@ -130,7 +130,7 @@ public abstract class AbstractValidatingInterceptor extends TransformerObjectSup
|
||||
* @param schemaCollection the xsd schema collection to use
|
||||
* @throws IOException in case of I/O errors
|
||||
*/
|
||||
public void setXsdSchemaCollection(XsdSchemaCollection schemaCollection) throws IOException {
|
||||
public void setXsdSchemaCollection(XsdSchemaCollection schemaCollection) {
|
||||
this.validator = schemaCollection.createValidator();
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright 2002-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.ws.transport.http.support;
|
||||
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
|
||||
import org.springframework.web.servlet.support.AbstractDispatcherServletInitializer;
|
||||
import org.springframework.ws.transport.http.MessageDispatcherServlet;
|
||||
|
||||
/**
|
||||
* Base class for {@link WebApplicationInitializer} implementations that register a
|
||||
* {@link MessageDispatcherServlet} configured with annotated classes, e.g. Spring's
|
||||
* {@link Configuration @Configuration} classes.
|
||||
*
|
||||
* <p>Concrete implementations are required to implement {@link #getRootConfigClasses()}
|
||||
* and {@link #getServletConfigClasses()} as well as {@link #getServletMappings()}.
|
||||
* Further template and customization methods are provided by
|
||||
* {@link AbstractDispatcherServletInitializer}.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @since 2.2
|
||||
*/
|
||||
public abstract class AbstractAnnotationConfigMessageDispatcherServletInitializer
|
||||
extends AbstractMessageDispatcherServletInitializer {
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* <p>This implementation creates an {@link AnnotationConfigWebApplicationContext},
|
||||
* providing it the annotated classes returned by {@link #getRootConfigClasses()}.
|
||||
* Returns {@code null} if {@link #getRootConfigClasses()} returns {@code null}.
|
||||
*/
|
||||
@Override
|
||||
protected WebApplicationContext createRootApplicationContext() {
|
||||
Class<?>[] configClasses = getRootConfigClasses();
|
||||
if (!ObjectUtils.isEmpty(configClasses)) {
|
||||
AnnotationConfigWebApplicationContext rootAppContext = new AnnotationConfigWebApplicationContext();
|
||||
rootAppContext.register(configClasses);
|
||||
return rootAppContext;
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* <p>This implementation creates an {@link AnnotationConfigWebApplicationContext},
|
||||
* providing it the annotated classes returned by {@link #getServletConfigClasses()}.
|
||||
*/
|
||||
@Override
|
||||
protected WebApplicationContext createServletApplicationContext() {
|
||||
AnnotationConfigWebApplicationContext servletAppContext = new AnnotationConfigWebApplicationContext();
|
||||
Class<?>[] configClasses = getServletConfigClasses();
|
||||
if (!ObjectUtils.isEmpty(configClasses)) {
|
||||
servletAppContext.register(configClasses);
|
||||
}
|
||||
return servletAppContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify {@link org.springframework.context.annotation.Configuration @Configuration}
|
||||
* and/or {@link org.springframework.stereotype.Component @Component} classes to be
|
||||
* provided to the {@linkplain #createRootApplicationContext() root application context}.
|
||||
* @return the configuration classes for the root application context, or {@code null}
|
||||
* if creation and registration of a root context is not desired
|
||||
*/
|
||||
protected abstract Class<?>[] getRootConfigClasses();
|
||||
|
||||
/**
|
||||
* Specify {@link org.springframework.context.annotation.Configuration @Configuration}
|
||||
* and/or {@link org.springframework.stereotype.Component @Component} classes to be
|
||||
* provided to the {@linkplain #createServletApplicationContext() dispatcher servlet
|
||||
* application context}.
|
||||
* @return the configuration classes for the dispatcher servlet application context
|
||||
* (may not be empty or {@code null})
|
||||
*/
|
||||
protected abstract Class<?>[] getServletConfigClasses();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
/*
|
||||
* Copyright 2005-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.ws.transport.http.support;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletRegistration;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.context.AbstractContextLoaderInitializer;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
import org.springframework.ws.transport.http.MessageDispatcherServlet;
|
||||
|
||||
/**
|
||||
* Base class for {@link org.springframework.web.WebApplicationInitializer
|
||||
* WebApplicationInitializer} implementations that register a
|
||||
* {@link MessageDispatcherServlet} in the servlet context.
|
||||
*
|
||||
* <p>Concrete implementations are required to implement {@link
|
||||
* #createServletApplicationContext()}, which gets invoked from
|
||||
* {@link #registerMessageDispatcherServlet(ServletContext)}. Further customization can be
|
||||
* achieved by overriding {@link #customizeRegistration(ServletRegistration.Dynamic)}.
|
||||
*
|
||||
* <p>Because this class extends from {@link AbstractContextLoaderInitializer}, concrete
|
||||
* implementations are also required to implement {@link #createRootApplicationContext()}
|
||||
* to set up a parent "<strong>root</strong>" application context. If a root context is
|
||||
* not desired, implementations can simply return {@code null} in the
|
||||
* {@code createRootApplicationContext()} implementation.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @since 2.2
|
||||
*/
|
||||
public abstract class AbstractMessageDispatcherServletInitializer extends
|
||||
AbstractContextLoaderInitializer {
|
||||
|
||||
/**
|
||||
* The default servlet name. Can be customized by overriding {@link #getServletName}.
|
||||
*/
|
||||
public static final String DEFAULT_SERVLET_NAME = "messageDispatcher";
|
||||
|
||||
/**
|
||||
* The default servlet mappings. Can be customized by overriding {@link #getServletMappings()}.
|
||||
*/
|
||||
public static final String[] DEFAULT_SERVLET_MAPPINGS = new String[] { "/services", "*.wsdl"};
|
||||
|
||||
@Override
|
||||
public void onStartup(ServletContext servletContext) throws ServletException {
|
||||
super.onStartup(servletContext);
|
||||
|
||||
this.registerMessageDispatcherServlet(servletContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a {@link MessageDispatcherServlet} against the given servlet context.
|
||||
* <p>This method will create a {@code MessageDispatcherServlet} with the name
|
||||
* returned by {@link #getServletName()}, initializing it with the application context
|
||||
* returned from {@link #createServletApplicationContext()}, and mapping it to the
|
||||
* patterns returned from {@link #getServletMappings()}.
|
||||
* <p>Further customization can be achieved by overriding {@link
|
||||
* #customizeRegistration(ServletRegistration.Dynamic)}.
|
||||
* @param servletContext the context to register the servlet against
|
||||
*/
|
||||
protected void registerMessageDispatcherServlet(ServletContext servletContext) {
|
||||
String servletName = this.getServletName();
|
||||
Assert.hasLength(servletName, "getServletName() may not return empty or null");
|
||||
|
||||
WebApplicationContext servletAppContext = this.createServletApplicationContext();
|
||||
Assert.notNull(servletAppContext,
|
||||
"createServletApplicationContext() did not return an application " +
|
||||
"context for servlet [" + servletName + "]");
|
||||
|
||||
MessageDispatcherServlet dispatcherServlet =
|
||||
new MessageDispatcherServlet(servletAppContext);
|
||||
dispatcherServlet.setTransformWsdlLocations(isTransformWsdlLocations());
|
||||
dispatcherServlet.setTransformSchemaLocations(isTransformSchemaLocations());
|
||||
|
||||
ServletRegistration.Dynamic registration =
|
||||
servletContext.addServlet(servletName, dispatcherServlet);
|
||||
|
||||
Assert.notNull(registration,
|
||||
"Failed to register servlet with name '" + servletName + "'." +
|
||||
"Check if there is another servlet registered under the same name.");
|
||||
|
||||
registration.setLoadOnStartup(1);
|
||||
registration.addMapping(getServletMappings());
|
||||
|
||||
this.customizeRegistration(registration);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name under which the {@link MessageDispatcherServlet} will be registered.
|
||||
* Defaults to {@link #DEFAULT_SERVLET_NAME}.
|
||||
* @see #registerMessageDispatcherServlet(ServletContext)
|
||||
*/
|
||||
protected String getServletName() {
|
||||
return DEFAULT_SERVLET_NAME;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a servlet application context to be provided to the {@code MessageDispatcherServlet}.
|
||||
* <p>The returned context is delegated to Spring's
|
||||
* {@link MessageDispatcherServlet#MessageDispatcherServlet(WebApplicationContext)}.
|
||||
* As such, it typically contains endpoints, interceptors and other
|
||||
* web service-related beans.
|
||||
* @see #registerMessageDispatcherServlet(ServletContext)
|
||||
*/
|
||||
protected abstract WebApplicationContext createServletApplicationContext();
|
||||
|
||||
/**
|
||||
* Specify the servlet mapping(s) for the {@code MessageDispatcherServlet}.
|
||||
* Defaults to {@link #DEFAULT_SERVLET_MAPPING}.
|
||||
* @see #registerMessageDispatcherServlet(ServletContext)
|
||||
*/
|
||||
protected String[] getServletMappings() {
|
||||
return DEFAULT_SERVLET_MAPPINGS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether relative address locations in the WSDL are to be transformed
|
||||
* using the request URI of the incoming HTTP request. Defaults to {@code false}.
|
||||
*/
|
||||
public boolean isTransformWsdlLocations() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether relative address locations in the XSD are to be transformed using
|
||||
* the request URI of the incoming HTTP request. Defaults to {@code false}.
|
||||
*/
|
||||
protected boolean isTransformSchemaLocations() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Optionally perform further registration customization once
|
||||
* {@link #registerMessageDispatcherServlet(ServletContext)} has completed.
|
||||
* @param registration the {@code MessageDispatcherServlet} registration to be customized
|
||||
* @see #registerMessageDispatcherServlet(ServletContext)
|
||||
*/
|
||||
protected void customizeRegistration(ServletRegistration.Dynamic registration) {
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
package org.springframework.ws.wsdl.wsdl11.provider;
|
||||
|
||||
import java.io.IOException;
|
||||
import javax.wsdl.Definition;
|
||||
import javax.wsdl.Types;
|
||||
import javax.wsdl.WSDLException;
|
||||
@@ -64,7 +63,7 @@ public class InliningXsdSchemaTypesProvider extends TransformerObjectSupport imp
|
||||
return new XsdSchema[]{schema};
|
||||
}
|
||||
|
||||
public XmlValidator createValidator() throws IOException {
|
||||
public XmlValidator createValidator() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
package org.springframework.ws.config.annotation;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.ws.server.endpoint.adapter.DefaultMethodEndpointAdapter;
|
||||
import org.springframework.ws.server.endpoint.annotation.Endpoint;
|
||||
import org.springframework.ws.server.endpoint.mapping.PayloadRootAnnotationMethodEndpointMapping;
|
||||
import org.springframework.ws.soap.addressing.server.AnnotationActionEndpointMapping;
|
||||
import org.springframework.ws.soap.server.endpoint.annotation.SoapAction;
|
||||
import org.springframework.ws.soap.server.endpoint.mapping.SoapActionAnnotationMethodEndpointMapping;
|
||||
|
||||
/**
|
||||
* @author Arjen Poutsma
|
||||
*/
|
||||
public class DefaultWsConfigurationTest {
|
||||
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
|
||||
applicationContext.register(TestConfig.class);
|
||||
applicationContext.refresh();
|
||||
|
||||
this.applicationContext = applicationContext;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void payloadRootAnnotationMethodEndpointMapping() throws Exception {
|
||||
PayloadRootAnnotationMethodEndpointMapping endpointMapping = this.applicationContext.getBean(
|
||||
PayloadRootAnnotationMethodEndpointMapping.class);
|
||||
assertEquals(0, endpointMapping.getOrder());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void soapActionAnnotationMethodEndpointMapping() throws Exception {
|
||||
SoapActionAnnotationMethodEndpointMapping endpointMapping = this.applicationContext.getBean(
|
||||
SoapActionAnnotationMethodEndpointMapping.class);
|
||||
assertEquals(1, endpointMapping.getOrder());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void annotationActionEndpointMapping() throws Exception {
|
||||
AnnotationActionEndpointMapping endpointMapping = this.applicationContext.getBean(
|
||||
AnnotationActionEndpointMapping.class);
|
||||
assertEquals(2, endpointMapping.getOrder());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultMethodEndpointAdapter() throws Exception {
|
||||
|
||||
DefaultMethodEndpointAdapter adapter =
|
||||
this.applicationContext.getBean(DefaultMethodEndpointAdapter.class);
|
||||
|
||||
assertFalse(adapter.getMethodArgumentResolvers().isEmpty());
|
||||
assertFalse(adapter.getMethodReturnValueHandlers().isEmpty());
|
||||
}
|
||||
|
||||
|
||||
@EnableWs
|
||||
@Configuration
|
||||
public static class TestConfig {
|
||||
|
||||
@Bean(name="testEndpoint")
|
||||
public TestEndpoint testEndpoint() {
|
||||
return new TestEndpoint();
|
||||
}
|
||||
}
|
||||
|
||||
@Endpoint
|
||||
private static class TestEndpoint {
|
||||
|
||||
@SoapAction("handle")
|
||||
public void handle() {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
package org.springframework.ws.config.annotation;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.ws.server.EndpointInterceptor;
|
||||
import org.springframework.ws.server.endpoint.adapter.DefaultMethodEndpointAdapter;
|
||||
import org.springframework.ws.server.endpoint.interceptor.EndpointInterceptorAdapter;
|
||||
import org.springframework.ws.server.endpoint.mapping.PayloadRootAnnotationMethodEndpointMapping;
|
||||
|
||||
/**
|
||||
* @author Arjen Poutsma
|
||||
*/
|
||||
public class WsConfigurationSupportTest {
|
||||
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
AnnotationConfigApplicationContext applicationContext =
|
||||
new AnnotationConfigApplicationContext();
|
||||
applicationContext.register(TestConfig.class);
|
||||
applicationContext.refresh();
|
||||
|
||||
this.applicationContext = applicationContext;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void interceptors() {
|
||||
PayloadRootAnnotationMethodEndpointMapping endpointMapping = this.applicationContext.getBean(
|
||||
PayloadRootAnnotationMethodEndpointMapping.class);
|
||||
assertEquals(0, endpointMapping.getOrder());
|
||||
|
||||
EndpointInterceptor[] interceptors = endpointMapping.getInterceptors();
|
||||
assertEquals(1, interceptors.length);
|
||||
assertTrue(interceptors[0] instanceof MyInterceptor);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultMethodEndpointAdapter() {
|
||||
DefaultMethodEndpointAdapter endpointAdapter =
|
||||
this.applicationContext.getBean(DefaultMethodEndpointAdapter.class);
|
||||
assertNotNull(endpointAdapter);
|
||||
|
||||
assertTrue(endpointAdapter instanceof MyDefaultMethodEndpointAdapter);
|
||||
}
|
||||
|
||||
|
||||
@Configuration
|
||||
public static class TestConfig extends WsConfigurationSupport {
|
||||
|
||||
@Override
|
||||
protected void addInterceptors(List<EndpointInterceptor> interceptors) {
|
||||
interceptors.add(new MyInterceptor());
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Override
|
||||
public DefaultMethodEndpointAdapter defaultMethodEndpointAdapter() {
|
||||
return new MyDefaultMethodEndpointAdapter();
|
||||
}
|
||||
}
|
||||
|
||||
public static class MyInterceptor extends EndpointInterceptorAdapter {
|
||||
|
||||
}
|
||||
|
||||
public static class MyDefaultMethodEndpointAdapter
|
||||
extends DefaultMethodEndpointAdapter {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
package org.springframework.ws.config.annotation;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.ws.context.MessageContext;
|
||||
import org.springframework.ws.server.EndpointInterceptor;
|
||||
import org.springframework.ws.server.endpoint.adapter.DefaultMethodEndpointAdapter;
|
||||
import org.springframework.ws.server.endpoint.adapter.method.MethodArgumentResolver;
|
||||
import org.springframework.ws.server.endpoint.adapter.method.MethodReturnValueHandler;
|
||||
import org.springframework.ws.server.endpoint.interceptor.EndpointInterceptorAdapter;
|
||||
import org.springframework.ws.server.endpoint.mapping.PayloadRootAnnotationMethodEndpointMapping;
|
||||
|
||||
/**
|
||||
* @author Arjen Poutsma
|
||||
*/
|
||||
public class WsConfigurerAdapterTest {
|
||||
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
|
||||
applicationContext.register(TestConfig.class);
|
||||
applicationContext.refresh();
|
||||
|
||||
this.applicationContext = applicationContext;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void interceptors() {
|
||||
PayloadRootAnnotationMethodEndpointMapping endpointMapping = this.applicationContext.getBean(
|
||||
PayloadRootAnnotationMethodEndpointMapping.class);
|
||||
assertEquals(0, endpointMapping.getOrder());
|
||||
|
||||
EndpointInterceptor[] interceptors = endpointMapping.getInterceptors();
|
||||
assertEquals(1, interceptors.length);
|
||||
assertTrue(interceptors[0] instanceof MyInterceptor);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void argumentResolvers() {
|
||||
DefaultMethodEndpointAdapter endpointAdapter = this.applicationContext.getBean(DefaultMethodEndpointAdapter.class);
|
||||
|
||||
List<MethodArgumentResolver> argumentResolvers =
|
||||
endpointAdapter.getCustomMethodArgumentResolvers();
|
||||
assertEquals(1, argumentResolvers.size());
|
||||
assertTrue(argumentResolvers.get(0) instanceof MyMethodArgumentResolver);
|
||||
|
||||
argumentResolvers = endpointAdapter.getMethodArgumentResolvers();
|
||||
assertFalse(argumentResolvers.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void returnValueHandlers() {
|
||||
DefaultMethodEndpointAdapter endpointAdapter = this.applicationContext.getBean(DefaultMethodEndpointAdapter.class);
|
||||
|
||||
List<MethodReturnValueHandler> returnValueHandlers =
|
||||
endpointAdapter.getCustomMethodReturnValueHandlers();
|
||||
assertEquals(1, returnValueHandlers.size());
|
||||
assertTrue(returnValueHandlers.get(0) instanceof MyReturnValueHandler);
|
||||
|
||||
returnValueHandlers = endpointAdapter.getMethodReturnValueHandlers();
|
||||
assertFalse(returnValueHandlers.isEmpty());
|
||||
}
|
||||
|
||||
|
||||
@Configuration
|
||||
@EnableWs
|
||||
public static class TestConfig extends WsConfigurerAdapter {
|
||||
|
||||
@Override
|
||||
public void addInterceptors(List<EndpointInterceptor> interceptors) {
|
||||
interceptors.add(new MyInterceptor());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addArgumentResolvers(List<MethodArgumentResolver> argumentResolvers) {
|
||||
argumentResolvers.add(new MyMethodArgumentResolver());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addReturnValueHandlers(
|
||||
List<MethodReturnValueHandler> returnValueHandlers) {
|
||||
returnValueHandlers.add(new MyReturnValueHandler());
|
||||
}
|
||||
}
|
||||
|
||||
public static class MyInterceptor extends EndpointInterceptorAdapter {
|
||||
}
|
||||
|
||||
public static class MyMethodArgumentResolver implements MethodArgumentResolver {
|
||||
|
||||
@Override
|
||||
public boolean supportsParameter(MethodParameter parameter) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object resolveArgument(MessageContext messageContext,
|
||||
MethodParameter parameter) throws Exception {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static class MyReturnValueHandler implements MethodReturnValueHandler {
|
||||
|
||||
@Override
|
||||
public boolean supportsReturnType(MethodParameter returnType) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleReturnValue(MessageContext messageContext,
|
||||
MethodParameter returnType, Object returnValue) throws Exception {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -24,6 +24,10 @@ import javax.xml.parsers.ParserConfigurationException;
|
||||
import javax.xml.transform.Source;
|
||||
import javax.xml.transform.dom.DOMSource;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.util.Assert;
|
||||
@@ -32,10 +36,6 @@ import org.springframework.xml.sax.SaxUtils;
|
||||
import org.springframework.xml.validation.XmlValidator;
|
||||
import org.springframework.xml.validation.XmlValidatorFactory;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
/**
|
||||
* The default {@link XsdSchema} implementation.
|
||||
* <p/>
|
||||
@@ -98,8 +98,13 @@ public class SimpleXsdSchema implements XsdSchema, InitializingBean {
|
||||
return new DOMSource(schemaElement);
|
||||
}
|
||||
|
||||
public XmlValidator createValidator() throws IOException {
|
||||
return XmlValidatorFactory.createValidator(xsdResource, XmlValidatorFactory.SCHEMA_W3C_XML);
|
||||
public XmlValidator createValidator() {
|
||||
try {
|
||||
return XmlValidatorFactory.createValidator(xsdResource, XmlValidatorFactory.SCHEMA_W3C_XML);
|
||||
}
|
||||
catch (IOException ex) {
|
||||
throw new XsdSchemaException(ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
public void afterPropertiesSet() throws ParserConfigurationException, IOException, SAXException {
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
package org.springframework.xml.xsd;
|
||||
|
||||
import java.io.IOException;
|
||||
import javax.xml.transform.Source;
|
||||
|
||||
import org.springframework.xml.validation.XmlValidator;
|
||||
@@ -48,7 +47,6 @@ public interface XsdSchema {
|
||||
* Creates a {@link XmlValidator} based on the schema.
|
||||
*
|
||||
* @return a validator for this schema
|
||||
* @throws IOException in case of I/O errors
|
||||
*/
|
||||
XmlValidator createValidator() throws IOException;
|
||||
XmlValidator createValidator();
|
||||
}
|
||||
|
||||
@@ -16,8 +16,6 @@
|
||||
|
||||
package org.springframework.xml.xsd;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.springframework.xml.validation.XmlValidator;
|
||||
|
||||
/**
|
||||
@@ -39,8 +37,7 @@ public interface XsdSchemaCollection {
|
||||
* Creates a {@link XmlValidator} based on the schemas contained in this collection.
|
||||
*
|
||||
* @return a validator for this collection
|
||||
* @throws IOException in case of I/O errors
|
||||
*/
|
||||
XmlValidator createValidator() throws IOException;
|
||||
XmlValidator createValidator();
|
||||
|
||||
}
|
||||
|
||||
@@ -27,6 +27,11 @@ import javax.xml.transform.Source;
|
||||
import javax.xml.transform.dom.DOMSource;
|
||||
import javax.xml.transform.stream.StreamSource;
|
||||
|
||||
import org.apache.ws.commons.schema.XmlSchema;
|
||||
import org.apache.ws.commons.schema.XmlSchemaCollection;
|
||||
import org.apache.ws.commons.schema.XmlSchemaSerializer;
|
||||
import org.w3c.dom.Document;
|
||||
|
||||
import org.springframework.beans.BeanInstantiationException;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.core.io.Resource;
|
||||
@@ -36,11 +41,6 @@ import org.springframework.xml.validation.XmlValidator;
|
||||
import org.springframework.xml.validation.XmlValidatorFactory;
|
||||
import org.springframework.xml.xsd.XsdSchema;
|
||||
|
||||
import org.apache.ws.commons.schema.XmlSchema;
|
||||
import org.apache.ws.commons.schema.XmlSchemaCollection;
|
||||
import org.apache.ws.commons.schema.XmlSchemaSerializer;
|
||||
import org.w3c.dom.Document;
|
||||
|
||||
/**
|
||||
* Implementation of the {@link XsdSchema} interface that uses Apache WS-Commons XML Schema.
|
||||
*
|
||||
@@ -114,12 +114,18 @@ public class CommonsXsdSchema implements XsdSchema {
|
||||
return new StreamSource(bis);
|
||||
}
|
||||
|
||||
public XmlValidator createValidator() throws IOException {
|
||||
Resource resource = new UrlResource(schema.getSourceURI());
|
||||
return XmlValidatorFactory.createValidator(resource, XmlValidatorFactory.SCHEMA_W3C_XML);
|
||||
public XmlValidator createValidator() {
|
||||
try {
|
||||
Resource resource = new UrlResource(schema.getSourceURI());
|
||||
return XmlValidatorFactory
|
||||
.createValidator(resource, XmlValidatorFactory.SCHEMA_W3C_XML);
|
||||
}
|
||||
catch (IOException ex) {
|
||||
throw new CommonsXsdSchemaException(ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns the wrapped Commons <code>XmlSchema</code> object. */
|
||||
/** Returns the wrapped Commons <code>XmlSchema</code> object. */
|
||||
public XmlSchema getSchema() {
|
||||
return schema;
|
||||
}
|
||||
|
||||
@@ -22,6 +22,18 @@ import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.ws.commons.schema.XmlSchema;
|
||||
import org.apache.ws.commons.schema.XmlSchemaCollection;
|
||||
import org.apache.ws.commons.schema.XmlSchemaExternal;
|
||||
import org.apache.ws.commons.schema.XmlSchemaImport;
|
||||
import org.apache.ws.commons.schema.XmlSchemaInclude;
|
||||
import org.apache.ws.commons.schema.XmlSchemaObject;
|
||||
import org.apache.ws.commons.schema.resolver.DefaultURIResolver;
|
||||
import org.apache.ws.commons.schema.resolver.URIResolver;
|
||||
import org.xml.sax.InputSource;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.context.ResourceLoaderAware;
|
||||
import org.springframework.core.io.Resource;
|
||||
@@ -35,18 +47,6 @@ import org.springframework.xml.validation.XmlValidatorFactory;
|
||||
import org.springframework.xml.xsd.XsdSchema;
|
||||
import org.springframework.xml.xsd.XsdSchemaCollection;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.ws.commons.schema.XmlSchema;
|
||||
import org.apache.ws.commons.schema.XmlSchemaCollection;
|
||||
import org.apache.ws.commons.schema.XmlSchemaExternal;
|
||||
import org.apache.ws.commons.schema.XmlSchemaImport;
|
||||
import org.apache.ws.commons.schema.XmlSchemaInclude;
|
||||
import org.apache.ws.commons.schema.XmlSchemaObject;
|
||||
import org.apache.ws.commons.schema.resolver.DefaultURIResolver;
|
||||
import org.apache.ws.commons.schema.resolver.URIResolver;
|
||||
import org.xml.sax.InputSource;
|
||||
|
||||
/**
|
||||
* Implementation of the {@link XsdSchemaCollection} that uses Apache WS-Commons XML Schema.
|
||||
* <p/>
|
||||
@@ -162,16 +162,21 @@ public class CommonsXsdSchemaCollection implements XsdSchemaCollection, Initiali
|
||||
return result;
|
||||
}
|
||||
|
||||
public XmlValidator createValidator() throws IOException {
|
||||
Resource[] resources = new Resource[xmlSchemas.size()];
|
||||
for (int i = xmlSchemas.size() - 1; i >= 0; i--) {
|
||||
XmlSchema xmlSchema = xmlSchemas.get(i);
|
||||
String sourceUri = xmlSchema.getSourceURI();
|
||||
if (StringUtils.hasLength(sourceUri)) {
|
||||
resources[i] = new UrlResource(sourceUri);
|
||||
}
|
||||
}
|
||||
return XmlValidatorFactory.createValidator(resources, XmlValidatorFactory.SCHEMA_W3C_XML);
|
||||
public XmlValidator createValidator() {
|
||||
try {
|
||||
Resource[] resources = new Resource[xmlSchemas.size()];
|
||||
for (int i = xmlSchemas.size() - 1; i >= 0; i--) {
|
||||
XmlSchema xmlSchema = xmlSchemas.get(i);
|
||||
String sourceUri = xmlSchema.getSourceURI();
|
||||
if (StringUtils.hasLength(sourceUri)) {
|
||||
resources[i] = new UrlResource(sourceUri);
|
||||
}
|
||||
}
|
||||
return XmlValidatorFactory
|
||||
.createValidator(resources, XmlValidatorFactory.SCHEMA_W3C_XML);
|
||||
} catch (IOException ex) {
|
||||
throw new CommonsXsdSchemaException(ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
private void inlineIncludes(XmlSchema schema, Set<XmlSchema> processedIncludes, Set<XmlSchema> processedImports) {
|
||||
|
||||
@@ -148,6 +148,40 @@
|
||||
that means that it looks for '<filename>/WEB-INF/spring-ws-servlet.xml</filename>'. This file will
|
||||
contain all of the Spring Web Services beans such as endpoints, marshallers and suchlike.
|
||||
</para>
|
||||
<para>
|
||||
As an alternative for <filename>web.xml</filename>, if you are running on a Servlet 3+ environment, you
|
||||
can configure Spring-WS programmatically.
|
||||
For this purpose, Spring-WS provides a number of abstract base classes that extend the
|
||||
<interfacename>WebApplicationInitializer</interfacename> interface found in the Spring Framework.
|
||||
If you are also using <interfacename>@Configuration</interfacename> classes for your bean definitions, you are
|
||||
best of extending the <classname>AbstractAnnotationConfigMessageDispatcherServletInitializer</classname>, like so:
|
||||
</para>
|
||||
<programlisting><![CDATA[public class MyServletInitializer
|
||||
extends AbstractAnnotationConfigMessageDispatcherServletInitializer {
|
||||
|
||||
@Override
|
||||
protected Class<?>[] getRootConfigClasses() {
|
||||
return new Class[]{MyRootConfig.class};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<?>[] getServletConfigClasses() {
|
||||
return new Class[]{MyEndpointConfig.class};
|
||||
}
|
||||
|
||||
}]]></programlisting>
|
||||
<para>
|
||||
In the example above, we tell Spring that endpoint bean definitions can be found in the <classname>MyEndpointConfig</classname>
|
||||
class (which is a <interfacename>@Configuration</interfacename> class).
|
||||
Other bean definitions (typically services, repositories, etc.) can be found in the <classname>MyRootConfig</classname>
|
||||
class.
|
||||
By default, the <classname>AbstractAnnotationConfigMessageDispatcherServletInitializer</classname> maps the servlet to
|
||||
two patterns: <filename>/services</filename> and <filename>*.wsdl</filename>, though this can be changed by overriding the
|
||||
<methodname>getServletMappings()</methodname> method.
|
||||
For more details on the programmatic configuration of the <classname>MessageDispatcherServlet</classname>, refer to the
|
||||
Javadoc of <classname>AbstractMessageDispatcherServletInitializer</classname> and
|
||||
<classname>AbstractAnnotationConfigMessageDispatcherServletInitializer</classname>.
|
||||
</para>
|
||||
<section id="server-automatic-wsdl-exposure">
|
||||
<title>Automatic WSDL exposure</title>
|
||||
<para>
|
||||
@@ -164,9 +198,16 @@
|
||||
Take notice of the value of the '<literal>id</literal>' attribute, because this will be used when
|
||||
exposing the WSDL.
|
||||
</para>
|
||||
<programlisting><![CDATA[<sws:static-wsdl id="orders" location="/WEB-INF/wsdl/orders.wsdl"/>]]></programlisting>
|
||||
<programlisting><![CDATA[<sws:static-wsdl id="orders" location="orders.wsdl"/>]]></programlisting>
|
||||
<para>
|
||||
The WSDL defined in the '<filename>Orders.wsdl</filename>' file can then be accessed via
|
||||
Or as <interfacename>@Bean</interfacename> method in a <interfacename>@Configuration</interfacename> class:
|
||||
</para>
|
||||
<programlisting><![CDATA[@Bean
|
||||
public SimpleWsdl11Definition orders() {
|
||||
return new SimpleWsdl11Definition(new ClassPathResource("orders.xml"));
|
||||
}]]></programlisting>
|
||||
<para>
|
||||
The WSDL defined in the '<filename>orders.wsdl</filename>' file on the classpath can then be accessed via
|
||||
<literal>GET</literal> requests to a URL of the following form (substitute the host, port and
|
||||
servlet context path as appropriate).
|
||||
</para>
|
||||
@@ -174,9 +215,9 @@
|
||||
<note>
|
||||
<para>
|
||||
All <interfacename>WsdlDefinition</interfacename> bean definitions are exposed by the
|
||||
<classname>MessageDispatcherServlet</classname> under their bean id (or bean name) with the
|
||||
<classname>MessageDispatcherServlet</classname> under their bean name with the
|
||||
suffix <literal>.wsdl</literal>.
|
||||
So if the bean id is <literal>echo</literal>, the host name is "server", and the Servlet
|
||||
So if the bean name is <literal>echo</literal>, the host name is "server", and the Servlet
|
||||
context (war name) is "spring-ws", the WSDL can be obtained via
|
||||
<uri>http://server/spring-ws/echo.wsdl</uri>
|
||||
</para>
|
||||
@@ -209,6 +250,11 @@
|
||||
</servlet-mapping>
|
||||
|
||||
</web-app>]]></programlisting>
|
||||
<para>
|
||||
If you use the <classname>AbstractAnnotationConfigMessageDispatcherServletInitializer</classname>,
|
||||
enabling transformation is as simple as overriding the <methodname>isTransformWsdlLocations()</methodname>
|
||||
method to return <literal>true</literal>.
|
||||
</para>
|
||||
<para>
|
||||
Consult the class-level Javadoc on the <classname>WsdlDefinitionHandlerAdapter</classname> class
|
||||
to learn more about the whole transformation process.
|
||||
@@ -223,10 +269,33 @@
|
||||
<programlisting><![CDATA[<sws:dynamic-wsdl id="orders"
|
||||
portTypeName="Orders"
|
||||
locationUri="http://localhost:8080/ordersService/">
|
||||
<sws:xsd location="/WEB-INF/xsd/Orders.xsd"/>
|
||||
<sws:xsd location="Orders.xsd"/>
|
||||
</sws:dynamic-wsdl>]]></programlisting>
|
||||
<para>
|
||||
The <literal><dynamic-wsdl></literal> builds a WSDL from a XSD schema by using conventions.
|
||||
Or, as <interfacename>@Bean</interfacename> method:
|
||||
</para>
|
||||
<programlisting><![CDATA[@Bean
|
||||
public DefaultWsdl11Definition orders() {
|
||||
DefaultWsdl11Definition definition = new DefaultWsdl11Definition();
|
||||
definition.setPortTypeName("Orders");
|
||||
definition.setLocationUri("http://localhost:8080/ordersService/");
|
||||
definition.setSchema(new SimpleXsdSchema(new ClassPathResource("echo.xsd")));
|
||||
|
||||
return definition;
|
||||
}]]></programlisting>
|
||||
<para>
|
||||
The <literal><dynamic-wsdl></literal> element depends on the
|
||||
<classname>DefaultWsdl11Definition</classname> class.
|
||||
This definition class uses WSDL providers in the
|
||||
<package>org.springframework.ws.wsdl.wsdl11.provider</package> package and the
|
||||
<classname>ProviderBasedWsdl4jDefinition</classname>
|
||||
to generate a WSDL the first time it is requested.
|
||||
Refer to the class-level Javadoc of these classes to see how you can extend this mechanism,
|
||||
if necessary.
|
||||
</para>
|
||||
<para>
|
||||
The <classname>DefaultWsdl11Definition</classname> (and therefore, the <literal><dynamic-wsdl></literal> tag)
|
||||
builds a WSDL from a XSD schema by using conventions.
|
||||
It iterates over all <literal>element</literal> elements
|
||||
found in the schema, and creates a <literal>message</literal> for all elements.
|
||||
Next, it creates WSDL <literal>operation</literal> for all messages that end with the
|
||||
@@ -254,16 +323,6 @@
|
||||
This greatly simplifies the deployment of the schemas, which still making it possible to edit them
|
||||
separately.
|
||||
</para>
|
||||
<para>
|
||||
The <literal><dynamic-wsdl></literal> element depends on the
|
||||
<classname>DefaultWsdl11Definition</classname> class.
|
||||
This definition class uses WSDL providers in the
|
||||
<package>org.springframework.ws.wsdl.wsdl11.provider</package> package and the
|
||||
<classname>ProviderBasedWsdl4jDefinition</classname>
|
||||
to generate a WSDL the first time it is requested.
|
||||
Refer to the class-level Javadoc of these classes to see how you can extend this mechanism,
|
||||
if necessary.
|
||||
</para>
|
||||
<caution>
|
||||
<para>
|
||||
Even though it can be quite handy to create the WSDL at runtime from your XSDs, there
|
||||
@@ -305,13 +364,13 @@
|
||||
|
||||
...
|
||||
|
||||
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
|
||||
|
||||
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/>
|
||||
|
||||
</beans>]]></programlisting>
|
||||
Note that by explicitly adding the <classname>WebServiceMessageReceiverHandlerAdapter</classname>,
|
||||
the dispatcher servlet does not load the default adapters, and is unable to handle standard Spring-MVC
|
||||
<interfacename>Controllers</interfacename>. Therefore, we add the
|
||||
<classname>SimpleControllerHandlerAdapter</classname> at the end.
|
||||
<interfacename>@Controllers</interfacename>. Therefore, we add the
|
||||
<classname>RequestMappingHandlerAdapter</classname> at the end.
|
||||
</para>
|
||||
<para>
|
||||
In a similar fashion, you can wire up a <classname>WsdlDefinitionHandlerAdapter</classname> to make sure
|
||||
@@ -382,12 +441,6 @@
|
||||
</bean>
|
||||
</beans>]]></programlisting>
|
||||
</para>
|
||||
<para>
|
||||
As an alternative to the <classname>WebServiceMessageListener</classname>, Spring Web Services provides
|
||||
a <classname>WebServiceMessageDrivenBean</classname>, an EJB
|
||||
<interfacename>MessageDrivenBean</interfacename>. For more information on EJB, refer to the class level
|
||||
Javadoc of the <classname>WebServiceMessageDrivenBean</classname>.
|
||||
</para>
|
||||
</section>
|
||||
<section>
|
||||
<title>Email transport</title>
|
||||
@@ -700,13 +753,46 @@ public class AnnotationOrderEndpoint {
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
<emphasis role="bold">xmlns:sws="http://www.springframework.org/schema/web-services"</emphasis>
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
<emphasis role="bold">http://www.springframework.org/schema/web-services
|
||||
http://www.springframework.org/schema/web-services/web-services-2.0.xsd"></emphasis>
|
||||
http://www.springframework.org/schema/web-services/web-services.xsd"></emphasis>
|
||||
|
||||
<emphasis role="bold"><sws:annotation-driven /></emphasis>
|
||||
|
||||
</beans></programlisting>
|
||||
</para>
|
||||
<para>
|
||||
Or, if you are using <interfacename>@Configuration</interfacename> classes instead of Spring XML, you can
|
||||
annotate your configuration class with <interfacename>@EnableWs</interfacename>, like so:
|
||||
</para>
|
||||
<programlisting><emphasis role="bold">@EnableWs</emphasis>
|
||||
@Configuration
|
||||
public class EchoConfig {
|
||||
|
||||
// @Bean definitions go here
|
||||
|
||||
}</programlisting>
|
||||
<para>
|
||||
To customize the <interfacename>@EnableWs</interfacename> configuration, you can implement
|
||||
<interfacename>WsConfigurer</interfacename>, or better yet extend the
|
||||
<classname>WsConfigurerAdapter</classname>.
|
||||
For instance:<programlisting>@Configuration
|
||||
@EnableWs
|
||||
@ComponentScan(basePackageClasses = { MyConfiguration.class })
|
||||
public class MyConfiguration extends WsConfigurerAdapter {
|
||||
|
||||
@Override
|
||||
public void addInterceptors(List<EndpointInterceptor> interceptors) {
|
||||
interceptors.add(new MyInterceptor());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addArgumentResolvers(List<MethodArgumentResolver> argumentResolvers) {
|
||||
argumentResolvers.add(new MyArgumentResolver());
|
||||
}
|
||||
|
||||
// More overridden methods ...
|
||||
}</programlisting>
|
||||
</para>
|
||||
<para>
|
||||
In the next couple of sections, a more elaborate description of the <interfacename>@Endpoint</interfacename>
|
||||
@@ -1258,7 +1344,7 @@ public class AnnotationOrderEndpoint {
|
||||
security-related SOAP headers, or the logging of request and response message.
|
||||
</para>
|
||||
<para>
|
||||
Endpoint interceptors are typically defined by using a <literal><sws;interceptors ></literal>
|
||||
Endpoint interceptors are typically defined by using a <literal><sws:interceptors></literal>
|
||||
element in your application context.
|
||||
In this element, you can simply define endpoint interceptor beans that apply to all endpoints defined
|
||||
in that application context.
|
||||
@@ -1289,6 +1375,20 @@ public class AnnotationOrderEndpoint {
|
||||
is actually a reference to a bean definition outside of the <literal><interceptors></literal>
|
||||
element. You can use bean references anywhere inside the <literal><interceptors></literal> element.
|
||||
</para>
|
||||
<para>
|
||||
When using <interfacename>@Configuration</interfacename> classes, you can extend from
|
||||
<classname>WsConfigurerAdapter</classname> to add interceptors.
|
||||
Like so:<programlisting>@Configuration
|
||||
@EnableWs
|
||||
public class MyWsConfiguration extends WsConfigurerAdapter {
|
||||
|
||||
@Override
|
||||
public void addInterceptors(List<EndpointInterceptor> interceptors) {
|
||||
interceptors.add(new MyPayloadRootInterceptor());
|
||||
}
|
||||
|
||||
}</programlisting>
|
||||
</para>
|
||||
<para>
|
||||
Interceptors must implement the
|
||||
<interfacename>EndpointInterceptor</interfacename> interface from the
|
||||
@@ -1328,14 +1428,16 @@ public class AnnotationOrderEndpoint {
|
||||
<programlisting><![CDATA[
|
||||
<sws:interceptors>
|
||||
<bean class="org.springframework.ws.server.endpoint.interceptor.PayloadLoggingInterceptor"/>
|
||||
</sws:interceptors>
|
||||
|
||||
</beans>]]></programlisting>
|
||||
</sws:interceptors>]]></programlisting>
|
||||
<para>
|
||||
Both of these interceptors have two properties: '<property>logRequest</property>' and
|
||||
'<property>logResponse</property>', which can be set to <literal>false</literal> to disable logging
|
||||
for either request or response messages.
|
||||
</para>
|
||||
<para>
|
||||
Of course, you could use the <classname>WsConfigurerAdapter</classname> approach, as described above,
|
||||
for the <classname>PayloadLoggingInterceptor</classname> as well.
|
||||
</para>
|
||||
</section>
|
||||
<section>
|
||||
<title><classname>PayloadValidatingInterceptor</classname></title>
|
||||
@@ -1367,6 +1469,10 @@ public class AnnotationOrderEndpoint {
|
||||
<property name="validateRequest" value="false"/>
|
||||
<property name="validateResponse" value="true"/>
|
||||
</bean>]]></programlisting>
|
||||
<para>
|
||||
Of course, you could use the <classname>WsConfigurerAdapter</classname> approach, as described above,
|
||||
for the <classname>PayloadValidatingInterceptor</classname> as well.
|
||||
</para>
|
||||
</section>
|
||||
<section>
|
||||
<title><classname>PayloadTransformingInterceptor</classname></title>
|
||||
@@ -1389,6 +1495,10 @@ public class AnnotationOrderEndpoint {
|
||||
endpoint mapping that applies to the "old style" messages, and add the interceptor to that mapping.
|
||||
Hence, the transformation will apply only to these "old style" message.
|
||||
</para>
|
||||
<para>
|
||||
Of course, you could use the <classname>WsConfigurerAdapter</classname> approach, as described above,
|
||||
for the <classname>PayloadTransformingInterceptor</classname> as well.
|
||||
</para>
|
||||
</section>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
Reference in New Issue
Block a user