...
A JAX-WS Endpoint can be configured in XML in addition to using the JAX-WS APIs. Once you've created your server implementation, you simply need to provide the class name and an address. Here is a simple example:
Code Block | ||||
---|---|---|---|---|
| ||||
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">
<jaxws:endpoint id="classImpl"
implementor="org.apache.cxf.jaxws.service.Hello"
endpointName="e:HelloEndpointCustomized"
serviceName="s:HelloServiceCustomized"
address="http://localhost:8080/test"
xmlns:e="http://service.jaxws.cxf.apache.org/endpoint"
xmlns:s="http://service.jaxws.cxf.apache.org/service"/>
</beans>
|
...
Here is a more advanced example which shows how to provide interceptors and properties:
Code Block | ||||
---|---|---|---|---|
| ||||
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xmlns:soap="http://cxf.apache.org/bindings/soap"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://cxf.apache.org/bindings/soap
http://cxf.apache.org/schemas/configuration/soap.xsd
http://cxf.apache.org/jaxws
http://cxf.apache.org/schemas/jaxws.xsd">
<import resource="classpath:META-INF/cxf/cxf.xml"/>
<import resource="classpath:META-INF/cxf/cxf-extension-soap.xml"/>
<jaxws:endpoint
id="helloWorld"
implementor="demo.spring.HelloWorldImpl"
address="http://localhost/HelloWorld">
<jaxws:inInterceptors>
<bean class="com.acme.SomeInterceptor"/>
<ref bean="anotherInterceptor"/>
</jaxws:inInterceptor>
<jaxws:properties>
<entry key="mtom-enabled" value="true"/>
</jaxws:properties>
</jaxws:endpoint>
<bean id="anotherInterceptor" class="com.acme.SomeInterceptor"/>
<jaxws:endpoint id="simpleWithBinding"
implementor="#greeter"
address="http://localhost:8080/simpleWithAddress">
<jaxws:binding>
<soap:soapBinding mtomEnabled="true" version="1.2"/>
</jaxws:binding>
</jaxws:endpoint>
<jaxws:endpoint id="inlineInvoker"
address="http://localhost:8080/simpleWithAddress">
<jaxws:implementor>
<bean class="org.apache.hello_world_soap_http.GreeterImpl"/>
</jaxws:implementor>
<jaxws:invoker>
<bean class="org.apache.cxf.jaxws.spring.NullInvoker"/>
</jaxws:invoker>
</jaxws:endpoint>
</beans>
|
...
The easiest way to add a Web Services client to a Spring context is to use the <jaxws:client>
element (similar to the <jaxws:endpoint>
element used for the server side). Here's a simple example:
Code Block | ||||
---|---|---|---|---|
| ||||
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/jaxws
http://cxf.apache.org/schemas/jaxws.xsd">
<jaxws:client id="helloClient"
serviceClass="demo.spring.HelloWorld"
address="http://localhost:9002/HelloWorld" />
</beans>
|
...
Here is a more advanced example which shows how to provide interceptors, JAX-WS handlers, and properties:
Code Block | ||||
---|---|---|---|---|
| ||||
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/jaxws
http://cxf.apache.org/schemas/jaxws.xsd">
<!-- Interceptors extend e.g.
org.apache.cxf.phase.AbstractPhaseInterceptor -->
<bean id="anotherInterceptor" class="..." />
<!-- Handlers implement e.g. javax.xml.ws.handler.soap.SOAPHandler -->
<bean id="jaxwsHandler" class="..." />
<!-- The SOAP client bean -->
<jaxws:client id="helloClient"
serviceClass="demo.spring.HelloWorld"
address="http://localhost:9002/HelloWorld">
<jaxws:inInterceptors>
<bean class="org.apache.cxf.interceptor.LoggingInInterceptor"/>
<ref bean="anotherInterceptor"/>
</jaxws:inInterceptor>
<jaxws:handlers>
<ref bean="jaxwsHandler" />
</jaxws:handlers>
<jaxws:properties>
<entry key="mtom-enabled" value="true"/>
</jaxws:properties>
</jaxws:client>
</beans>
|
...
This approach requires more explicit Spring bean configuration than the previous option, and may require more configuration data depending on which features are used. To configure a client this way, you'll need to declare a proxy factory bean and also a client bean which is created by that proxy factory. Here is an example:
Code Block | ||||
---|---|---|---|---|
| ||||
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://cxf.apache.org/jaxws
http://cxf.apache.org/schemas/jaxws.xsd">
<bean id="proxyFactory"
class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">
<property name="serviceClass" value="demo.spring.HelloWorld"/>
<property name="address" value="http://localhost:9002/HelloWorld"/>
</bean>
<bean id="client" class="demo.spring.HelloWorld"
factory-bean="proxyFactory" factory-method="create"/>
</beans>
|
...
The second bean definition is for the client. In this case it implements the HelloWorld interface and is created by the proxyFactory <bean> by calling the create() method. You can then reference this "client" bean and inject it anywhere into your application. Here is an example of a very simple Java class which accesses the client bean:
Code Block | ||||
---|---|---|---|---|
| ||||
include org.springframework.context.support.ClassPathXmlApplicationContext;
public final class HelloWorldClient {
private HelloWorldClient() { }
public static void main(String args[]) throws Exception {
ClassPathXmlApplicationContext context
= new ClassPathXmlApplicationContext(
new String[]{"my/path/to/client-beans.xml"});
HelloWorld client = (HelloWorld)context.getBean("client");
String response = client.sayHi("Dan");
System.out.println("Response: " + response);
System.exit(0);
}
}
|
...
Using some of the properties will require additional configuration in the Spring context. For instance, using JAX-WS handlers requires that you explicitly import several CXF Spring configurations, and assign the "bus" property of the JaxWsProxyFactory bean like this:
Code Block | ||||
---|---|---|---|---|
| ||||
<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
<import resource="classpath:META-INF/cxf/cxf-extension-http.xml" />
<bean id="clientFactory" class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">
<property name="serviceClass" value="demo.spring.HelloWorld"/>
<property name="address" value="http://localhost:9002/HelloWorld"/>
<property name="bus" ref="cxf" />
</bean>
|
...
To cast a client proxy to a CXF client:
Code Block | ||||
---|---|---|---|---|
| ||||
GreeterService gs = new GreeterService();
Greeter greeter = gs.getGreeterPort();
org.apache.cxf.endpoint.Client client =
org.apache.cxf.frontend.ClientProxy.getClient(greeter);
org.apache.cxf.endpoint.Endpoint cxfEndpoint = client.getEndpoint();
cxfEndpoint.getOutInterceptors().add(...);
|
To cast a JAX-WS endpoint to a CXF server:
Code Block | ||||
---|---|---|---|---|
| ||||
javax.xml.ws.Endpoint jaxwsEndpoint = javax.xml.ws.Endpoint.publish(
"http://localhost:9020/SoapContext/GreeterPort", new GreeterImpl());
org.apache.cxf.jaxws.EndpointImpl jaxwsEndpointImpl =
(org.apache.cxf.jaxws.EndpointImpl)jaxwsEndpoint;
org.apache.cxf.endpoint.Server server = jaxwsEndpointImpl.getServer();
org.apache.cxf.endpoint.Endpoint cxfEndpoint = server.getEndpoint();
cxfEndpoint.getOutInterceptors().add(...);
org.apache.cxf.service.Service cxfService = cxfEndpoint.getService();
cxfService.getOutInterceptors().add(...);
|
...
CXF provides <jaxws:server>, <jaxws:client> to configure the server/client side endpoint. Here are some examples:
Code Block | ||||
---|---|---|---|---|
| ||||
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xmlns:soap="http://cxf.apache.org/bindings/soap"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://cxf.apache.org/bindings/soap
http://cxf.apache.org/schemas/configuration/soap.xsd
http://cxf.apache.org/jaxws
http://cxf.apache.org/schemas/jaxws.xsd">
<jaxws:server id="inlineImplementor" address="http://localhost:8080/simpleWithAddress">
<jaxws:serviceBean>
<bean class="org.apache.hello_soap_http.GreeterImpl"/>
</jaxws:serviceBean>
</jaxws:server>
<jaxws:server id="bookServer" serviceClass=
"org.apache.cxf.mytype.AnonymousComplexTypeImpl"
address="http://localhost:8080/act"
bus="cxf">
<jaxws:invoker>
<bean class="org.apache.cxf.service.invoker.BeanInvoker">
<constructor-arg>
<bean class="org.apache.cxf.mytype.AnonymousComplexTypeImpl"/>
</constructor-arg>
</bean>
</jaxws:invoker>
<jaxws:dataBinding>
<bean class="org.apache.cxf.jaxb.JAXBDataBinding">
<property name="namespaceMap">
<map>
<entry>
<key>
<value>http://cxf.apache.org/anon_complex_type/</value>
</key>
<value>BeepBeep</value>
</entry>
</map>
</property>
</bean>
</jaxws:dataBinding>
</jaxws:server>
<jaxws:client id="bookClient"
serviceClass="org.apache.cxf.mytype.AnonymousComplexType"
address="http://localhost:8080/act"/>
</beans>
|
Since JAX-WS frontend server and client spring configuration parser are inherited from the simple frontend, please see Simple Frontend Configuration for the attribute and element definitions.
Configure the JAXWS Server Using SpringBoot
Here is an example:
Code Block | ||
---|---|---|
| ||
import org.apache.cxf.Bus; import org.apache.cxf.jaxws.EndpointImpl; import org.apache.cxf.transport.servlet.CXFServlet; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory; import org.springframework.boot.context.embedded.ServletRegistrationBean; import org.springframework.boot.context.web.SpringBootServletInitializer; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.ImportResource; @Configuration @EnableAutoConfiguration @ImportResource({ "classpath:META-INF/cxf/cxf.xml" }) public class Application extends SpringBootServletInitializer { @Autowired private ApplicationContext applicationContext; public static void main(String[] args) { SpringApplication.run(Application.class, args); } // Replaces the need for web.xml @Bean public ServletRegistrationBean servletRegistrationBean(ApplicationContext context) { return new ServletRegistrationBean(new CXFServlet(), "/api/*"); } // Replaces cxf-servlet.xml @Bean // <jaxws:endpoint id="helloWorld" implementor="demo.spring.service.HelloWorldImpl" address="/HelloWorld"/> public EndpointImpl helloService() { Bus bus = (Bus) applicationContext.getBean(Bus.DEFAULT_BUS_ID); Object implementor = new HelloWorldImpl(); EndpointImpl endpoint = new EndpointImpl(bus, implementor); endpoint.publish("/hello"); return endpoint; } // Used when deploying to a standalone servlet container, i.e. tomcat @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { return application.sources(Application.class); } } |