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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 03:24:03