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

