Java中发送Http请求的方式有很多,记录一下相关的请求方式,本次记录Jdk自带的HttpURLConnection,简单简洁,使用简单.
HttpURLConnection是Jdk自带的请求工具,不用依赖第三方jar包,适用简单的场景使用.
使用方式是, 通过调用URL.openConnection方法,得到一个URLConnection对象,并强转为HttpURLConnection对象.
java.net.URL部分源码:
public URLConnection openConnection() throws java.io.IOException { return handler.openConnection(this); }
java.net.HttpURLConnection部分源码:
abstract public class HttpURLConnection extends URLConnection { // ... }
从代码可知HttpURLConnection是URLConnection子类, 其内类中主要放置的是一些父类的方法和请求码信息.
发送GET请求, 其主要的参数从URI中获取,还有请求头,cookies等数据.
发送POST请求, HttpURLConnection实例必须设置setDoOutput(true),其请求体数据写入由HttpURLConnection的getOutputStream()方法返回的输出流来传输数据.
@Controller @Slf4j public class HelloWorld { @Override @GetMapping("/world/getData") @ResponseBody public String getData(@RequestParam Map<String, Object> param) { System.out.println(param.toString()); return "<h1> Hello World getData 方法</h1>"; } @PostMapping("/world/getResult") @ResponseBody public String getResult(@RequestBody Map<String, Object> param) { System.out.println(param.toString()); return "<h1> Hello World getResult 方法</h1>"; } }
package com.cf.demo.http; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.net.HttpURLConnection; import java.net.URL; import java.net.URLEncoder; import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; import lombok.Data; import lombok.extern.slf4j.Slf4j; /** * Http请求工具类 */ @Slf4j @Data public class JdkHttpUtils { /** * 获取 POST请求 * * @return 请求结果 */ public static String getPost(String url, Integer connectTimeout, Integer readTimeout, String contentType, Map<String, String> heads, Map<String, String> params) throws IOException { URL u; HttpURLConnection connection = null; OutputStream out; try { u = new URL(url); connection = (HttpURLConnection) u.openConnection(); connection.setRequestMethod("POST"); connection.setConnectTimeout(connectTimeout); connection.setReadTimeout(readTimeout); connection.setRequestProperty("Content-Type", contentType); // POST请求必须设置该属性 connection.setDoOutput(true); connection.setDoInput(true); if (heads != null) { for (Map.Entry<String, String> stringStringEntry : heads.entrySet()) { connection.setRequestProperty(stringStringEntry.getKey(), stringStringEntry.getValue()); } } out = connection.getOutputStream(); if (params != null && !params.isEmpty()) { out.write(toJSONString(params).getBytes()); } out.flush(); out.close(); // 获取请求返回的数据流 InputStream is = connection.getInputStream(); ByteArrayOutputStream baos = new ByteArrayOutputStream(); // 封装输入流is,并指定字符集 int i; while ((i = is.read()) != -1) { baos.write(i); } return baos.toString(); } catch (Exception e) { log.error("请求发生异常,信息为= {} ", e.getMessage()); } return null; } /** * 获取 POST请求 * * @return 请求结果 */ public static String getGet(String url, Integer connectTimeout, Integer readTimeout, String contentType, Map<String, String> heads, Map<String, String> params) throws IOException { // 拼接请求参数 if (params != null && !params.isEmpty()) { url += "?"; if (params != null && !params.isEmpty()) { StringBuilder sb = new StringBuilder(); for (Map.Entry<String, String> stringObjectEntry : params.entrySet()) { try { sb.append(stringObjectEntry.getKey()).append("=").append( URLEncoder.encode(stringObjectEntry.getValue(), "UTF-8")) .append("&"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } sb.delete(sb.length() - 1, sb.length()); url += sb.toString(); } } URL u; HttpURLConnection connection; u = new URL(url); connection = (HttpURLConnection) u.openConnection(); connection.setRequestMethod("GET"); connection.setConnectTimeout(connectTimeout); connection.setReadTimeout(readTimeout); connection.setRequestProperty("Content-Type", contentType); if (heads != null) { for (Map.Entry<String, String> stringStringEntry : heads.entrySet()) { connection.setRequestProperty(stringStringEntry.getKey(), stringStringEntry.getValue()); } } // 获取请求返回的数据流 InputStream is = connection.getInputStream(); ByteArrayOutputStream baos = new ByteArrayOutputStream(); // 封装输入流is,并指定字符集 int i; while ((i = is.read()) != -1) { baos.write(i); } return baos.toString(); } /** * Map转Json字符串 */ public static String toJSONString(Map<String, String> map) { Iterator<Entry<String, String>> i = map.entrySet().iterator(); if (!i.hasNext()) { return "{}"; } StringBuilder sb = new StringBuilder(); sb.append('{'); for (; ; ) { Map.Entry<String, String> e = i.next(); String key = e.getKey(); String value = e.getValue(); sb.append("\""); sb.append(key); sb.append("\""); sb.append(':'); sb.append("\""); sb.append(value); sb.append("\""); if (!i.hasNext()) { return sb.append('}').toString(); } sb.append(',').append(' '); } } }
@Slf4j public class HttpTest { // 请求地址 public String url = ""; // 请求头参数 public Map<String, String> heads = new HashMap<>(); // 请求参数 public Map<String, String> params = new HashMap<>(); // 数据类型 public String contentType = "application/json"; // 连接超时 public Integer connectTimeout = 15000; // 读取超时 public Integer readTimeout = 60000; @Test public void testGET() { // 1 添加数据 url = "http://localhost:8080/world/getData"; heads.put("token", "hhhhhhhhhhhaaaaaaaa"); params.put("username", "libai"); String result = null; try { // 2 发送Http请求,获取返回结果 result = JdkHttpUtils .getGet(url, connectTimeout, readTimeout, contentType, heads, params); } catch (IOException e) { e.printStackTrace(); } // 3 打印结果 log.info(result); } @Test public void testPOST() { // 1 添加数据 url = "http://localhost:8080/world/getResult"; heads.put("token", "hhhhhhhhhhhaaaaaaaa"); params.put("username", "libai"); String result = null; try { // 2 发送Http请求,获取返回结果 result = JdkHttpUtils .getPost(url, connectTimeout, readTimeout, contentType, heads, params); } catch (IOException e) { e.printStackTrace(); } // 3 打印结果 log.info(result); } }
POST请求测试结果
/* [main] INFO com.cf.demo.HttpTest - <h1> Hello World getResult 方法</h1> {username=libai} */
GET请求测试结果
/* [main] INFO com.cf.demo.HttpTest - <h1> Hello World getData方法</h1> {username=libai} */
参考资料:
https://www.baeldung.com/java-http-request