有一堆遗留的JAX请求代码必须进行扩展,现在包括一个包含“<!CDATA[.]>”封装数据的字段。
我们设法使字段进入请求,但它被发送到服务器,CDATA是XML编码的:
<data><![CDATA[<?xml version=....
<CheckData>
...
</CheckData>
]]></data>
有可用的问题和说明。JAXB Marshalling Unmarshalling with CDATA和https://coderleaf.wordpress.com/2016/11/14/handling-cdata-with-jaxb/),但它们都涉及到直接可用或嵌入到适当的应用服务器环境中的马歇尔。
我们已经创建了一个CdataCharacterEscapeHandler,它将正确地执行CDATA字段的(非)编码,并且当我们在手动创建的Marshaller中使用它时,这也是有效的。
不幸的是,我们的客户端是围绕一个JaxWsProxyFactoryBean代理代码构建的,它隐藏了所有的魔力,并且不管我们尝试了什么,都没有改变它的行为。(这些类是从使用Apache codegen-plugin通过Maven处理的XSD生成的。)
...
JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
LogHandler.configureFactory(factory);
factory.setServiceClass(PaymentCheck.class);
factory.setAddress(serviceUrl);
factory.setUsername(username);
factory.setPassword(password);
Check checkProxy = (Check)factory.create();
CheckResult = checkProxy.check(paramA, paramB);
...
JaxWsProxyFactoryBean隐藏了Marshaller、绑定等的所有创建逻辑,在这些逻辑中我们还没有找到从外部更改/影响的方法,因此似乎使用了默认的CharacterEscapeHandler,它不知道CDATA,并编码所有的值XML样式。
我们找不到如何使用自定义CharacterEscapeHandler或将其注入
是否可以配置/更改JaxWsProxyFactoryBean设置/创建,以便它也使用CDATA感知的CharacterEscapeHandler?
发布于 2022-05-20 08:50:47
虽然我们仍然无法通过大量的调试和反向工程在线找到任何文档或示例,但我们设法找到了解决方案。
可以在创建内部marshaller实例期间使用的JaxWsProxyFactoryBean中提供自定义封送处理程序属性。
这些属性可以作为JAXBDataBinding的一部分提供给工厂。
必须将创建的自定义的实例"com.sun.xml.bind.characterEscapeHandler"
(或"com.sun.xml.bind.marshaller.CharacterEscapeHandler"
也有效)放入JAXBDataBinding的封送器属性"com.sun.xml.bind.characterEscapeHandler"
(或"com.sun.xml.bind.marshaller.CharacterEscapeHandler"
也有效),然后工厂将遵守这些属性。
...
JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
LogHandler.configureFactory(factory);
factory.setServiceClass(PaymentCheck.class);
factory.setAddress(serviceUrl);
factory.setUsername(username);
factory.setPassword(password);
JAXBDataBinding jaxbDataBinding = new JAXBDataBinding();
Map<String, Object> marshallerProperties = new HashMap<>();
marshallerProperties.put("com.sun.xml.bind.characterEscapeHandler", new CdataCharacterEscapeHandler());
jaxbDataBinding.setMarshallerProperties(marshallerProperties);
factory.setDataBinding(jaxbDataBinding);
Check checkProxy = (Check)factory.create();
CheckResult = checkProxy.check(paramA, paramB);
...
使用此解决方案,JaxWsProxyFactoryBean创建的JAX代理客户端最终将正确的请求发送给服务器。
<data><![CDATA[<?xml version=....
<CheckData>
...
</CheckData>
]]></data>
https://stackoverflow.com/questions/72316099
复制相似问题