【问题标题】:How can I write a post statement to an HttpUrlConnection that's zipped?如何将 post 语句写入压缩的 HttpUrlConnection?
【发布时间】:2014-03-26 14:42:57
【问题描述】:

我一直被告知您应该压缩数据以提高效率。关于输入大小,这个比较容易,如下图:

HttpURLConnection urlConnection=(HttpURLConnection) new URL(url).openConnection();
urlConnection.setRequestProperty("Accept-Encoding", "gzip");
InputStream instream=urlConnection.getInputStream();
Map<String, List<String>> headers = urlConnection.getHeaderFields();
List<String> contentEncodings=headers.get("Content-Encoding");
boolean hasGzipHeader=false;
if (contentEncodings!=null) {
    for (String header:contentEncodings) {
        if (header.equalsIgnoreCase("gzip")) {
            hasGzipHeader=true;
            break;
        }
    }
}
if (hasGzipHeader) {
    instream = new GZIPInputStream(instream);
}

输出端似乎有点棘手。我发现了如何只发送一般的 Post 语句输出,如下所示:

HttpsURLConnection conn = (HttpsURLConnection) url
        .openConnection();
conn.setReadTimeout(10000);
conn.setConnectTimeout(15000);
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setRequestProperty("Accept-Encoding", "gzip");
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type",
        "application/x-www-form-urlencoded");

OutputStream os = conn.getOutputStream();
os.write(getQuery(results).getBytes(Charset.forName("UTF8")));

private String getQuery(List<BasicNameValuePair> params)
        throws UnsupportedEncodingException {
    StringBuilder result = new StringBuilder();
    boolean first = true;
    for (BasicNameValuePair pair : params) {
        if (first)
            first = false;
        else
            result.append("&");

        result.append(URLEncoder.encode(pair.getName(), "UTF-8"));
        result.append("=");
        result.append(URLEncoder.encode(pair.getValue(), "UTF-8"));
    }
    return result.toString();
}

但我不知道如何将输出流压缩,如果可能的话。我不知道如何判断服务器是否会接受连接,以及如何告诉服务器数据已压缩。发送编码后的数据很容易,如下:

ByteArrayOutputStream baos = new ByteArrayOutputStream();
GZIPOutputStream gzipStream = new GZIPOutputStream(baos);
gzipStream.write(getQuery(results).getBytes(
        Charset.forName("UTF8")));
os.write(baos.toByteArray());

【问题讨论】:

    标签: java android post gzip httpurlconnection


    【解决方案1】:

    是的,对于输入(下载)HttpURLConnection 的 Android 实现会透明地执行 gunzip。但是对于输出(上传),这不会自动完成。客户端无法知道服务器是否支持压缩。因此,您必须手动执行此操作,并且必须确保您的服务器理解请求。

    你可以在DavidWebb找到一个例子。

    压缩负载的代码:

    static byte[] gzip(byte[] input) {
        GZIPOutputStream gzipOS = null;
        try {
            ByteArrayOutputStream byteArrayOS = new ByteArrayOutputStream();
            gzipOS = new GZIPOutputStream(byteArrayOS);
            gzipOS.write(input);
            gzipOS.flush();
            gzipOS.close();
            gzipOS = null;
            return byteArrayOS.toByteArray();
        } catch (Exception e) {
            throw new WebbException(e); // <-- just a RuntimeException
        } finally {
            if (gzipOS != null) {
                try { gzipOS.close(); } catch (Exception ignored) {}
            }
        }
    }
    

    你必须设置以下标题:

    connection.setRequestProperty("Content-Encoding", "gzip");
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-06
      • 2013-09-24
      • 1970-01-01
      • 2012-02-17
      • 2016-04-26
      相关资源
      最近更新 更多