JAXB读取XML报hr标签未匹配闭合的SAXParseException异常
问题原因
你当前的实现存在核心逻辑问题,触发了hr标签解析异常:
你直接将URL对象传入StreamSource构造方法时,JDK底层发起HTTP请求不会携带合法的浏览器标识头,欧洲议会的站点防护策略会拦截这类非正常客户端请求,返回HTML格式的错误拦截页,而非你预期的XML文档。HTML页面中存在不符合XML严格闭合规范的<hr>标签,这就是异常提示中hr标签的来源,和目标地址的正常XML内容无关。
另外你贴出的代码存在笔误:JAXBContextjaxbContext缺少变量类型和变量名之间的空格,会直接触发编译错误,不过这不是运行时解析异常的诱因。
修复方案
按以下步骤调整即可解决异常:
- 不要直接将URL传入
StreamSource,先手动发起HTTP请求,模拟浏览器携带合法User-Agent请求头,拿到真实的XML响应流后再做反序列化。 - 可选增加响应格式校验逻辑:拿到流之后先读取前部分内容,判断如果返回的是HTML内容(包含
<html>、<hr>等标签),说明请求被拦截,方便快速定位问题。
修复后的可运行代码示例(基于JDK11+内置HttpClient,无额外第三方依赖):
import java.net.URI; import java.net.http.HttpClient; import java.net.http.HttpRequest; import java.net.http.HttpResponse; import java.io.InputStream; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBElement; import javax.xml.bind.Unmarshaller; import javax.xml.transform.stream.StreamSource; public class MepsXmlParser { public static void main(String[] args) throws Exception { // 构造带合法请求头的HTTP请求 HttpClient httpClient = HttpClient.newHttpClient(); HttpRequest xmlRequest = HttpRequest.newBuilder() .uri(URI.create("https://www.europarl.europa.eu/meps/en/full-list/xml")) // 模拟常规浏览器的User-Agent,绕过站点拦截 .header("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36") .GET() .build(); // 拉取真实XML响应流 HttpResponse<InputStream> xmlResponse = httpClient.send(xmlRequest, HttpResponse.BodyHandlers.ofInputStream()); try (InputStream xmlStream = xmlResponse.body()) { // 执行JAXB反序列化 JAXBContext jaxbContext = JAXBContext.newInstance(EuropeanParliamentMemberResponse.class); Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller(); JAXBElement<EuropeanParliamentMemberResponse> result = jaxbUnmarshaller.unmarshal( new StreamSource(xmlStream), EuropeanParliamentMemberResponse.class ); // 后续业务逻辑处理result } } }
如果你使用JDK8版本,没有内置HttpClient,可以用HttpURLConnection实现相同的请求头设置逻辑,核心是不要裸传URL给解析器,确保拿到的是真实XML响应再解析。
内容的提问来源于stack exchange,提问作者MEF
相关产品推荐
相关产品推荐

