In this article I'll be demonstrating two ways to compress Apache CXF SOAP requests and responses to conserve network resources--Fast Infoset (FI) and GZip compression. We'll modify the introductory DoubleIt web service tutorial to test this functionality along with Wireshark to see how the SOAP requests and responses change as a result. The code modifications necessary are quite minimal, just a few lines over one or two source files.
As a reference point, let's use Wireshark to see the SOAP request and response for a standard DoubleIt call without compression:
POST /doubleit/services/doubleit HTTP/1.1 Content-Type: text/xml; charset=UTF-8 Accept: */* SOAPAction: "" User-Agent: Apache-CXF/3.2.2 Cache-Control: no-cache Pragma: no-cache Host: localhost:8080 Connection: keep-alive Content-Length: 224 <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Body> <ns2:DoubleIt xmlns:ns2="http://www.example.org/schema/DoubleIt"> <numberToDouble>10</numberToDouble> </ns2:DoubleIt> </soap:Body> </soap:Envelope> HTTP/1.1 200 Content-Type: text/xml;charset=UTF-8 Content-Length: 238 Date: Sat, 10 Mar 2018 16:09:14 GMT <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Body> <ns2:DoubleItResponse xmlns:ns2="http://www.example.org/schema/DoubleIt"> <doubledNumber>20</doubledNumber> </ns2:DoubleItResponse> </soap:Body> </soap:Envelope>
First, let's activate fast infoset, both client- and service-side. The negotiation process involves the SOAP client sending an uncompressed Accept: application/fastinfoset
HTTP header in the first SOAP request. If the server is configured to support FI, it will return a compressed SOAP response with a content type of application/fastinfoset
. Subsequently all SOAP requests and responses between the client and web service provider will then use FI. However, if the server is not configured to use FI the server will return an uncompressed SOAP response with the usual text/xml
Content-Type. The following table shows how to activate FI:
Component | How to implement Fast Infoset Compression |
---|---|
CXF Web Service Provider |
Add the FastInfoset dependency to your project. Then attach the @FastInfoset feature to either the Service Endpoint Interface (SEI) or SEI implementation: @WebService(targetNamespace = "http://www.example.org/contract/DoubleIt"... @org.apache.cxf.annotations.FastInfoset public class DoubleItPortTypeImpl implements DoubleItPortType { .... } Alternative configuration options: Can configure via the org.apache.cxf.feature.FastInfosetFeature either on the ServerFactoryBean or the cxf:bus. As the FastInfosetFeature just installs the two FI interceptors, those interceptors can also be added programmatically to the web service endpoint. Note FI will be activated only if the client requests it. The feature's |
CXF SOAP Client |
Add the FastInfoset dependency to your project. Then add the FastInfoset interceptors to the SOAP client class: public class WSClient { public static void main (String[] args) { DoubleItService service = new DoubleItService(); DoubleItPortType port = service.getDoubleItPort(); Client client = ClientProxy.getClient(port); client.getInInterceptors().add(new org.apache.cxf.interceptor.FIStaxInInterceptor()); client.getOutInterceptors().add(new org.apache.cxf.interceptor.FIStaxOutInterceptor()); ... } } Alternative: add the FastInfosetFeature to the ClientFactoryBean. Note FI will be activated only if the service is configured to provide it. FI can be forced from the client to the service without negotiation using the methods described above for the web service provider, however there is no guarantee the service provider will be able to process it. |
Now, let's check the results over the wire:
POST /doubleit/services/doubleit HTTP/1.1 Content-Type: text/xml; charset=UTF-8 Accept: application/fastinfoset, */* SOAPAction: "" User-Agent: Apache-CXF/3.2.2 Cache-Control: no-cache Pragma: no-cache Host: localhost:8080 Connection: keep-alive Content-Length: 224 <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Body> <ns2:DoubleIt xmlns:ns2="http://www.example.org/schema/DoubleIt"> <numberToDouble>10</numberToDouble> </ns2:DoubleIt> </soap:Body> </soap:Envelope> HTTP/1.1 200 Content-Type: application/fastinfoset Transfer-Encoding: chunked Date: Sat, 10 Mar 2018 17:39:16 GMT .....8..soap(http://schemas.xmlsoap.org/soap/envelope/.?...Envelope?...Body8..ns2%http://www.example.org/schema/DoubleIt.?...DoubleItResponse<.doubledNumber.20....POST /doubleit/services/doubleit HTTP/1.1 Content-Type: application/fastinfoset Accept: application/fastinfoset, */* SOAPAction: "" User-Agent: Apache-CXF/3.2.2 Cache-Control: no-cache Pragma: no-cache Host: localhost:8080 Connection: keep-alive Content-Length: 155 .....8..soap(http://schemas.xmlsoap.org/soap/envelope/.?...Envelope?...Body8..ns2%http://www.example.org/schema/DoubleIt.?...DoubleIt< numberToDouble.0....HTTP/1.1 200 Content-Type: application/fastinfoset Transfer-Encoding: chunked Date: Sat, 10 Mar 2018 17:39:16 GMT .....8..soap(http://schemas.xmlsoap.org/soap/envelope/.?...Envelope?...Body8..ns2%http://www.example.org/schema/DoubleIt.?...DoubleItResponse<.doubledNumber.0....
For GZIP, follow the below table for configuration information. The negotiation process involves the SOAP client sending an Accept-Encoding: gzip
HTTP header in the first SOAP request. If the server is configured to support GZIP compression, it will return a compressed SOAP response with the Content-Encoding: gzip
HTTP Header. Subsequently all SOAP requests and responses between the client and web service provider will then use GZIP. If the server is not configured to use GZIP then SOAP requests and responses will be sent as normal, uncompressed.
Component | How to implement GZIP Compression |
---|---|
CXF Web Service Provider | Attach the @org.apache.cxf.annotations.GZIP annotation to DoubleItPortTypeImpl, or either the GZIPFeature or its two corresponding interceptors as described in the previous table for the FI configuration. Note the annotation, feature and GZIPOutInterceptor all provide an optional |
CXF SOAP Client | Attach the GZIPFeature or the GZIP interceptors (along with the threshold value, if desired) as described in the previous table for FI. |
The results with GZIP are shown below. I set the threshold to zero, both client- and service-side, to ensure compression of all messages. (Note following Wireshark's HTTP stream will uncompress by default, causing one to think no compression is occurring. To see the compressed values as below, right-click any packet part of the SOAP calls and choose "Follow->TCPStream" instead.)
POST /doubleit/services/doubleit HTTP/1.1 Content-Type: text/xml; charset=UTF-8 Accept: */* Accept-Encoding: gzip;q=1.0, identity; q=0.5, *;q=0 SOAPAction: "" User-Agent: Apache-CXF/3.2.2 Cache-Control: no-cache Pragma: no-cache Host: localhost:8080 Connection: keep-alive Content-Length: 224 <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Body> <ns2:DoubleIt xmlns:ns2="http://www.example.org/schema/DoubleIt"> <numberToDouble>10</numberToDouble> </ns2:DoubleIt> </soap:Body> </soap:Envelope>HTTP/1.1 200 Content-Encoding: gzip Vary: Accept-Encoding Content-Type: text/xml;charset=UTF-8 Content-Length: 158 Date: Sat, 10 Mar 2018 18:03:20 GMT ..........m.... .D....X.#A.F.^<..T6..,..........d&.fW1.(.aFG.w.w.e..M?.Q...GoX.........)A.U...>. ...M...xC..x....M) \.....:.k33m..:......l......s.l../&....... POST /doubleit/services/doubleit HTTP/1.1 Content-Type: text/xml; charset=UTF-8 Accept: */* Accept-Encoding: gzip;q=1.0, identity; q=0.5, *;q=0 Content-Encoding: gzip SOAPAction: "" User-Agent: Apache-CXF/3.2.2 Cache-Control: no-cache Pragma: no-cache Host: localhost:8080 Connection: keep-alive Content-Length: 150 ..........].1..0.E..z..1F!......`.!..:m..q.. .....l.\..8....)....c...4..;....*W.?...k..kf.../k"......5.>A_])E..B...f=|...Ch............u..?..7Y.......HTTP/1.1 200 Content-Encoding: gzip Vary: Accept-Encoding Content-Type: text/xml;charset=UTF-8 Content-Length: 157 Date: Sat, 10 Mar 2018 18:03:20 GMT ..........m.... .D....X.. .../...*.{..t.......x..d..*&..)<.Q...]`Y.}7..%.....E../h.C....tZ5...S..;y..wxNW.H..n...........l3.4..6i/..q.[.kC...b........Q.7....
Posted by Glen Mazza in Web Services at 07:00AM Mar 10, 2018 | Comments[0]
|