对于HTTP的报文头设置,作为一名Android开发者,如果在没有使用第三方框架的前提条件下,直接使用HttpUrlConnection进行GET数据,会因为参数属性的设置导致一些不必要的麻烦。本文主要是我在裸辞后,找工作时,公司给的测试题,在使用HttpURLConnection访问数据时挖出的坑。共有两个大方向的BUG。一是GZIPInputStream,另一个是Unicode。
一、GZIPInputStream问题。
在成功获取数据之后,通过打印,发现出现乱码问题,排除两端的utf-8编码,依旧是乱码,在调试过程中,发现conn.getInputStream()返回的对象是GZIPInputStream。这在之前公司和个人项目中从未有过,所以去百度。
解决办法:
1:设定请求属性——
conn.setRequestProperty("Accept-Encoding", "gzip, deflate");
2:在返回时做解压操作——
String content_encode = conn.getContentEncoding();
if (null != content_encode && !"".equals(content_encode) && content_encode.contains("gzip")) {
GZIPInputStream in = new GZIPInputStream(is);
if (in == null) {
return "";
}
第一个步骤必须有,否则conn.getContentEncoding()的值只会是NULL.
二、Unicode问题。
在浏览器中访问,返回JSON字符串中中文不是中文,当时以为还是乱码问题,通过和公司接口提供人员沟通,确定是Unicode编码问题,也就是说需要做解码,该解码的函数是本人在网络上找的,验证正确:
public static String decodeUnicode(String theString) {
char aChar;
int len = theString.length();
StringBuffer outBuffer = new StringBuffer(len);
for (int x = 0; x < len;) {
aChar = theString.charAt(x++);
if (aChar == '\\') {
aChar = theString.charAt(x++);
if (aChar == 'u') {
// Read the xxxx
int value = 0;
for (int i = 0; i < 4; i++) {
aChar = theString.charAt(x++);
switch (aChar) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
value = (value << 4) + aChar - '0';
break;
case 'a':
case 'b':
case 'c':
case 'd':
case 'e':
case 'f':
value = (value << 4) + 10 + aChar - 'a';
break;
case 'A':
case 'B':
case 'C':
case 'D':
case 'E':
case 'F':
value = (value << 4) + 10 + aChar - 'A';
break;
default:
throw new IllegalArgumentException(
"Malformed \\uxxxx encoding.");
}
}
outBuffer.append((char) value);
} else {
if (aChar == 't')
aChar = '\t';
else if (aChar == 'r')
aChar = '\r';
else if (aChar == 'n')
aChar = '\n';
else if (aChar == 'f')
aChar = '\f';
outBuffer.append(aChar);
}
} else
outBuffer.append(aChar);
}
return outBuffer.toString();
}
成功解决问题后,最终本人使用OkHttp框架来进行另一个接口的测试,当时公司一共给了两个接口来作为应聘的测试题目。在使用过程中,发现在使用该框架的情况下,不需要考虑GZIPInputStream的问题,但是依旧需要做Unicode的解码工作。
String mUrl = sb.toString();
OkHttpClient mOkHttpClient = new OkHttpClient();
Request request = new Request.Builder().url(mUrl).build();
mOkHttpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
String responseData = response.body().string();
String data = HttpRequestInternet.decodeUnicode(responseData);
if (data.length() < 1){
return;
}
if (!data.endsWith("}")){
int length = data.length();
int len = data.lastIndexOf(",");
String dataDeal = data.substring(0, len) + "}";
setResponseData(dataDeal);
newsInterface.updateUI(responseData);
} else{
setResponseData(data);
newsInterface.updateUI(responseData);
}
}
});