如何将post语句写入压缩的HttpUrlConnection?

Pea*_*oto 7 java post android gzip httpurlconnection

我总是被告知你应该压缩数据以提高效率.在输入大小上,这相对容易,如下所示:

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);
}
Run Code Online (Sandbox Code Playgroud)

输出端看起来有点棘手.我已经找到了如何发送一般的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();
}
Run Code Online (Sandbox Code Playgroud)

但我无法弄清楚如何获得输出流gziped,如果它甚至可能.我无法弄清楚如何判断服务器是否接受连接,以及如何告诉服务器数据已压缩.发送编码的数据很容易,如下所示:

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

hgo*_*ebl 10

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

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

gzip有效负载的代码:

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) {}
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

你必须设置以下标题:

connection.setRequestProperty("Content-Encoding", "gzip");
Run Code Online (Sandbox Code Playgroud)