zoukankan      html  css  js  c++  java
  • 从一个bug的解决过程到httpClient的用法

      本篇记录一个bug出现与解决的过程,希望以后在了解了更多的技术细节的基础上,可以对现阶段的一些代码块进行进一步改进。

      在接触到的第一个项目中,使用了一个同事写的HttpUtil,其中的get请求:

    public static String getMethod(String url) {
            CloseableHttpClient httpclient = HttpClients.createDefault();
            HttpGet get = new HttpGet(url);
            get.addHeader("Content-Type", "application/json; charset=utf-8");
            CloseableHttpResponse response = null;
            try {
                response = httpclient.execute(get);
                String rev = EntityUtils.toString(response.getEntity());
                return rev;
            } catch (Exception e) {
                log.info(e.getMessage());return null;
            } finally {
                get.releaseConnection();
                close(httpclient, response);
            }
        }

      但是当响应中出现中文时,该方法的返回值会有乱码,于是有了第二版,他将返回的内容用输入流接收,并规定编码格式(其实我在想用toString(HttpEntity,Charset)会不会有效果,没试过):

    /**
         * httpGET请求,中文不乱码
         * 
         * @param url
         * @return
         */
        public static String httpByGet(String url) {
            StringBuffer response = new StringBuffer();
            HttpClient client = new HttpClient();
            HttpMethod method = new GetMethod(url);
            BufferedReader reader = null;
            InputStreamReader in = null;
            InputStream input = null;
            try {
                client.executeMethod(method);
                if (method.getStatusCode() == HttpStatus.SC_OK) {
                    input = method.getResponseBodyAsStream();
                    in = new InputStreamReader(input, "UTF-8");
                    if (in != null) {
                        reader = new BufferedReader(in);
                        String line;
                        while ((line = reader.readLine()) != null) {
                            response.append(line);
                        }
                    }
                }
            } catch (Exception e) {
                log.info(e.getMessage());
            } finally {
                try {
                    if (input != null) {
                        input.close();
                    }
                    if (in != null) {
                        in.close();
                    }
                    if (reader != null) {
                        reader.close();
                    }
                } catch (IOException ex) {
                    log.info(e.getMessage());
                }
            }
            return response.toString();
        }

      这个方法解决了中文乱码的问题,之后一直在项目中使用该方法,但不久又出现了另一个问题。当时需要传入多个参数才能调用另一个接口,一般来说,参数太多的情况还是会倾向用post方法,一来url的长度有限制,二来在请求体中处理一些特殊符号也更容易,但是那个接口只有get方法才能请求,所以在调用这个方法时,还是得拼接url。很快url拼接成功,但是由于value中大量特殊符号不得不采用URLEncoder对其进行转义,转义之后请求发送成功。这个时候,使用接口的同事发现,虽然采用该方法可以成功取到返回的内容,但与在浏览器中返回的内容不一致。

      但是既然浏览器可以成功返回指定的内容,那就可以按照浏览器访问的模式去发送请求,于是利用postman成功发送一条请求,并且用了它的generate code工具(postman也是个神器,我觉得要系统学习一下这个工具,应该可以为开发省事不少),找到了它用java实现的代码(OKHttpClient),但还是采用了拼接URL的方式,将请求发送出去,得到返回结果。

    public static String httpByOKGet(String url) {
            OkHttpClient client = new OkHttpClient();
            client.setReadTimeout(60, TimeUnit.SECONDS);
            client.setWriteTimeout(60, TimeUnit.SECONDS);
            client.setConnectTimeout(60, TimeUnit.SECONDS);
            Request request = new Request.Builder().url(url).get().addHeader("content-type", "application/json")
                    .addHeader("cache-control", "no-cache")
                    .addHeader("postman-token", "c155bbab-f11c-7fa3-b155-e69906f67d75").build();
            StringBuilder sb = new StringBuilder();
            InputStream input = null;
            InputStreamReader in = null;
            BufferedReader reader = null;
            try {
                Response response = client.newCall(request).execute();
                input = response.body().byteStream();
                in = new InputStreamReader(input, "UTF-8");
                if (in != null) {
                    reader = new BufferedReader(in);
                    String line;
                    while ((line = reader.readLine()) != null) {
                        sb.append(line);
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    if (input != null) {
                        input.close();
                    }
                    if (in != null) {
                        in.close();
                    }
                    if (reader != null) {
                        reader.close();
                    }
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
            return sb.toString();
        }

      应急还可以,只是每次这个url就这么拼接总觉得不妥,而且当时居然就直接把postman的token带在里面写到了util包的类里...后期用了BasicNameValuePair来处理这些参数,觉得规范了一些,但是httpClient这一块儿还是不系统,后期就专门在这一小块儿上看看文档,总结最新版的常见用法,归纳到博客中。

  • 相关阅读:
    字符编码
    IO流技术
    TreeMap使用和Comparable比较
    Collections工具类
    使用迭代器进行遍历时
    238. 除自身以外数组的乘积
    python 字典按键、值排序
    collections.Counter用法
    442. 数组中重复的数据
    1395. 统计作战单位数
  • 原文地址:https://www.cnblogs.com/bruceChan0018/p/6031899.html
Copyright © 2011-2022 走看看