Java案例如何发送HTTP请求?

wen java案例 10

Java案例如何发送HTTP请求?从基础到实战的完整指南

目录导读

  1. 为什么Java开发者需要掌握HTTP请求?
  2. Java发送HTTP请求的四大主流方式
  3. 经典案例:用HttpURLConnection发送GET/POST请求
  4. 企业级实战:Apache HttpClient完整示例
  5. 现代化方案:OkHttp与Spring RestTemplate
  6. 常见问题与解决方案(Q&A)
  7. 性能优化与最佳实践

为什么Java开发者需要掌握HTTP请求?

在当今微服务架构和API经济时代,Java应用常常需要与其他系统交互——无论是调用第三方RESTful API、爬取网页数据,还是构建分布式服务的内部通信,掌握如何用Java发送HTTP请求已成为后端开发的基本功。

Java案例如何发送HTTP请求?

根据Stack Overflow 2023开发者调查,超过70%的Java项目涉及HTTP通信,但很多初学者仍停留在“使用浏览器”的思维模式,不知道在代码中如何发起网络请求。

核心场景包括

  • 调用微信支付、支付宝等第三方接口
  • 对接企业内部微服务网关
  • 实现数据采集(网页爬虫)
  • 构建API测试工具

Java发送HTTP请求的四大主流方式

方法 JDK版本要求 优点 缺点 适用场景
HttpURLConnection JDK 1.1+ 零依赖,原生支持 API较底层,代码繁琐 简单测试/JDK内置
Apache HttpClient JDK 1.5+ 功能全面,支持连接池 需导入第三方JAR 企业级生产环境
OkHttp JDK 1.7+ 高效异步,语法简洁 需要引入依赖 Android/高并发场景
Spring RestTemplate Spring 3+ 模板化设计,集成方便 需Spring框架 Spring项目首选

注意:Java 11后引入了HttpClient(位于java.net.http包),可视为HttpURLConnection的替代方案。


经典案例:用HttpURLConnection发送GET/POST请求

GET请求示例(获取JSON数据):

public static String sendGet(String urlStr) throws Exception {
    URL url = new URL(urlStr);
    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
    conn.setRequestMethod("GET");
    conn.setConnectTimeout(5000);
    conn.setReadTimeout(5000);
    // 读取响应
    BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
    String inputLine;
    StringBuilder response = new StringBuilder();
    while ((inputLine = in.readLine()) != null) {
        response.append(inputLine);
    }
    in.close();
    return response.toString();
}

POST请求示例(发送JSON数据):

public static String sendPost(String urlStr, String jsonBody) throws Exception {
    URL url = new URL(urlStr);
    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
    conn.setRequestMethod("POST");
    conn.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
    conn.setDoOutput(true);
    // 写入请求体
    try (OutputStream os = conn.getOutputStream()) {
        byte[] input = jsonBody.getBytes("utf-8");
        os.write(input, 0, input.length);
    }
    // 读取响应
    try (BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8"))) {
        StringBuilder response = new StringBuilder();
        String line;
        while ((line = br.readLine()) != null) {
            response.append(line.trim());
        }
        return response.toString();
    }
}

案例说明:以上代码展示了最基础的HTTP通信逻辑,适用于JDK自带环境,但需注意资源关闭和异常处理。


企业级实战:Apache HttpClient完整示例

Maven依赖

<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.5.14</version>
</dependency>

发送GET请求并处理Headers

public static String doGetWithHeaders(String url) {
    try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
        HttpGet request = new HttpGet(url);
        request.addHeader("User-Agent", "Mozilla/5.0");
        request.addHeader("Authorization", "Bearer your_token_here");
        try (CloseableHttpResponse response = httpClient.execute(request)) {
            HttpEntity entity = response.getEntity();
            return EntityUtils.toString(entity, "UTF-8");
        }
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    }
}

POST请求带参数(表单提交)

