最近在跟Asp.net端调接口,产品接口里面有个上传产品头像的功能。Asp.net端需要把上传的图片流重新用Apache Base64编码,服务端使用base64解码成byte输入流上传到Windows azure云端就可以了。在今天之前小檀的接口都是正确的,今天重新再走了一下流程发现图片上传到云端后打不开。小檀走了一下本地httpclient请求模拟了一下,无果。
作为一个程序员,bug太多他不会哭,当他调了一上午的代码发现罪魁祸首是一个空格,他就想泪奔了。废话不多说,现在开始说正文。
在公司崔哥的帮助下,发现原来是这行代码出了问题。代码如下:
public static JSONObject buffer(HttpServletRequest request) {
JSONObject checkInfo = null;
try {
BufferedReader br = new BufferedReader(new InputStreamReader(request.getInputStream(),"utf-8"));
String line = null;
StringBuilder sb = new StringBuilder();
while ((line = br.readLine()) != null) {
sb.append(line);
}
// 将资料解码
String reqBody = sb.toString();
//reqBody = URLDecoder.decode(reqBody, "utf-8");
checkInfo = JSONObject.parseObject(reqBody);
} catch (Exception e) {
e.printStackTrace();
}
return checkInfo;
}
对的,就是这行被注释掉的代码。随便百度一下就知道,通过urlencode转码后的字符串,需要通过UrlDecode进行解码。这个必须一致,所以秒懂了!所以如果想保留这行代码,那么客户端http request body必须要使用UrlEncoder转码。反之都不要!下面分享一下我的httpclient4.x post的封装代码:
// 发送post请求,返回结果response
//I.使用StringEntity组织参数流,虽然不推荐了,但是很好用
public static HttpResponse getResponseByPostWithStringEntity(String postUrl, Map<String, Object> paramsMap) {
HttpResponse httpResponse = null;
StringEntity entity = null;
try {
if (paramsMap != null && StringUtils.isNotBlank(postUrl)) {
entity = new StringEntity(JSON.toJSONString(paramsMap),MIME_TYPE, CONTENT_CHARSET);
HttpPost httpPost = new HttpPost(postUrl);
// 为HttpPost设置实体数据
httpPost.setEntity(entity);
httpResponse = httpclient.execute(httpPost);
}
} catch (Exception e) {
e.printStackTrace();
}
return httpResponse;
}
//发送post请求,返回结果response
//II. urlEncode httpclient目前版本极力推荐(备注:客户端重新编码后,服务器端必须解码)
public static HttpResponse getResponseByPostWithUrlEncoded(String postUrl, Map<String, Object> paramsMap) {
HttpResponse httpResponse = null;
UrlEncodedFormEntity entity = null;// 参数流
List<NameValuePair> nameValuePairArrayList = new ArrayList<NameValuePair>();
try {
if (paramsMap != null && !paramsMap.isEmpty() && StringUtils.isNotBlank(postUrl)) {
// 将传过来的参数填充到List<NameValuePair>中
for (Map.Entry<String, Object> entry : paramsMap.entrySet()) {
nameValuePairArrayList.add(new BasicNameValuePair(entry.getKey(), entry.getValue() != null ? entry.getValue()
.toString() : ""));
}
entity = new UrlEncodedFormEntity(nameValuePairArrayList, CONTENT_CHARSET);
HttpPost httpPost = new HttpPost(postUrl);
// 为HttpPost设置实体数据
httpPost.setEntity(entity);
httpResponse = httpclient.execute(httpPost);
}
} catch (Exception e) {
e.printStackTrace();
}
return httpResponse;
}
从这个错误深刻发现,沟通应该到细节,要清楚自己的程序里面每行代码的作用和意义!