Java读取指定网页XML内容转为字符串时出现HTTP响应异常如何解决?
问题根因
目标站点返回的HTTP响应头不符合RFC规范,浏览器自带宽松解析逻辑可以正常渲染,但Java原生网络库、Apache HttpClient默认开启严格HTTP协议校验,因此会抛出响应无效的异常。wget的--content-on-error参数本质就是跳过协议校验直接读取返回体,因此可以拿到内容。
可用解决方案
方案1:配置Apache HttpClient关闭严格校验(推荐,有HTTP基础能力兜底)
无需依赖外部工具,通过调整HttpClient配置即可兼容不规范响应,代码示例如下:
import org.apache.http.client.config.RequestConfig; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.HttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.util.EntityUtils; import java.nio.charset.StandardCharsets; public class NonStandardHttpReader { public static void main(String[] args) throws Exception { // 关闭严格HTTP协议校验,允许非规范响应 RequestConfig looseConfig = RequestConfig.custom() .setStrictMode(false) .build(); try (CloseableHttpClient httpClient = HttpClients.custom() .setDefaultRequestConfig(looseConfig) .build()) { HttpGet httpGet = new HttpGet("你的目标URL"); HttpResponse response = httpClient.execute(httpGet); // 直接读取返回体,忽略协议层面的格式错误 String rawXML = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8); // 后续可自行解析XML System.out.println(rawXML); } } }
方案2:原生Socket直接读取TCP流(无额外依赖,兼容性最高)
如果不想引入第三方依赖,可以直接通过TCP套接字读取完整返回内容,跳过HTTP协议解析,自行截取XML部分即可:
import java.io.InputStream; import java.net.Socket; import java.nio.charset.StandardCharsets; public class RawTcpReader { public static void main(String[] args) throws Exception { String host = "目标站点域名"; int port = 443; // HTTPS站点用443,HTTP站点用80 String path = "请求路径和参数"; // HTTPS站点使用SSLSocket,HTTP站点直接new Socket(host, port)即可 try (Socket socket = javax.net.ssl.SSLSocketFactory.getDefault().createSocket(host, port); InputStream is = socket.getInputStream()) { // 构造标准GET请求报文发送 String request = String.format("GET %s HTTP/1.1\r\nHost: %s\r\nConnection: close\r\n\r\n", path, host); socket.getOutputStream().write(request.getBytes(StandardCharsets.UTF_8)); socket.getOutputStream().flush(); // 读取全部返回内容(包含不符合规范的HTTP头和XML响应体) String fullContent = new String(is.readAllBytes(), StandardCharsets.UTF_8); // 自行截取XML起始位置即可拿到目标内容 int xmlStartIndex = fullContent.indexOf("<?xml"); String rawXML = xmlStartIndex != -1 ? fullContent.substring(xmlStartIndex) : fullContent; // 后续可自行解析XML System.out.println(rawXML); } } }
注意事项
以上两种方案均跳过了HTTP协议的严格校验,仅适合对接此类不遵循规范的老旧站点,正常业务场景不建议使用,会丢失HTTP协议的错误校验能力。如果返回内容出现乱码,可尝试调整字符集为中欧地区常用的Windows-1250编码测试。
内容的提问来源于stack exchange,提问作者Mayuna
相关产品推荐
相关产品推荐

