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字符,为何会转为未声明实体?
请求解决以下任一问题:
- 让Castor接受UTF-8或十六进制值,不报未声明实体错误;
- 让JAXB生成带实体声明的XML。
补充信息
启用NonAsciiCharacterHandler后生成的XML示例:
<PostalAddr> <AddrLine1>Õ888 Sample Rd.</AddrLine1> <AddrLine2>È021 Apartment 55</AddrLine2> <CityNm>ó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>Õ888 Sample Rd.</AddrLine1> <AddrLine2>È021 Apartment 55</AddrLine2> <CityNm>óDoyle</CityNm> <PostalZIPCd>99999</PostalZIPCd> <StateProvCd>AK</StateProvCd> </PostalAddr>
这导致Breeze解析出错,我认为Castor反序列化是问题根源,需让其保留十六进制或实际字符。
内容的提问来源于stack exchange,提问作者S Hornby
相关产品推荐
相关产品推荐