public static String doPostForm(String url, Map<String, String> params) {
    try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
        HttpPost httpPost = new HttpPost(url);
        List<NameValuePair> nvps = new ArrayList<>();
        for (Map.Entry<String, String> entry : params.entrySet()) {
            nvps.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
        }
        httpPost.setEntity(new UrlEncodedFormEntity(nvps, "UTF-8"));
        try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
            return EntityUtils.toString(response.getEntity(), "UTF-8");
        }
    } catch (IOException e) {
        throw new RuntimeException("POST请求失败", e);
    }
}

企业级优势

  • 支持连接池管理(避免频繁创建/销毁连接)
  • 自动处理cookie、重定向
  • 丰富的拦截器机制

现代化方案:OkHttp与Spring RestTemplate

OkHttp案例(Kotlin/Java双友好)

OkHttpClient client = new OkHttpClient.Builder()
    .connectTimeout(10, TimeUnit.SECONDS)
    .readTimeout(30, TimeUnit.SECONDS)
    .build();
Request request = new Request.Builder()
    .url("https://api.example.com/data")
    .post(RequestBody.create(
        MediaType.parse("application/json"), 
        "{\"key\":\"value\"}"
    ))
    .build();
try (Response response = client.newCall(request).execute()) {
    return response.body().string();
}

Spring RestTemplate(需Spring Boot项目)

@Service
public class ApiService {
    @Autowired
    private RestTemplate restTemplate;
    public String callExternalApi() {
        // GET请求
        String result = restTemplate.getForObject(
            "https://api.github.com/users/{username}", 
            String.class, 
            "square"
        );
        // POST请求
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        HttpEntity<String> entity = new HttpEntity<>("{\"name\":\"test\"}", headers);
        ResponseEntity<String> response = restTemplate.exchange(
            "https://httpbin.org/post",
            HttpMethod.POST,
            entity,
            String.class
        );
        return response.getBody();
    }
}

常见问题与解决方案(Q&A)

Q1:为什么我的POST请求返回400错误?

  • 检查Content-Type是否匹配服务器期望格式
  • 确认JSON格式是否合法(使用在线验证工具)
  • 检查字符编码是否正确

Q2:如何处理HTTPS请求中的证书问题?

// 信任所有证书(仅限开发环境)
TrustManager[] trustAllCerts = new TrustManager[]{
    new X509TrustManager() {
        public void checkClientTrusted(X509Certificate[] certs, String authType) {}
        public void checkServerTrusted(X509Certificate[] certs, String authType) {}
        public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[0]; }
    }
};
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, trustAllCerts, new SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());

Q3:如何设置超时时间?

  • HttpURLConnection:setConnectTimeout()/setReadTimeout()
  • HttpClient:RequestConfig.custom().setConnectTimeout(5000)
  • OkHttp:new OkHttpClient.Builder().connectTimeout(...)

Q4:发送请求时出现Connection refused怎么办?

  • 确认目标地址IP和端口是否正确
  • 检查网络连通性(telnet测试)
  • 查看防火墙是否拦截请求

性能优化与最佳实践

  1. 使用连接池:避免每次请求都创建新连接,支持Keep-Alive

    // HttpClient连接池配置
    PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
    cm.setMaxTotal(200);
    cm.setDefaultMaxPerRoute(50);
  2. 合理设置超时:连接超时一般3-5秒,读取超时15-30秒

  3. 异步请求:OkHttp支持Call.enqueue()实现非阻塞调用

  4. 资源关闭:始终在finally块中关闭Response/InputStream

  5. 日志记录:使用SLF4J记录请求/响应详情,便于排错

  6. 重试机制:对幂等操作(GET/PUT)实现指数退避重试


延伸阅读:如果你需要处理大型文件上传,推荐使用Apache HttpClient的MultipartEntityBuilder;若用于微服务间调用,可考虑Spring Cloud OpenFeign。

本文通过从原生API到现代框架的完整对比,结合大量可运行代码片段,帮助你快速掌握Java HTTP请求开发的方方面面,无论你是初学者还是经验丰富的开发者,都能从中找到适合自己项目的实现方案。

抱歉,评论功能暂时关闭!