I've started learning the Apache CXF with Spring. First of all, I've tried to create a simple client/server model.
The server-side is: service.HelloWorld.java
@WebService
public interface HelloWorld {
String sayHi(String text);
}
service.HelloWorldImpl.java
@WebService(endpointInterface = "service.HelloWorld")
public class HelloWorldImpl implements HelloWorld {
public String sayHi(String text) {
return "Hello, " + text;
}
}
The client-side is: client.Client.java public class Client {
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"cxf-client-servlet.xml"});
HelloWorld client = (HelloWorld) context.getBean("client");
System.out.println(client.sayHi("Batman"));
}
}
cxf-client-servlet.xml
<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/schema/jaxws.xsd">
<bean id="client" class="service.HelloWorld" factory-bean="clientFactory" factory-method="create"/>
<bean id="clientFactory" class="org.apache.cxf.jaxws.JaxWsProxyFactoryBean">
<property name="serviceClass" value="service.HelloWorld"/>
<property name="address" value="http://localhost:8080/services/HelloWorld"/>
</bean>
The problem is: to make the client work I've had to add service.HelloWorld (package + interface) to the clients's project. I've heard that before using a service I need to generate a stub. So it's confusing for me. So that, what is the correct approach and what is the best practice (may be it is better to use some contract-first approach or suchlike)? Later, I want to add WS-Security, so I need a strong background =)
Thanks in advance.
You can use a simple spring configuration like this for client side -
<jaxws:client id="mywebServiceClient"
serviceClass="com.saurzcode.TestService"
address="http://saurzcode.com:8088/mockTestService">
<jaxws:binding>
<soap:soapBinding version="1.2" mtomEnabled="true" />
</jaxws:binding>
</jaxws:client>
<cxf:bus>
<cxf:outInterceptors>
<bean class="com.saurzcode.ws.caller.SoapHeaderInterceptor" />
</cxf:outInterceptors>
</cxf:bus>
Ignore the Interceptor if you don't need it.
More details in this post.
If you are doing code-first WS development then it is fine to distribute the interface and give it to the client. I believe @WebService
is not needed (?) on the interface (only implementation), so the client does not have dependencies on this annotation.
Even if you are doing code-first web-services, you may still download the WSDL document generated for you by Apache CXF and give it to the client instead. With this approach (which is considered more mature, not to mention it can be used on different platforms like .NET) the client has to generate the stubs (using tool like wsdl2java
). This process will essentially create very similar client interface automatically.
That's one of the reasons why so many people prefer contract-first development - the same WSDL is used to generate client-side stubs and server-side WS implementation. This limits the scope of (accidental) incompatibilites.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With