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

Java HttpURLConnection读取带负载的400错误响应问题

解决API 400状态码响应读取问题

你的代码无法处理400响应的核心原因是:当HttpURLConnection返回4xx/5xx这类错误状态码时,直接调用getInputStream()会抛出IOException,而错误响应的内容实际需要通过getErrorStream()来获取。

下面是修改后的完整代码,同时优化了文件写入的重复逻辑:

public static void blahblah(String input, String CustomerID, String endpoint, String dateNameFolder) throws UnknownHostException {
    try {
        URL url = new URL(endpoint);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setDoOutput(true);
        conn.setRequestMethod("POST");
        conn.setRequestProperty("Content-Type", "application/json; charset=UTF-8");

        OutputStream os = conn.getOutputStream();
        os.write(input.getBytes());
        os.flush();
        os.close(); // 主动关闭输出流,避免资源泄漏

        // 关键:先获取响应状态码,判断使用正常流还是错误流
        int responseCode = conn.getResponseCode();
        InputStream inputStream = (responseCode >= 200 && responseCode < 300) 
            ? conn.getInputStream() 
            : conn.getErrorStream();

        BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
        StringBuilder sb = new StringBuilder();
        String output;
        while ((output = br.readLine()) != null) {
            sb.append(output);
        }
        br.close(); // 关闭输入流

        // 优化文件写入逻辑,用try-with-resources自动管理流
        File fileObj = new File(CustomerID + ".json");
        try (FileWriter dataWriter = new FileWriter(fileObj)) {
            dataWriter.write(sb.toString());
        }

        // 针对400错误,解析XML提取详细错误信息
        if (responseCode == HttpURLConnection.HTTP_BAD_REQUEST) {
            parseErrorXml(sb.toString(), CustomerID);
        }

        conn.disconnect();

    } catch (MalformedURLException e) {
        log.info(e);
    } catch (IOException e) {
        log.error("请求Catalog API时发生IO错误,客户ID: " + CustomerID);
        log.info(e);
    }
}

// 解析400响应的XML错误内容
private static void parseErrorXml(String xmlContent, String customerID) {
    try {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document doc = builder.parse(new InputSource(new StringReader(xmlContent)));
        doc.getDocumentElement().normalize();

        String statusCode = doc.getElementsByTagName("StatusCode").item(0).getTextContent();
        String errorCode = doc.getElementsByTagName("ErrorCode").item(0).getTextContent();
        String message = doc.getElementsByTagName("Message").item(0).getTextContent();

        log.error("客户ID: " + customerID + ",API错误详情:");
        log.error("状态标识: " + statusCode);
        log.error("错误码: " + errorCode);
        log.error("错误信息: " + message);

        // 解析上下文关联信息
        NodeList contextNodes = doc.getElementsByTagName("Context");
        if (contextNodes.getLength() > 0) {
            Element context = (Element) contextNodes.item(0);
            String entityCode = context.getElementsByTagName("EntityUniqueCode").item(0).getTextContent();
            String charId = context.getElementsByTagName("CharacteristicID").item(0).getTextContent();
            log.error("关联数据: 实体唯一码=" + entityCode + ",特征ID=" + charId);
        }

    } catch (Exception e) {
        log.error("解析错误XML失败,客户ID: " + customerID, e);
    }
}

关键修改说明

  1. 状态码判断与流选择:先调用getResponseCode()获取状态码,根据码值范围选择读取正常流或错误流,确保400响应内容能被捕获。
  2. 资源自动管理:使用try-with-resources语法处理文件写入流,避免手动关闭流时的遗漏问题。
  3. 错误信息解析:新增parseErrorXml方法,专门解析400响应的XML内容,提取关键错误字段并记录日志,方便快速定位问题。
  4. 流关闭优化:主动关闭输出流和输入流,避免不必要的资源占用。

400错误响应示例

<Response>
    <StatusCode>BadRequest</StatusCode>
    <ErrorCode>OrderRequestInvalid.InvalidCharacteristicUse</ErrorCode>
    <Message>Characteristic ID cannot be found in the specification: { EntityUniqueCode: CS_0aefdfec-022e-4ac9-a84b-83c8ea2e0fd0, CharacteristicID: 76c4e767-ce7b-4675-a178-d832839b322f}</Message>
    <Context>
        <EntityUniqueCode>CS_0aefdfec-022e-4ac9-a84b-83c8ea2e0fd0</EntityUniqueCode>
        <CharacteristicID>76c4e767-ce7b-4675-a178-d832839b322f</CharacteristicID>
    </Context>
</Response>

内容的提问来源于stack exchange,提问作者enemyofnone

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 22:24:23