java 发送 http 请求练习两年半(HttpURLConnection)

打印 上一主题 下一主题

主题 893|帖子 893|积分 2679

1、起一个 springboot 程序做 http 测试:
  1.     @GetMapping("/http/get")
  2.     public ResponseEntity<String> testHttpGet(@RequestParam("param") String param) {
  3.         System.out.println(param);
  4.         return ResponseEntity.ok("---------> revive http get request --------->");
  5.     }
  6.     @PostMapping("/http/post")
  7.     public ResponseEntity<String> testHttpPost(@RequestBody List<Object> body) {
  8.         System.out.println(body);
  9.         return ResponseEntity.ok("---------> receive http post request --------->");
  10.     }
复制代码
2、写一个 HttpURLConnection 自定义客户端
  1. import java.io.BufferedReader;
  2. import java.io.DataOutputStream;
  3. import java.io.IOException;
  4. import java.io.InputStream;
  5. import java.io.InputStreamReader;
  6. import java.net.ConnectException;
  7. import java.net.HttpURLConnection;
  8. import java.net.URL;
  9. import java.net.URLEncoder;
  10. import java.nio.charset.StandardCharsets;
  11. import java.util.Map;
  12. public class MyHttpClient {
  13.     private final HttpURLConnection connection;
  14.     private MyHttpClient(String url, Map<String, String> params) throws IOException {
  15.         connection = buildConnection(url, params);
  16.     }
  17.     private MyHttpClient(String url, Map<String, String> params, String jsonBody) throws IOException {
  18.         connection = buildConnection(url, params);
  19.         connection.setRequestMethod("POST");
  20.         connection.setRequestProperty("Content-Type", "application/json;charset=utf-8");
  21.         connection.setDoOutput(true);
  22.         try (DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream())) {
  23.             outputStream.writeBytes(jsonBody);
  24.             outputStream.flush();
  25.         }
  26.     }
  27.     public static MyHttpClient get(String url, Map<String, String> params) throws IOException {
  28.         return new MyHttpClient(url, params);
  29.     }
  30.     public static MyHttpClient post(String url, Map<String, String> params, String jsonBody) throws IOException {
  31.         return new MyHttpClient(url, params, jsonBody);
  32.     }
  33.     /**
  34.      * 创建 http 连接
  35.      *
  36.      * @param url    请求路径
  37.      * @param params 请求参数,可以为空
  38.      * @return http 连接
  39.      */
  40.     private HttpURLConnection buildConnection(String url, Map<String, String> params) throws IOException {
  41.         String requestParams = getParamsString(params);
  42.         return (HttpURLConnection) new URL(requestParams != null ? url + "?" + requestParams : url).openConnection();
  43.     }
  44.     /**
  45.      * 获取 http 请求响应结果
  46.      *
  47.      * @return 响应结果,失败抛异常
  48.      */
  49.     public String getResponse() throws IOException {
  50.         int responseCode = connection.getResponseCode();
  51.         if (responseCode >= HttpURLConnection.HTTP_OK && responseCode < HttpURLConnection.HTTP_MULT_CHOICE) {
  52.             BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
  53.             String inputLine;
  54.             StringBuilder response = new StringBuilder();
  55.             while ((inputLine = in.readLine()) != null) {
  56.                 response.append(inputLine);
  57.             }
  58.             in.close();
  59.             connection.disconnect();
  60.             return response.toString();
  61.         } else {
  62.             connection.disconnect();
  63.             InputStream errorStream = connection.getErrorStream();
  64.             if (errorStream == null) {
  65.                 throw new ConnectException("request fail");
  66.             }
  67.             throw new ConnectException(new String(errorStream.readAllBytes(), StandardCharsets.UTF_8));
  68.         }
  69.     }
  70.     /**
  71.      * 拼接请求参数
  72.      *
  73.      * @param params 参数 map
  74.      * @return 请求参数字符串
  75.      */
  76.     public static String getParamsString(Map<String, String> params) {
  77.         if (params == null || params.isEmpty()) {
  78.             return null;
  79.         }
  80.         StringBuilder result = new StringBuilder();
  81.         for (Map.Entry<String, String> entry : params.entrySet()) {
  82.             result.append(URLEncoder.encode(entry.getKey(), StandardCharsets.UTF_8));
  83.             result.append("=");
  84.             result.append(URLEncoder.encode(entry.getValue(), StandardCharsets.UTF_8));
  85.             result.append("&");
  86.         }
  87.         String resultString = result.toString();
  88.         return resultString.length() > 0
  89.                 ? resultString.substring(0, resultString.length() - 1)
  90.                 : resultString;
  91.     }
  92. }
复制代码
3、测试 get 和 post 请求
  1.     public static void main(String[] args) throws IOException {
  2.         MyHttpClient myHttpClient = MyHttpClient.get("http://127.0.0.1:8083/springboot/http/get",
  3.                 Map.of("param", "1"));
  4.         String resultGet = myHttpClient.getResponse();
  5.         System.out.println(resultGet);
  6.         MyHttpClient httpClient = MyHttpClient.post("http://127.0.0.1:8083/springboot/http/post",
  7.                 null,
  8.                 "[1,2,3,4,5]");
  9.         String resultPost = httpClient.getResponse();
  10.         System.out.println(resultPost);
  11.     }
复制代码
4、控制台输出结果
  1. ---------> revive http get request --------->
  2. ---------> receive http post request --------->
  3. Process finished with exit code 0
复制代码
中间遇到一些坑,经常以为 http 会有方法像 openfeign 那样传入请求参数,忽略了路径拼接,
启动的 springboot 接收的 post 的请求体为 List 类型,且 Content-Type 是 json,在测试 post 请求时一直报错,看了 spring 控制台才发现 json 转对象封装 没对上。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

我爱普洱茶

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表