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

Java跨版本XML序列化:Castor非ASCII字符解析报错问题

问题:跨版本Java应用SOAP通信中非ASCII字符解析错误

我有两个需协同工作的应用:一个是自行开发的Java 17应用,另一个是管控权限有限的Java 8应用。

Java 17应用需将POJO序列化为XML,通过SOAP发送至Java 8应用;Java 8应用接收XML后,用Castor反序列化为POJO并处理。

但遇到非ASCII字符时流程出错,已确保双方编码为UTF-8,Java 17端使用Jakarta/JAXB序列化,代码如下:

JAXBContext context = JAXBContext.newInstance(PojoClass.class);
Marshaller marshaller = context.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_ENCODING, "utf-8");
marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, false);
//marshaller.setProperty("org.glassfish.jaxb.characterEscapeHandler", new NonAsciiEscapeHandler());
StringWriter sw = new StringWriter();
marshaller.marshal(pojoClassInstance, sw);
return sw.toString();

我曾尝试添加字符转义处理器,将非ASCII字符转为十六进制值,按理解此形式无需实体声明。

但Java 8应用中,Castor反序列化后Breeze解析XML时,com.tbf.xml.XmlObjectFactory报错:"The entity 'Otilde' was referenced, but not declared."。我明明发送的是十六进制值或UTF-8字符,为何会转为未声明实体?

请求解决以下任一问题:

  1. 让Castor接受UTF-8或十六进制值,不报未声明实体错误;
  2. 让JAXB生成带实体声明的XML。

补充信息

启用NonAsciiCharacterHandler后生成的XML示例:

<PostalAddr>
    <AddrLine1>&#xd5;888 Sample Rd.</AddrLine1>
    <AddrLine2>&#xc8;021 Apartment 55</AddrLine2>
    <CityNm>&#xf3;Doyle</CityNm>
    <PostalZIPCd>99999</PostalZIPCd>
    <StateProvCd>AK</StateProvCd>
</PostalAddr>

Apache HttpClient发送代码:

try(CloseableHttpClient client = HttpClients.createDefault()) {
            HttpPost httpPost = new HttpPost(url);
            HttpEntity entity = new StringEntity(xmlMessage, StandardCharsets.UTF_8);
            httpPost.setEntity(entity);
            httpPost.setHeader("Content-type", "application/soap+xml");
            httpPost.setHeader("Accept", "application/soap+xml");
            httpPost.addHeader("Accept-Charset", "utf-8");
            httpPost.setHeader("SOAPAction", "SOAP");

            CloseableHttpResponse response = client.execute(httpPost);
}

Java 17端提取HttpEntity内容后XML显示:

<PostalAddr>
    <AddrLine1>Õ888 Sample Rd.</AddrLine1>
    <AddrLine2>È021 Apartment 55</AddrLine2>
    <CityNm>óDoyle</CityNm>
    <PostalZIPCd>99999</PostalZIPCd>
    <StateProvCd>AK</StateProvCd>
</PostalAddr>

Castor反序列化后XML变为:

<PostalAddr>
    <AddrLine1>&Otilde;888 Sample Rd.</AddrLine1>
    <AddrLine2>&Egrave;021 Apartment 55</AddrLine2>
    <CityNm>&oacute;Doyle</CityNm>
    <PostalZIPCd>99999</PostalZIPCd>
    <StateProvCd>AK</StateProvCd>
</PostalAddr>

这导致Breeze解析出错,我认为Castor反序列化是问题根源,需让其保留十六进制或实际字符。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 08:08:12