【三种】Java构建HTTP请求的方法

  • 在Java开发中,肯定会遇到构建HTTP请求的场景,常遇到的就是 GETPOST
  • 以下总结三种常用的方法并实践之:①HttpURLConnection ②HttpClient ③Hutool
  • demo对应github地址:https://github.com/tyronczt/java-learn/blob/master/Tools/http-request

方法一、HttpURLConnection

HttpURLConnection 是 Java 的标准类,是 Java 比较原生的一种实现方式。

/**
* 发送get请求
*
* @param httpurl url地址
* @return
*/
public static String doGet(String httpurl) {
   HttpURLConnection connection = null;
   InputStream is = null;
   BufferedReader br = null;
   String result = null;// 返回结果字符串
   try {
       // 创建远程url连接对象
       URL url = new URL(httpurl);
       // 通过远程url连接对象打开一个连接,强转成httpURLConnection类
       connection = (HttpURLConnection) url.openConnection();
       // 设置连接方式:get
       connection.setRequestMethod("GET");
       // 设置连接主机服务器的超时时间:15000毫秒
       connection.setConnectTimeout(15000);
       // 设置读取远程返回的数据时间:60000毫秒
       connection.setReadTimeout(60000);
       // 发送请求
       connection.connect();
       // 通过connection连接,获取输入流
       int responseCode = connection.getResponseCode();
       if (responseCode == 200) {
           is = connection.getInputStream();
           // 封装输入流is,并指定字符集
           br = new BufferedReader(new InputStreamReader(is, "UTF-8"));
           // 存放数据
           StringBuffer sbf = new StringBuffer();
           String temp = null;
           while ((temp = br.readLine()) != null) {
               sbf.append(temp);
               sbf.append("\r\n");
           }
           result = sbf.toString();
       }
   } catch (MalformedURLException e) {
       e.printStackTrace();
   } catch (IOException e) {
       e.printStackTrace();
   } finally {
       // 关闭资源
       if (null != br) {
           try {
               br.close();
           } catch (IOException e) {
               e.printStackTrace();
           }
       }

       if (null != is) {
           try {
               is.close();
           } catch (IOException e) {
               e.printStackTrace();
           }
       }
       connection.disconnect();// 关闭远程连接
   }
   return result;
}

/**
* Post请求
*
* @param httpUrl url地址
* @param param   参数
* @return 返回
*/
public static String doPost(String httpUrl, String param) {
   HttpURLConnection connection = null;
   InputStream is = null;
   OutputStream os = null;
   BufferedReader br = null;
   String result = null;
   try {
       URL url = new URL(httpUrl);
       // 通过远程url连接对象打开连接
       connection = (HttpURLConnection) url.openConnection();
       // 设置连接请求方式
       connection.setRequestMethod("POST");
       // 设置连接主机服务器超时时间:15000毫秒
       connection.setConnectTimeout(15000);
       // 设置读取主机服务器返回数据超时时间:60000毫秒
       connection.setReadTimeout(60000);

       // 默认值为:false,当向远程服务器传送数据/写数据时,需要设置为true
       connection.setDoOutput(true);
       // 默认值为:true,当前向远程服务读取数据时,设置为true,该参数可有可无
       connection.setDoInput(true);
       // 请求参数判断,带问号的说明是String拼接,反之则为json
       if (param.contains("=")) {
           // 设置传入参数的格式:请求参数应该是 name1=value1&name2=value2 的形式。
           connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
       } else {
           //设置参数类型是json格式
           connection.setRequestProperty("Content-Type", "application/json;charset=utf-8");
       }
       // 通过连接对象获取一个输出流
       os = connection.getOutputStream();
       // 通过输出流对象将参数写出去/传输出去,它是通过字节数组写出的,并设置utf-8,防止中文出错
       os.write(param.getBytes("utf-8"));
       // 通过连接对象获取一个输入流,向远程读取
       if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
           is = connection.getInputStream();
           // 对输入流对象进行包装:charset根据工作项目组的要求来设置
           br = new BufferedReader(new InputStreamReader(is, "UTF-8"));

           StringBuffer sbf = new StringBuffer();
           String temp = null;
           // 循环遍历一行一行读取数据
           while ((temp = br.readLine()) != null) {
               sbf.append(temp);
               sbf.append("\r\n");
           }
           result = sbf.toString();
       } else {
           System.out.println("ResponseCode is an error code:" + connection.getResponseCode());
       }
   } catch (MalformedURLException e) {
       e.printStackTrace();
   } catch (IOException e) {
       e.printStackTrace();
   } finally {
       // 关闭资源
       if (null != br) {
           try {
               br.close();
           } catch (IOException e) {
               e.printStackTrace();
           }
       }
       if (null != os) {
           try {
               os.close();
           } catch (IOException e) {
               e.printStackTrace();
           }
       }
       if (null != is) {
           try {
               is.close();
           } catch (IOException e) {
               e.printStackTrace();
           }
       }
       // 断开与远程地址url的连接
       connection.disconnect();
   }
   return result;
}

