由URLDecoder.decode(reqBody, "utf-8");引发的bug

     最近在跟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目前版本极力推荐(备注:客户端重新编码后,服务器端必须解码)

扫描二维码关注公众号,回复: 583554 查看本文章

 

 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;

    }

   从这个错误深刻发现,沟通应该到细节,要清楚自己的程序里面每行代码的作用和意义!

   

   

猜你喜欢

转载自javaxiaoyetan.iteye.com/blog/2153429
今日推荐