我正在尝试收到针对常规api调用的回复,例如https://api.stackexchange.com/2.1/me/associated?key=myKey&access_token=myAccessToken
作为回应我得到类似 _ l | [U9 J bqPmp轹something NmxM = A ...
我认为到目前为止一切正常,因为响应应该是GZIPped。但是当尝试解压缩String时,我收到一个错误: java.io.IOException:未知格式(幻数ef1f)(由GZIPInputStream抛出)。
目前我正在使用以下课程:
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.zip.GZIPInputStream;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import android.os.AsyncTask;
import android.util.JsonReader;
import android.util.Log;
public class RetrieveAccounts extends AsyncTask<Void, String, String> {
protected String myFeed = "";
String retrieveAddress = "https://api.stackexchange.com/2.1/me/associated?key=myKey&access_token=";
public RetrieveAccounts(String accessToken) {
retrieveAddress += accessToken;
Log.i("URL", "Retrieve Address: " + retrieveAddress);
}
public ArrayList<String> readMessagesArray(JsonReader reader) throws IOException {
ArrayList<String> messages = new ArrayList<String>();
reader.beginArray();
while (reader.hasNext()) {
if(reader.nextName().equals("site_name")) {
messages.add(reader.nextString());
}
}
reader.endArray();
return messages;
}
@Override
protected String doInBackground(Void... params) {
Log.i("URL", "doInBackground");
StringBuilder builder = new StringBuilder();
HttpClient client = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(retrieveAddress);
httpGet.setHeader("Accept-Encoding", "GZIP");
for(int i = 0; i < httpGet.getAllHeaders().length; i++) {
Log.i("URL", "Header " + i + ": " + httpGet.getAllHeaders()[i].getValue());
}
try {
HttpResponse response = client.execute(httpGet);
StatusLine statusLine = response.getStatusLine();
int statusCode = statusLine.getStatusCode();
if(statusCode == 200) {
BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
String line;
while ((line = reader.readLine()) != null) {
builder.append(line);
}
}
else {
Log.e("URL", "Failed to download file");
}
}
catch (ClientProtocolException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
return builder.toString();
}
@Override
protected void onPostExecute(String result) {
String meinErgebnis = "";
try {
meinErgebnis = decompress(result.getBytes());
}
catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Log.i("URL", "Ergebnis: " + meinErgebnis);
}
public static String decompress(byte[] bytes) throws UnsupportedEncodingException, IOException {
// if (str == null || str.length() == 0) {
// return str;
// }
System.out.println("Input String length : " + bytes.length);
GZIPInputStream gis = new GZIPInputStream(new ByteArrayInputStream(bytes));
BufferedReader bf = new BufferedReader(new InputStreamReader(gis, "UTF-8"));
String outStr = "";
String line;
while ((line=bf.readLine())!=null) {
outStr += line;
}
System.out.println("Output String lenght : " + outStr.length());
return outStr;
}
}
IOException的堆栈跟踪:
[dalvik.system.VMStack.getThreadStackTrace(Native Method),
java.lang.Thread.getStackTrace(Thread.java:591),
de.stefansurkamp.stacknotifications.RetrieveAccounts.decompress(RetrieveAccounts.java:111),
de.stefansurkamp.stacknotifications.RetrieveAccounts.onPostExecute(RetrieveAccounts.java:89),
de.stefansurkamp.stacknotifications.RetrieveAccounts.onPostExecute(RetrieveAccounts.java:1),
android.os.AsyncTask.finish(AsyncTask.java:602),
android.os.AsyncTask.access$600(AsyncTask.java:156),
android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:615),
android.os.Handler.dispatchMessage(Handler.java:99),
android.os.Looper.loop(Looper.java:137),
android.app.ActivityThread.main(ActivityThread.java:4493),
java.lang.reflect.Method.invokeNative(Native Method),
java.lang.reflect.Method.invoke(Method.java:511),
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:788),
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:555),
dalvik.system.NativeStart.main(Native Method)]
我认为这些是响应的十六进制值:
1F 8B 08 00 00 00 00 00 04 00 BD 94 4D 6F DC 20 10 86 FF 8A C5 D9 4A 00 63 3E 7C 8B AA 3D F4 D4 4A 51 4F 55 65 11 2F EB 45 B5 C1 05 9C 6C BB DA FF 5E EC DD 36 A9 BB 4E 9C AD 52 DF 3C 33 C0 BC 0F 2F B3 07 3A A8 D6 83 E2 F3 1E DC C9 75 AD CA CA F6 26 C4 C0 1E D4 B6 59 83 02 A6 C0 EB E6 5E 39 50 64 29 B8 73 D6 FC 50 A0 40 D9 61 88 07 55 1A D9 C6 7F 70 1B 64 F5 35 F9 10 EB 36 8D 7D 00 A7 64 EF 9A 98 DB 86 D0 15 D7 D7 7E 28 B1 A7 8A AB CA B6 B1 AA F7 CA 95 3A 1E 23 38 86 98 A6 C0 A9 AE 0F 32 68 6B 40 91 A3 3C 05 B2 1A 3B 3A 16 E5 94 33 96 82 CA A9 B1 A4 5C CB 30 36 83 18 17 8C 67 22 05 8D F4 A1 8C 6B 94 F7 BF B3 9C 53 4A 10 1E 36 33 FE 21 1E 38 EE 18 F5 44 6D DF 7A E5 C7 AD 4E 31 44 0F E9 02 14 F0 09 8A 29 89 BE 53 2E F9 14 85 9D A7 30 A4 07 D9 53 02 98 22 82 C9 9F 04 10 44 0B 09 70 44 A0 C0 88 CE 10 18 F8 40 04 A7 04 CE 00 80 AF D5 8F CF 3A E1 A6 EB FC BC 0B 64 CC FE A5 9F 10 98 5F 2C 9F 0A 46 31 46 B3 06 18 DC 95 2D 90 8F FE 55 FE 70 F1 C9 6A 17 2F 59 2B 53 A9 E4 88 63 B5 AB B6 D2 D4 EA 2C 92 7E 77 35 52 51 A7 A2 29 99 D8 3F 61 13 32 68 39 99 5C C0 9C CE 3D 0D C6 51 CE 33 FE 16 64 E0 84 CC 47 67 6B 27 DB 56 39 BF 84 4A F7 58 FE 3C 1E 04 33 41 E8 C5 CE 81 9C 63 32 CB 27 FA 4A 70 B8 C4 39 AF 7E 38 53 3E 37 66 ED AC 5E 27 2B 13 B6 BD D7 B1 9B 45 9C E4 71 D9 0B 16 12 22 BF F8 71 31 86 45 84 94 CD 22 E2 19 A6 EC 7F 20 7A 6F 36 D6 B5 63 77 C9 AD AA 7A A7 C3 F7 25 8C FC A9 F6 79 48 98 23 CC 2F 86 94 11 96 C3 B9 09 F4 98 7D 7B 48 EF 6C 6D 74 D0 F7 71 F6 54 E3 0C 5A 64 A3 CA D6 BE D2 2F B9 88 4C 4C 24 C4 F2 31 C4 A2 85 F2 B9 31 84 10 A7 64 89 87 D0 E1 CB 10 B4 41 96 4E B5 52 1B 6D EA A1 0F 4E 7E 85 5B B9 1B 2E 2E 7E 29 D8 4A 5F B6 D6 C5 43 36 B2 F1 EA F0 13 51 B5 01 C0 F0 08 00 00
关于如何解决这个问题的任何想法?
答案 0 :(得分:0)
当您对通过响应发送的数据使用GZIP压缩时,您应该首先对压缩数据使用Base64编码器,然后发送它。 在接收方,您应该使用Base64进行解码,然后解压缩。
apt-get --purge remove nginx-*
apt-get install nginx
repository是一个可用于编码/解码Base64的库。
要小心,如果您正在为Android开发,就像在Android 2.2中那样,库已包含在内(我认为是v1.4)。