如何将使用 GZIP 压缩的字符串从 Java App 发送到 PHP Web 服务
Posted
技术标签:
【中文标题】如何将使用 GZIP 压缩的字符串从 Java App 发送到 PHP Web 服务【英文标题】:How to send string compressed with GZIP from Java App to PHP web service 【发布时间】:2015-03-27 08:03:24 【问题描述】:我遇到了 GZIP 压缩问题:
我需要通过 POST 方法发送一个巨大的 JSON 字符串,它太大而无法像 URL 一样接受(例如:http://localhost/app/send/JSON STRING ENCODED BY BASE64),这会导致 HTTP 错误403
所以,我需要压缩我的 json,我找到了一种使用 GZIP 压缩的方法,我可以在 php 中使用 gzdecode() 进行解压缩。
但它不起作用......
我的函数 compress() 和 decompress() 在我的 Java 应用程序中工作正常,但是当我将它发送到 web 服务时,出现问题并且 gzdecode() 不起作用。 我不知道我错过了什么,我需要一些帮助
java 应用(客户端)中使用的函数
public String Post()
String retorno = "";
String u = compress(getInput());
u = URLEncoder.encode(URLEncoder.encode(u, "UTF-8"));
URL uri = new URL(url + u);
HttpURLConnection conn = (HttpURLConnection) uri.openConnection();
conn.setDoOutput(false);
conn.setRequestMethod(getMethod());
conn.setRequestProperty("Content-encoding", "gzip");
conn.setRequestProperty("Content-type", "application/octet-stream");
BufferedReader buffer = new BufferedReader(
new InputStreamReader((conn.getInputStream())));
String r = "";
while ((r = buffer.readLine()) != null)
retorno = r + "\n";
return retorno;
GZIP 压缩功能(客户端)
public static String compress(String str) throws IOException
byte[] blockcopy = ByteBuffer
.allocate(4)
.order(java.nio.ByteOrder.LITTLE_ENDIAN)
.putInt(str.length())
.array();
ByteArrayOutputStream os = new ByteArrayOutputStream(str.length());
GZIPOutputStream gos = new GZIPOutputStream(os);
gos.write(str.getBytes());
gos.close();
os.close();
byte[] compressed = new byte[4 + os.toByteArray().length];
System.arraycopy(blockcopy, 0, compressed, 0, 4);
System.arraycopy(os.toByteArray(), 0, compressed, 4,
os.toByteArray().length);
return Base64.encode(compressed);
用于接收 URL 的 php 方法(服务器,使用 Slim/PHP 框架)
init::$app->post('/enviar/:obj/', function( $obj )
$dec = base64_decode(urldecode( $obj ));//decode url and decode base64 tostring
$dec = gzdecode($dec);//here is my problem, gzdecode() doesn't work
发帖方式
public Sender() throws JSONException
//
url = "http://192.168.0.25/api/index.php/enviar/";
method = "POST";
output = true;
//
【问题讨论】:
不要使用str.getBytes()
;您没有指定编码。事实上,您也没有在发送的数据中指定它。 InputStreamReader
也一样。
如何为 InputStreamReader 指定编码?
通常情况下,the javadoc has the answer
好的,我应该使用常规的 UTF-8 编码或其他特定于 GZIP 压缩的编码?
选择编码与压缩无关;你当然会在压缩之前进行编码,但是你使用 UTF-8 + gzip(推荐)或者,谁知道,EBCDIC + compress,原理是一样的:字符 -> 字节流 -> 压缩字节流(然后在你的情况下用 BASE64 编码)
【参考方案1】:
正如在一些 cmets 中所注意到的那样。
更大的数据应该作为 POST 请求而不是 GET 发送。 URL 参数应仅用于单个变量。正如您所注意到的,URL 长度被限制为几 kB,并且以这种方式发送更大的数据并不是一个好主意(即使 GZIP 压缩)。
您的 GZIP 压缩代码似乎有误。请试试这个:
public static String compress(String str) throws IOException
ByteArrayOutputStream os = new ByteArrayOutputStream(str.length());
GZIPOutputStream gos = new GZIPOutputStream(os);
gos.write(str.getBytes());
os.close();
gos.close();
return Base64.encodeToString(os.toByteArray(),Base64.DEFAULT);
【讨论】:
纬线应该是:return Base64.encodeToString(os.toByteArray(),Base64.DEFAULT);以上是关于如何将使用 GZIP 压缩的字符串从 Java App 发送到 PHP Web 服务的主要内容,如果未能解决你的问题,请参考以下文章