main方法测试

public static void main(String[] args) {
      System.out.println("通过HttpURLConnection的get方式:" + doGet("http://localhost:8080/getReq"));
      Map map = new HashMap<>();
      map.put("name", "tyron");
      map.put("age", 18);
      System.out.println("通过HttpURLConnection的POST方式,参数为json形式:" + 
      doPost("http://localhost:8080/jsonPostReq", parseJson(map)));
      String param = "name=tyron";
      System.out.println("通过HttpURLConnection的POST方式,参数为String形式:" + 
      doPost("http://localhost:8080/stringPostReq", param));
  }

  /**
   * map转string
   *
   * @param map map
   * @return
   */
  public static String parseJson(Map map) {
      return JSONObject.toJSONString(map);
  }

控制台输出

通过HttpURLConnection的get方式:hello get

通过HttpURLConnection的POST方式,参数为json形式:用户:tyron,年龄:18

通过HttpURLConnection的POST方式,参数为String形式:hello:tyron

方法二:HttpClient4.5

HTTPClient 对 HTTP 的封装性比较不错,通过它基本上能够满足我们大部分的需求,HttpClient4.5 是 org.apache.http.client 下操作远程 url 的工具包



   org.apache.httpcomponents
   httpclient
   4.5.3

public static String doGet(String url) {
   CloseableHttpClient httpClient = null;
    CloseableHttpResponse response = null;
    String result = "";
    try {
        // 通过址默认配置创建一个httpClient实例
        httpClient = HttpClients.createDefault();
        // 创建httpGet远程连接实例
        HttpGet httpGet = new HttpGet(url);
        // 设置请求头信息,鉴权
//            httpGet.setHeader("Authorization", "Bearer da3efcbf-0845-4fe3-8aba-ee040be542c0");
        // 设置配置请求参数
        RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(35000)// 连接主机服务超时时间
                .setConnectionRequestTimeout(35000)// 请求超时时间
                .setSocketTimeout(60000)// 数据读取超时时间
                .build();
        // 为httpGet实例设置配置
        httpGet.setConfig(requestConfig);
        // 执行get请求得到返回对象
        response = httpClient.execute(httpGet);
        // 通过返回对象获取返回数据
        HttpEntity entity = response.getEntity();
        // 通过EntityUtils中的toString方法将结果转换为字符串
        result = EntityUtils.toString(entity);
    } catch (ClientProtocolException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        // 关闭资源
        if (null != response) {
            try {
                response.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (null != httpClient) {
            try {
                httpClient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    return result;
}

public static String doPost(String url, Map paramMap) {
    CloseableHttpClient httpClient = null;
    CloseableHttpResponse httpResponse = null;
    String result = "";
    // 创建httpClient实例
    httpClient = HttpClients.createDefault();
    // 创建httpPost远程连接实例
    HttpPost httpPost = new HttpPost(url);
    // 配置请求参数实例
    RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(35000)// 设置连接主机服务超时时间
            .setConnectionRequestTimeout(35000)// 设置连接请求超时时间
            .setSocketTimeout(60000)// 设置读取数据连接超时时间
            .build();
    // 为httpPost实例设置配置
    httpPost.setConfig(requestConfig);
    // 设置请求头
    httpPost.addHeader("Content-Type", "application/x-www-form-urlencoded");
    // 封装post请求参数
    if (null != paramMap && paramMap.size() > 0) {
        List nvps = new ArrayList<>();
        // 通过map集成entrySet方法获取entity
        Set> entrySet = paramMap.entrySet();
        // 循环遍历,获取迭代器
        Iterator> iterator = entrySet.iterator();
        while (iterator.hasNext()) {
            Entry mapEntry = iterator.next();
            nvps.add(new BasicNameValuePair(mapEntry.getKey(), mapEntry.getValue().toString()));
        }

        // 为httpPost设置封装好的请求参数
        try {
            httpPost.setEntity(new UrlEncodedFormEntity(nvps, "UTF-8"));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
    }
    try {
        // httpClient对象执行post请求,并返回响应参数对象
        httpResponse = httpClient.execute(httpPost);
        // 从响应对象中获取响应内容
        HttpEntity entity = httpResponse.getEntity();
        result = EntityUtils.toString(entity);
    } catch (ClientProtocolException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        // 关闭资源
        if (null != httpResponse) {
            try {
                httpResponse.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (null != httpClient) {
            try {
                httpClient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    return result;
}

main方法测试

public static void main(String[] args) {
    System.out.println(doGet("http://localhost:8080/getReq"));
    Map map = new HashMap<>();
    map.put("name", "tyron");
    System.out.println(doPost("http://localhost:8080/stringPostReq", map));
}

控制台输出

D:\soft\Java\jdk1.8.0_192\bin\java.exe "-javaagent:H:\Program Files\JetBrains\IntelliJ IDEA 2018.3.1\lib\idea_rt.jar=10427:H:\Program Files\JetBrains\IntelliJ IDEA 2018.3.1\bin" -Dfile.encoding=UTF-8 -classpath D:\soft\Java\jdk1.8.0_192\jre\lib\charsets.jar;D:\soft\Java\jdk1.8.0_192\jre\lib\deploy.jar;D:\soft\Java\jdk1.8.0_192\jre\lib\ext\access-bridge-64.jar;D:\soft\Java\jdk1.8.0_192\jre\lib\ext\cldrdata.jar;D:\soft\Java\jdk1.8.0_192\jre\lib\ext\dnsns.jar;D:\soft\Java\jdk1.8.0_192\jre\lib\ext\jaccess.jar;D:\soft\Java\jdk1.8.0_192\jre\lib\ext\jfxrt.jar;D:\soft\Java\jdk1.8.0_192\jre\lib\ext\localedata.jar;D:\soft\Java\jdk1.8.0_192\jre\lib\ext\nashorn.jar;D:\soft\Java\jdk1.8.0_192\jre\lib\ext\sunec.jar;D:\soft\Java\jdk1.8.0_192\jre\lib\ext\sunjce_provider.jar;D:\soft\Java\jdk1.8.0_192\jre\lib\ext\sunmscapi.jar;D:\soft\Java\jdk1.8.0_192\jre\lib\ext\sunpkcs11.jar;D:\soft\Java\jdk1.8.0_192\jre\lib\ext\zipfs.jar;D:\soft\Java\jdk1.8.0_192\jre\lib\javaws.jar;D:\soft\Java\jdk1.8.0_192\jre\lib\jce.jar;D:\soft\Java\jdk1.8.0_192\jre\lib\jfr.jar;D:\soft\Java\jdk1.8.0_192\jre\lib\jfxswt.jar;D:\soft\Java\jdk1.8.0_192\jre\lib\jsse.jar;D:\soft\Java\jdk1.8.0_192\jre\lib\management-agent.jar;D:\soft\Java\jdk1.8.0_192\jre\lib\plugin.jar;D:\soft\Java\jdk1.8.0_192\jre\lib\resources.jar;D:\soft\Java\jdk1.8.0_192\jre\lib\rt.jar;D:\idea_namespace\demo\target\classes;D:\maven\repository\org\springframework\boot\spring-boot-starter\2.1.4.RELEASE\spring-boot-starter-2.1.4.RELEASE.jar;D:\maven\repository\org\springframework\boot\spring-boot\2.1.4.RELEASE\spring-boot-2.1.4.RELEASE.jar;D:\maven\repository\org\springframework\spring-context\5.1.6.RELEASE\spring-context-5.1.6.RELEASE.jar;D:\maven\repository\org\springframework\boot\spring-boot-autoconfigure\2.1.4.RELEASE\spring-boot-autoconfigure-2.1.4.RELEASE.jar;D:\maven\repository\org\springframework\boot\spring-boot-starter-logging\2.1.4.RELEASE\spring-boot-starter-logging-2.1.4.RELEASE.jar;D:\maven\repository\ch\qos\logback\logback-classic\1.2.3\logback-classic-1.2.3.jar;D:\maven\repository\ch\qos\logback\logback-core\1.2.3\logback-core-1.2.3.jar;D:\maven\repository\org\apache\logging\log4j\log4j-to-slf4j\2.11.2\log4j-to-slf4j-2.11.2.jar;D:\maven\repository\org\apache\logging\log4j\log4j-api\2.11.2\log4j-api-2.11.2.jar;D:\maven\repository\org\slf4j\jul-to-slf4j\1.7.26\jul-to-slf4j-1.7.26.jar;D:\maven\repository\javax\annotation\javax.annotation-api\1.3.2\javax.annotation-api-1.3.2.jar;D:\maven\repository\org\springframework\spring-core\5.1.6.RELEASE\spring-core-5.1.6.RELEASE.jar;D:\maven\repository\org\springframework\spring-jcl\5.1.6.RELEASE\spring-jcl-5.1.6.RELEASE.jar;D:\maven\repository\org\yaml\snakeyaml\1.23\snakeyaml-1.23.jar;D:\maven\repository\org\slf4j\slf4j-api\1.7.26\slf4j-api-1.7.26.jar;D:\maven\repository\org\springframework\boot\spring-boot-starter-web\2.1.4.RELEASE\spring-boot-starter-web-2.1.4.RELEASE.jar;D:\maven\repository\org\springframework\boot\spring-boot-starter-json\2.1.4.RELEASE\spring-boot-starter-json-2.1.4.RELEASE.jar;D:\maven\repository\com\fasterxml\jackson\core\jackson-databind\2.9.8\jackson-databind-2.9.8.jar;D:\maven\repository\com\fasterxml\jackson\core\jackson-annotations\2.9.0\jackson-annotations-2.9.0.jar;D:\maven\repository\com\fasterxml\jackson\core\jackson-core\2.9.8\jackson-core-2.9.8.jar;D:\maven\repository\com\fasterxml\jackson\datatype\jackson-datatype-jdk8\2.9.8\jackson-datatype-jdk8-2.9.8.jar;D:\maven\repository\com\fasterxml\jackson\datatype\jackson-datatype-jsr310\2.9.8\jackson-datatype-jsr310-2.9.8.jar;D:\maven\repository\com\fasterxml\jackson\module\jackson-module-parameter-names\2.9.8\jackson-module-parameter-names-2.9.8.jar;D:\maven\repository\org\springframework\boot\spring-boot-starter-tomcat\2.1.4.RELEASE\spring-boot-starter-tomcat-2.1.4.RELEASE.jar;D:\maven\repository\org\apache\tomcat\embed\tomcat-embed-core\9.0.17\tomcat-embed-core-9.0.17.jar;D:\maven\repository\org\apache\tomcat\embed\tomcat-embed-el\9.0.17\tomcat-embed-el-9.0.17.jar;D:\maven\repository\org\apache\tomcat\embed\tomcat-embed-websocket\9.0.17\tomcat-embed-websocket-9.0.17.jar;D:\maven\repository\org\hibernate\validator\hibernate-validator\6.0.16.Final\hibernate-validator-6.0.16.Final.jar;D:\maven\repository\javax\validation\validation-api\2.0.1.Final\validation-api-2.0.1.Final.jar;D:\maven\repository\org\jboss\logging\jboss-logging\3.3.2.Final\jboss-logging-3.3.2.Final.jar;D:\maven\repository\com\fasterxml\classmate\1.4.0\classmate-1.4.0.jar;D:\maven\repository\org\springframework\spring-web\5.1.6.RELEASE\spring-web-5.1.6.RELEASE.jar;D:\maven\repository\org\springframework\spring-beans\5.1.6.RELEASE\spring-beans-5.1.6.RELEASE.jar;D:\maven\repository\org\springframework\spring-webmvc\5.1.6.RELEASE\spring-webmvc-5.1.6.RELEASE.jar;D:\maven\repository\org\springframework\spring-aop\5.1.6.RELEASE\spring-aop-5.1.6.RELEASE.jar;D:\maven\repository\org\springframework\spring-expression\5.1.6.RELEASE\spring-expression-5.1.6.RELEASE.jar;D:\maven\repository\com\alibaba\fastjson\1.2.39\fastjson-1.2.39.jar;D:\maven\repository\org\apache\httpcomponents\httpclient\4.5.3\httpclient-4.5.3.jar;D:\maven\repository\org\apache\httpcomponents\httpcore\4.4.11\httpcore-4.4.11.jar;D:\maven\repository\commons-codec\commons-codec\1.11\commons-codec-1.11.jar;D:\maven\repository\cn\hutool\hutool-all\4.5.10\hutool-all-4.5.10.jar com.tyron.demo.http_client.Client_HttpClient4
DEBUG org.apache.http.client.protocol.RequestAddCookies - CookieSpec selected: default
DEBUG org.apache.http.client.protocol.RequestAuthCache - Auth cache not set in the context
DEBUG org.apache.http.impl.conn.PoolingHttpClientConnectionManager - Connection request: [route: {}->http://localhost:8080][total kept alive: 0; route allocated: 0 of 2; total allocated: 0 of 20]
DEBUG org.apache.http.impl.conn.PoolingHttpClientConnectionManager - Connection leased: [id: 0][route: {}->http://localhost:8080][total kept alive: 0; route allocated: 1 of 2; total allocated: 1 of 20]
DEBUG org.apache.http.impl.execchain.MainClientExec - Opening connection {}->http://localhost:8080
DEBUG org.apache.http.impl.conn.DefaultHttpClientConnectionOperator - Connecting to localhost/127.0.0.1:8080
DEBUG org.apache.http.impl.conn.DefaultHttpClientConnectionOperator - Connection established 127.0.0.1:10432<->127.0.0.1:8080
DEBUG org.apache.http.impl.conn.DefaultManagedHttpClientConnection - http-outgoing-0: set socket timeout to 60000
DEBUG org.apache.http.impl.execchain.MainClientExec - Executing request GET /getReq HTTP/1.1
。。。省略
DEBUG org.apache.http.impl.execchain.MainClientExec - Connection can be kept alive indefinitely
DEBUG org.apache.http.impl.conn.PoolingHttpClientConnectionManager - Connection [id: 0][route: {}->http://localhost:8080] can be kept alive indefinitely
DEBUG org.apache.http.impl.conn.PoolingHttpClientConnectionManager - Connection released: [id: 0][route: {}->http://localhost:8080][total kept alive: 1; route allocated: 1 of 2; total allocated: 1 of 20]
DEBUG org.apache.http.impl.conn.PoolingHttpClientConnectionManager - Connection manager is shutting down
DEBUG org.apache.http.impl.conn.DefaultManagedHttpClientConnection - http-outgoing-0: Close connection
DEBUG org.apache.http.impl.conn.PoolingHttpClientConnectionManager - Connection manager shut down
hello get
DEBUG org.apache.http.impl.conn.PoolingHttpClientConnectionManager - Connection request: [route: {}->http://localhost:8080][total kept alive: 0; route allocated: 0 of 2; total allocated: 0 of 20]
DEBUG org.apache.http.impl.conn.PoolingHttpClientConnectionManager - Connection leased: [id: 1][route: {}->http://localhost:8080][total kept alive: 0; route allocated: 1 of 2; total allocated: 1 of 20]
DEBUG org.apache.http.impl.execchain.MainClientExec - Opening connection {}->http://localhost:8080
DEBUG org.apache.http.impl.conn.DefaultHttpClientConnectionOperator - Connecting to localhost/127.0.0.1:8080
DEBUG org.apache.http.impl.conn.DefaultHttpClientConnectionOperator - Connection established 127.0.0.1:10433<->127.0.0.1:8080
DEBUG org.apache.http.impl.conn.DefaultManagedHttpClientConnection - http-outgoing-1: set socket timeout to 60000
DEBUG org.apache.http.impl.execchain.MainClientExec - Executing request POST /stringPostReq HTTP/1.1
。。。省略
DEBUG org.apache.http.impl.conn.PoolingHttpClientConnectionManager - Connection manager shut down
hello:tyron

方法三、Hutool - HttpUtil

  • A set of tools that keep Java sweet。Hutool是一个Java工具包,也只是一个工具包,它帮助我们简化每一行代码,减少每一个方法,让Java语言也可以“甜甜的”。Hutool最初是我项目中“util”包的一个整理,后来慢慢积累并加入更多非业务相关功能,并广泛学习其它开源项目精髓,经过自己整理修改,最终形成丰富的开源工具集。
  • 此处使用的是 Http客户端工具类 - HttpUtil

main方法测试

public static void main(String[] args) {
    // 最简单的HTTP请求,可以自动通过header等信息判断编码,不区分HTTP和HTTPS
    String result1 = HttpUtil.get("http://localhost:8080/getReq");
    System.out.println(result1);

    // 当无法识别页面编码的时候,可以自定义请求页面的编码
    String result2 = HttpUtil.get("http://localhost:8080/getReq", CharsetUtil.CHARSET_UTF_8);
    System.out.println(result2);

    HashMap paramMap = new HashMap<>();
    paramMap.put("name", "tyron");
    String result = HttpUtil.post("http://localhost:8080/stringPostReq", paramMap);
    System.out.println(result);

    Map map = new HashMap<>();
    map.put("name", "tyron");
    map.put("age", 18);
    System.out.println(HttpUtil.post("http://localhost:8080/jsonPostReq", JSONUtil.parseFromMap(map).toString()));
}

控制台输出

[main] DEBUG cn.hutool.log.LogFactory - Use [Slf4j] Logger As Default.
hello get
hello get
hello:tyron
用户:tyron,年龄:18

你可能感兴趣的:(Java笔记)