前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ksoap2:实现gzip压缩发送request data

ksoap2:实现gzip压缩发送request data

作者头像
10km
发布2019-05-25 22:32:34
3830
发布2019-05-25 22:32:34
举报
文章被收录于专栏:10km的专栏10km的专栏

版权声明:本文为博主原创文章,转载请注明源地址。 https://cloud.tencent.com/developer/article/1433722

ksoap能不能支持gzip数据压缩传输?

我们知道webservice调用生成的xml数据挺大的,如果能压缩传输可以显著减少网络延迟,提高系统的整体性能。那么ksoap2支持gzip压缩传输么?这就是我这两天要搞清楚的问题。

接收response数据

ksoap2用于数据发送接收的类是由继承抽象类org.ksoap2.transport.Transport实现的HttTransportSE实现的

通过研究HttpTransportSE的call方法List org.ksoap2.transport.HttpTransportSE.call(String soapAction, SoapEnvelope envelope, List headers, File outputFile)

可以发现HttpTransportSE可以接收gzip压缩的数据。如果收到的是gzip,会自动将数据解压缩,以下为call方法的代码片段(中文注释为本文作者添加):

代码语言:javascript
复制
            retHeaders = connection.getResponseProperties();

            for (int i = 0; i < retHeaders.size(); i++) {
                HeaderProperty hp = (HeaderProperty)retHeaders.get(i);
                // HTTP response code has null key
                if (null == hp.getKey()) {
                    continue;
                }

                // If we know the size of the response, we should use the size to initiate vars
                if (hp.getKey().equalsIgnoreCase("content-length") ) {
                    if ( hp.getValue() != null ) {
                        try {
                            contentLength = Integer.parseInt( hp.getValue() );
                        } catch ( NumberFormatException nfe ) {
                            contentLength = 8192;
                        }
                    }
                }


                // Check the content-type header to see if we're getting back XML, in case of a
                // SOAP fault on 500 codes
                if (hp.getKey().equalsIgnoreCase("Content-Type")
                        && hp.getValue().contains("xml")) {
                    xmlContent = true;
                }


                // ignoring case since users found that all smaller case is used on some server
                // and even if it is wrong according to spec, we rather have it work..
                //判断是否为gzip压缩数据
                if (hp.getKey().equalsIgnoreCase("Content-Encoding")                    
                     && hp.getValue().equalsIgnoreCase("gzip")) {
                    gZippedContent = true;
                }
            }

            //first check the response code....
            if (status != 200) {
                //throw new IOException("HTTP request failed, HTTP status: " + status);
                throw new HttpResponseException("HTTP request failed, HTTP status: " + status, status);
            }

            if (contentLength > 0) {
                if (gZippedContent) {
                    //对gzip压缩数据解压缩
                    is = getUnZippedInputStream(
                            new BufferedInputStream(connection.openInputStream(),contentLength));
                } else {
                    is = new BufferedInputStream(connection.openInputStream(),contentLength);
                }
            }

发送request数据

那么发送数据呢?ksoap能不能对发送的请求数据进行gzip压缩?

下面是HttpTransportSE中发送请求数据的方法sendData(void org.ksoap2.transport.HttpTransportSE.sendData(byte[] requestData, ServiceConnection connection, SoapEnvelope envelope) )的代码,很简单可以看出,发送数据并没有gzip压缩:

代码语言:javascript
复制
    protected void sendData(byte[] requestData, ServiceConnection connection, SoapEnvelope envelope)
            throws IOException
    {
        connection.setRequestProperty("Content-Length", "" + requestData.length);
        connection.setFixedLengthStreamingMode(requestData.length);

        OutputStream os = connection.openOutputStream();
        os.write(requestData, 0, requestData.length);
        os.flush();
        os.close();
    }

现在我们可以得出结论,ksoap2的代码并没有支持gzip发送请求,我下载了它的最新版本3.6.1.也依然没有支持。

如何实现gzip压缩发送request data?

ksoap2本身就是个轻量级的soap框架,并没有做到非常完善,但因为它的框架结构比较好,使用者完全可以根据自己的需要在ksoap2的代码基础上进行功能扩展。

所以要实现gzip压缩发送request,需要自己动手实现。其实实现也不复杂:

好在sendData方法是protected,所以在不修改ksoap2代码的基础上我们只要从HttpTransportSE继承新建一个类,然后重写sendData方法,以后就用自己写的这个类来负责数据的发送和接收就可以实现完全的gzip压缩数据传输.

下面是我的实现完整代码:

HttpTransportSEWithGzip.java

代码语言:javascript
复制
package net.gdface.service.client.ksoapstub;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.Proxy;
import java.util.zip.GZIPOutputStream;

import org.ksoap2.SoapEnvelope;
import org.ksoap2.transport.HttpTransportSE;
import org.ksoap2.transport.ServiceConnection;

/**
 * 实现Gzip发送请求<br>
 * {@link #compress}为true时发送数据前先压缩数据
 * @author guyadong
 *
 */
public class HttpTransportSEWithGzip extends HttpTransportSE {
    /**
     * 是否启用GZIP压缩
     */
    public boolean compress=true;
    public HttpTransportSEWithGzip(String url) {
        super(url);
    }

    public HttpTransportSEWithGzip(Proxy proxy, String url) {
        super(proxy, url);
    }

    public HttpTransportSEWithGzip(String url, int timeout) {
        super(url, timeout);
    }

    public HttpTransportSEWithGzip(Proxy proxy, String url, int timeout) {
        super(proxy, url, timeout);
    }

    public HttpTransportSEWithGzip(String url, int timeout, int contentLength) {
        super(url, timeout, contentLength);
    }

    public HttpTransportSEWithGzip(Proxy proxy, String url, int timeout, int contentLength) {
        super(proxy, url, timeout, contentLength);
    }

    @Override
    protected void sendData(byte[] requestData, ServiceConnection connection, SoapEnvelope envelope) throws IOException {
        if (this.compress) {
            // 先将数据压缩再调用父类的sendData方法完成实际数据发送
            ByteArrayOutputStream arrayOutputStream = new ByteArrayOutputStream(1024);
            GZIPOutputStream os = null;
            try {
                os = new GZIPOutputStream(arrayOutputStream);
                os.write(requestData, 0, requestData.length);
                os.finish();
            } finally {
                if (null != os)
                    os.close();
            }
            // 指定数据编码方式为gzip压缩
            connection.setRequestProperty("Content-Encoding", "gzip");
            requestData = arrayOutputStream.toByteArray();
        }
        // 调用父类的方法完成请求数据发送
        super.sendData(requestData, connection, envelope);
    }
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2016年09月09日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • ksoap能不能支持gzip数据压缩传输?
  • 接收response数据
  • 发送request数据
  • 如何实现gzip压缩发送request data?
相关产品与服务
文件存储
文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档