最近在跟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; }
从这个错误深刻发现,沟通应该到细节,要清楚自己的程序里面每行代码的作用和意义!