zoukankan      html  css  js  c++  java
  • java 实现 HTTP请求(GET、POST)的方法

      使用Java进行服务调用时,避免不了要使用模拟HTTP请求来实现模拟,我在开发过程中恰巧遇到了这类的业务需求,所以就对这类的方法进行了一次总结,原理层次的东西暂时不考虑,毕竟HTTP的底层实现啥的,东西挺多且挺复杂的,对我的项目而言,理解这些东西并不能从直观上得到很明显的提升或帮助,还是代码来的比较实在,so,贴出几种方法的总结,用作备份,免的日后再重复造轮子。

    第一种:白痴方案,最原始的解决方案,功能暂时是实现了,但是里面会涉及到通用性和性能等的问题,暂时不考虑,代码如下

    public class HttpRequest {
    
        private static final Logger LOGGER = LoggerFactory.getLogger(HttpRequest.class.getName());
    
        /**
         * 向指定URL发送GET方法的请求
         *
         * @param url   发送请求的URL
         * @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
         * @return URL 所代表远程资源的响应结果
         */
        public static String sendGet(String url, String param) {
            StringBuilder result = new StringBuilder();
            BufferedReader bufferedReader = null;
            try {
                String urlNameString = url + "?" + param;
                URL realUrl = new URL(urlNameString);
                // 打开和URL之间的连接
                URLConnection connection = realUrl.openConnection();
                // 设置通用的请求属性
                connection.setRequestProperty("accept", "*/*");
                connection.setRequestProperty("connection", "Keep-Alive");
                connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
                // 建立实际的连接
                connection.connect();
                // 获取所有响应头字段
                Map<String, List<String>> map = connection.getHeaderFields();
                // 遍历所有的响应头字段
                for (String key : map.keySet()) {
                    LOGGER.info("key : {}", map.get(key));
                    System.out.println(key + "--->" + map.get(key));
                }
                // 定义 BufferedReader输入流来读取URL的响应
                bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
                String line;
                while ((line = bufferedReader.readLine()) != null) {
                    result.append(line);
                }
            } catch (Exception e) {
                LOGGER.error("HTTP GET error : {}", e.getMessage());
            }
            // 使用finally块来关闭输入流
            finally {
                try {
                    if (bufferedReader != null) {
                        bufferedReader.close();
                    }
                } catch (Exception e2) {
                    e2.printStackTrace();
                }
            }
            return result.toString();
        }
    
        /**
         * 向指定 URL 发送POST方法的请求
         *
         * @param url   发送请求的 URL
         * @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。
         * @return 所代表远程资源的响应结果
         */
        public static String sendPost(String url, String param) {
            LOGGER.info("url : {}", url);
            LOGGER.info("param : {}", param);
            PrintWriter out = null;
            BufferedReader in = null;
            StringBuilder result = new StringBuilder();
            try {
                URL realUrl = new URL(url);
                // 打开和URL之间的连接
                URLConnection conn = realUrl.openConnection();
                // 设置通用的请求属性
                conn.setRequestProperty("accept", "*/*");
                conn.setRequestProperty("connection", "Keep-Alive");
                conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
                conn.setRequestProperty("accept-language", "en-US,en;q=0.5");
                // 发送POST请求,必须设置如下两行
                conn.setDoOutput(true);
                conn.setDoInput(true);
                // 获取URLConnection对象对应的输出流
                out = new PrintWriter(conn.getOutputStream());
                // 发送请求参数
                out.print(param);
                // flush输出流的缓冲
                out.flush();
    
                // 定义BufferedReader输入流来读取URL的响应
                in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
                String line;
                while ((line = in.readLine()) != null) {
                    result.append(line);
                }
            } catch (Exception e) {
                LOGGER.error("HTTP POST error : {}", e.getMessage());
            }
            //使用finally块来关闭输出流、输入流
            finally {
                try {
                    if (out != null) out.close();
                    if (in != null) in.close();
                } catch (IOException ex) {
                    LOGGER.error("close IO error : {}", ex.getMessage());
                }
            }
            return result.toString();
        }
    }

    第二种:升级版本,基于上个版本进行的简化版,看起来更简洁一些,代码如下

    public class HttpClientUtil {
    
        private static final Logger LOGGER = LoggerFactory.getLogger(HttpClientUtil.class.getName());
    
        public static String sendGet(String url, String param) throws IOException {
            LOGGER.info("request url info : {}", url);
            HttpGet request = new HttpGet(url + "?" + param);
            return send(request);
        }
    
        public static String sendPost(String url, String param) throws IOException {
            LOGGER.info("request url info : {}", url);
            HttpPost request = new HttpPost(url);
            request.setEntity(
                    new StringEntity(param, ContentType.create("application/json;charset=UTF-8"))
            );
            return send(request);
        }
    
        private static String send(HttpRequestBase request) throws IOException {
            String message = "";
            request.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) ...");
            request.setHeader("accept", "*/*");
            request.setHeader("connection", "Keep-Alive");
            CloseableHttpClient httpclient = HttpClients.createDefault();
            CloseableHttpResponse response = httpclient.execute(request);
            HttpEntity entity = response.getEntity();
            ByteArrayOutputStream outStream = new ByteArrayOutputStream();
            if (entity != null) {
                long length = entity.getContentLength();
                if (length != -1 && length < 2048) {
                    message = EntityUtils.toString(entity);
                } else {
                    InputStream in = entity.getContent();
                    byte[] data = new byte[4096];
                    int count;
                    while ((count = in.read(data, 0, 4096)) != -1) {
                        outStream.write(data, 0, count);
                    }
                    message = new String(outStream.toByteArray(), "UTF-8");
                }
            }
            LOGGER.info(">>>>>>>>>>>>>>>>>response message info : {}", message);
            return message;
        }
    }

    第三种:这一种方案,彻底告别了傻瓜式的轮子创造过程,直接使用开源的,已封装好的代码工具来实现这一过程,但是有个问题就是,他会产生轮询日志,以此保持链接通讯,如果看着不爽,可以改源码里的配置,或者使用log4j2中的日志过滤器,直接将他的日志过滤掉,并只打印程序的日志信息,看起来更清爽一些,代码如下(PS:这个工具包全方位支持RESFUL请求方式,这里只列举常用的两种,其他的请自行实验)

    public class UnirestUtil {
    
        private static final Logger LOGGER = LoggerFactory.getLogger(UnirestUtil.class.getName());
    
        /**
         *
         * @param url 目标url
         * @param name 参数名称
         * @param param 请求参数
         * @return 网络传输状态码或请求结果
         */
        public static HttpResponse sendGet(String url, String name, String param) throws UnirestException {
            LOGGER.debug("request url info : {}", url);
            HttpResponse<String> response = Unirest.get(url)
                    .header("accept", "application/json;charset=UTF-8")
                    .queryString(name, param)
                    .asString();
            LOGGER.debug("response status info : {}", response.getStatus());
            LOGGER.debug("response status message info : {}", response.getStatusText());
            return response;
        }
    
        /**
         *
         * @param url 目标url
         * @param name 参数名称
         * @param param 请求参数实体
         * @return 网络传输状态码
         */
        public static HttpResponse sendPost(String url, String name, String param) throws UnirestException {
            LOGGER.debug("request url info : {}", url);
            HttpResponse<String> response = Unirest.post(url)
                    .header("accept", "application/json;charset=UTF-8")
                    .queryString(name, param)
                    .asString();
            LOGGER.debug("response status info : {}", response.getStatus());
            LOGGER.debug("response status message info : {}", response.getStatusText());
            return response;
        }
    }

     OK,至此,几种方案都贴出来了,可能还有更简洁可靠的方案来实现这个功能,但是我还没找到,如果您有更好的方法,请留言交流,分享出来吧,谢谢。

  • 相关阅读:
    【转】几种Java序列化方式的实现
    【转】Java泛型方法
    【转】java序列化一定要应该注意的6个事项!
    [转]Android APK签名原理及方法
    [转]Android中内存占用的含义:(VSS,PSS,RSS,USS)
    红黑树的C语言实现
    Btree算法的C语言实现
    C++之迭代器失效总结
    tcpdump抓包工具用法说明
    setsockopt函数功能及参数详解
  • 原文地址:https://www.cnblogs.com/SummerinShire/p/7194099.html
Copyright © 2011-2022 走看看