Java和PHP配合:deflate(压缩)和inflate(解压)
一、Java中deflate压缩发送给php解压缩
Android中deflate代码
OutputStream urlOutStream = urlConnection.getOutputStream(); // 要使用no_wrap的Deflater,php才能解压,9是最高的压缩级别,可以设置为1-9的级别,1速度最快 DeflaterOutputStream deflaterOut = new DeflaterOutputStream(urlOutStream, new Deflater(9, true)); deflaterOut.write((stringToPost[0]).getBytes()); deflaterOut.close(); urlOutStream.close();
PHP中inflate及deflate代码 (有时候终端方法压缩时会自动base64加密一次,php需要先解base64)https://tool.oschina.net/encrypt?type=3
<?php // 首先获取post的字符串: // 因为是直接写入的压缩字符串, // 通过$_POST[]并不能获取post内容, // 可以通过原始请求数据的只读输入流获得post内容 $postStr = file_get_contents('php://input'); // Java中默认的Deflater的数据格式有wrap,Java中应设置no_wrap的Deflater // 如果Java中没有指定no_wrap的Deflater,则PHP中通过下面的算法将wrap去掉,也可以正常解压 // $deflateForPHP = substr($postStr, 2, -4); // 解压缩获得请求的内容 $plainRequest = gzinflate($postStr); // code here ... // 将处理结果压缩后返回请求端 $result = "准备发给android的处理结果"; echo gzdeflate($result); ?>
Android中inflate代码
if (urlConnection.getResponseCode() == HttpURLConnection.HTTP_OK) { InputStream urlInputStream = urlConnection.getInputStream(); // php中gzdeflate()压缩的结果,没有wrap,需要自行计算头尾验证字符, // 或者指定new Inflater(true)的解压器才能正确解压(注意:没了传输错误校验) InflaterInputStream inflaterIn = new InflaterInputStream(urlInputStream, new Inflater(true)); BufferedReader reader = new BufferedReader(new InputStreamReader(inflaterIn)); String res = "", line; while ((line = reader.readLine()) != null) { res += line; } Log.i(TAG, "Response length: " + res.length() + " response: " + res); reader.close(); inflaterIn.close(); urlInputStream.close(); urlConnection.disconnect(); return res; }
二、完整代码:
private class mHttp extends AsyncTask<String, Void, String> { private URL mUrl; private String mMethod = "GET"; private int mHttpTimeout = 3000; /* milliseconds */ private String TAG = "mHttp"; public mHttp(String url, String method) throws MalformedURLException { mUrl = new URL(url); if(method.toUpperCase().contains("POST")) mMethod = "POST"; } public mHttp(String url) throws MalformedURLException { mUrl = new URL(url); } @Override protected String doInBackground(String... stringToPost) { if (mUrl != null) { try { HttpURLConnection urlConnection = (HttpURLConnection) mUrl.openConnection(); urlConnection.setReadTimeout(mHttpTimeout); urlConnection.setConnectTimeout(mHttpTimeout); urlConnection.setRequestMethod(mMethod); urlConnection.setDoInput(true); // PHP已经应用pzdeflate()处理了结果,添加Accept-Encoding的header避免Apache再deflate处理 urlConnection.addRequestProperty("Accept-Encoding", "q=1.0 identity"); if (mMethod.equals("POST")) { urlConnection.setDoOutput(true); urlConnection.addRequestProperty("Content-Encoding", "deflate"); OutputStream urlOutStream = urlConnection.getOutputStream(); DeflaterOutputStream deflaterOut = new DeflaterOutputStream(urlOutStream, new Deflater(9, true)); deflaterOut.write((stringToPost[0]).getBytes()); deflaterOut.close(); urlOutStream.close(); } urlConnection.connect(); if (urlConnection.getResponseCode() == HttpURLConnection.HTTP_OK) { InputStream urlInputStream = urlConnection.getInputStream(); InflaterInputStream inflaterIn = new InflaterInputStream(urlInputStream, new Inflater(true)); BufferedReader reader = new BufferedReader(new InputStreamReader(inflaterIn)); String res = "", line; while ((line = reader.readLine()) != null) { res += line; } Log.i(TAG, "Response length: " + res.length() + " response: " + res); reader.close(); inflaterIn.close(); urlInputStream.close(); urlConnection.disconnect(); return res; } else { // show response code. Log.i(TAG, "doInBackground: responseCode: " + urlConnection.getResponseCode()); urlConnection.disconnect(); return null; } } catch (Exception e) { e.printStackTrace(); } } return null; } @Override protected void onPostExecute(String result) { Log.i(TAG, "onPostExecute: " + result); // 处理result字符串,例如显示在UI组件上 // code here... } } mHttp http = new mHttp("http://examle.com/page.php", "post"); http.execute("String to be posted to the server");
用到的链接:
php://input 原始请求数据的只读输入流
DeflaterOutputStream
Deflater
InflaterInputStream
Inflater
gzinflate-in-java