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