You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java中遇HTTP 400错误时如何读取响应体?

问题:如何读取HTTP 4xx状态码对应的响应体?

我用Java代码调用HTTP POST接口时,响应码200能正常获取InputStream读取响应,但响应码400时,在标记/// error !!!的代码行会抛出异常:

Exception in thread "main" java.io.IOException: Server returned HTTP response code: 400 for URL: ...
at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1924)
at java.base/sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1520)
at com.test123.Main009.main(Main009.java:41)

请问有没有办法读取4xx状态码对应的响应体?

对应的原代码:

package com.test123;

import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

public class Main009 {

    public static void main(String[] args) throws Exception {
        String username = "xxx";
        String password = "yyy";
        
        URL url = new URL("http://host/path");
        URLConnection uc = url.openConnection();
        HttpURLConnection http = (HttpURLConnection)uc;
        
        http.setRequestMethod("POST"); // PUT is another valid option
        http.setDoOutput(true);
        http.setDoInput(true);

        byte[] request = "{ id: \"test2\" }".getBytes(StandardCharsets.UTF_8);
        int length = request.length;

        http.setFixedLengthStreamingMode(length);
        
        String userpass = username + ":" + password;
        String basicAuth = "Basic " + new String(Base64.getEncoder().encode(userpass.getBytes()));
        
        http.setRequestProperty ("Authorization", basicAuth);
        http.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
        // http.connect();
        
        try(OutputStream os = http.getOutputStream()) {
            os.write(request);
            os.flush();
            
            InputStream in = http.getInputStream(); /// error !!!  
            System.out.println(in);
        }
    }
}

解决方案

当HTTP响应码为4xx或5xx时,HttpURLConnection.getInputStream()会直接抛出异常,此时需要调用HttpURLConnection.getErrorStream()来读取错误响应体。核心处理逻辑如下:

  • 先获取响应码,根据响应码区间判断使用正常输入流还是错误流
  • 统一读取流内容,完成资源释放

修改后的代码示例:

package com.test123;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

public class Main009 {

    public static void main(String[] args) throws Exception {
        String username = "xxx";
        String password = "yyy";
        
        URL url = new URL("http://host/path");
        HttpURLConnection http = (HttpURLConnection) url.openConnection();
        
        http.setRequestMethod("POST");
        http.setDoOutput(true);
        http.setDoInput(true);

        byte[] request = "{ id: \"test2\" }".getBytes(StandardCharsets.UTF_8);
        int length = request.length;

        http.setFixedLengthStreamingMode(length);
        
        String userpass = username + ":" + password;
        String basicAuth = "Basic " + new String(Base64.getEncoder().encode(userpass.getBytes()));
        
        http.setRequestProperty("Authorization", basicAuth);
        http.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
        
        // 发送请求
        try(OutputStream os = http.getOutputStream()) {
            os.write(request);
            os.flush();
        }

        // 根据响应码选择对应输入流
        int responseCode = http.getResponseCode();
        InputStream inputStream = (responseCode >= 200 && responseCode < 300) 
            ? http.getInputStream() 
            : http.getErrorStream();

        // 读取并打印响应内容
        try(BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, StandardCharsets.UTF_8))) {
            StringBuilder response = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                response.append(line);
            }
            System.out.println("响应码: " + responseCode);
            System.out.println("响应内容: " + response.toString());
        } finally {
            http.disconnect();
        }
    }
}

关键说明
  1. 流的选择时机:必须先完成请求发送(写入输出流并关闭/flush),再获取响应码和对应流,否则会出现连接状态异常。
  2. 错误流的有效性:getErrorStream()仅在响应码为错误状态(4xx/5xx)时返回有效流,成功状态下调用会返回null。
  3. 资源释放:务必通过try-with-resources或手动关闭流,最后调用disconnect()释放HTTP连接资源。

内容的提问来源于stack exchange,提问作者peter.petrov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 05:00:38