1.Think about AJAX Web Service Calling
JavaScript runs in a single thread, however, it is able to call web service asynchronously.
Can a Java thread call web service asynchronously with NIO's help, rather than executor's. NIO would not block any thread, whereas calling web service via executor does block. Web service calling is rather time consuming, ranges from tens of milliseconds to several seconds in our practice, lots of blocking means very limited concurrency, as the underlying thread pool would be fully occupied shortly.
2. Why not employ JDK's built-in JAX-WS implementation? we apply CXF instead
In short, JDK's built-in JAX-WS implementation would block underlying thread, though it works in asynchronous manner. Conversely, CXF's JAX-RS implementation can utilize NIO, which would not block. CXF official site says:
CXF also has an HTTP client transport that is based on the Apache HTTP Components HttpAsyncClient library. The HttpAsyncClient library uses a non-blocking IO model.
More detailed analysis please refer to R2 and official documentation.
There is a brilliant article talking about non-blocking SOAP web service invocation, please refer to R2. This article covers the most critical part, however, I need to experiment and measure its test result, especially, Spring integration with CXF.
3. How to develop a non-blocking soap web service with CXF and Spring?
3.1 Generate Client Stub Code
3.1.1 Download CXF, we need the wsdl2java tool
3.1.2 Create async_binding.xml file
If you wonder why we need this file, please refer to R4
<bindings xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" wsdlLocation="http://10.9.1.99/vservice/BetService.asmx?wsdl" xmlns="http://java.sun.com/xml/ns/jaxws"> <bindings node="wsdl:definitions"> <enableAsyncMapping>true</enableAsyncMapping> </bindings> </bindings>3.1.3 Execute the wsdl2java
E:\apache-cxf-2.7.6\bin>wsdl2java -ant -client -p com.sv.bcs.provider.cxf.stub -d ws -b d:\async_binding.xml -encoding utf8 http://10.9.1.99/vservice/BetService.asmx?wsdlIssue: the generated code has Chinese character in the comments and in ANSI encoding, rather than our favorite utf8, very unpleasant, how to fix this issue?
3.2 Add CXF Dependencies with Maven
3.3 Spring Integration with CXF
Spring application context configuration seems instinctively easy.
<?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>AsyncHandler doesn't appear in application context? AsyncHandler lies in SEI.
3.4 AsyncHandler and Response Interface
javax.xml.ws.AsyncHandler
public interface AsyncHandler<T> { /** Called when the response to an asynchronous operation is available. * * @param res The response to the operation invocation. * **/ void handleResponse(Response<T> res); }
public interface Response<T> extends Future<T> { /** Gets the contained response context. * * @return The contained response context. May be <code>null</code> if a * response is not yet available. * **/ Map<String,Object> getContext(); }Why we need a future object when callback? as we all know that Future.get() would cause blocking. Beside, we can think about how AJAX do callback?
TO BE CONTINUED
Reference 1: http://www.javascriptkata.com/2007/06/12/ajax-javascript-and-threads-the-final-truth/
Reference 2: http://czechscala.com/2013/05/13/non-blocking-soap-web-services-invocation/
Reference 3: Configuring a Spring Client. http://cxf.apache.org/docs/jax-ws-configuration.html
Reference 4: Asynchronous Invocation Model. http://cxf.apache.org/docs/developing-a-consumer.html