我从 CXF 2.7.X 升级到 CXF 3.1.4 并启用了 MTOM(就像在 2.7.x 中一样),客户端中收到的响应仍然包含 Mime 类型信息:
--uuid:cacb0df1-911c-4440-bdf6-e7b6bfcaa5e1
Content-Type: text/xml; charset=UTF-8
Content-Transfer-Encoding: binary
Content-ID: <root.message@cxf.apache.org>
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/ ......
因此 XML 解析器 ( ValidatingStreamReader
) 抱怨存在非法字符。
如果我禁用,MTOM 它工作得很好(Spring 配置):
<entry key="mtom-enabled" value="false"/>
如果我不发送 MTOM,对方显然不会发回 MTOM 消息。
笔记:
我使用 CXF
WSS4JStaxOutInterceptor
和WSS4JStaxInInterceptor
拦截器对消息进行签名(请参阅下面的 Spring 配置)。我将
http:conduit
受信任的密钥库用于 https 流量。请参阅下面的 CXF Spring 配置。
知道如何配置 CXF 以便在我的情况下启用 MTOM,或者是什么导致升级后出现此 mime 类型信息?
<jaxws:client id="preProductionAanleveren" serviceClass="com.company.Service” address="${pre.production.url.delivery}">
<jaxws:inInterceptors>
<ref bean="preProductionSigningInterceptorIn"/>
<ref bean="preProductionWsaSignaturePartsInterceptor"/>
</jaxws:inInterceptors>
<jaxws:outInterceptors>
<ref bean="preProductionSigningInterceptorOut"/>
<ref bean="preProductionWsaSignaturePartsInterceptor"/>
</jaxws:outInterceptors>
<jaxws:properties>
<entry key="mtom-enabled" value="false"/>
<entry key="signatureParts" value="{Element}{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd}Timestamp;
{Element}{http://schemas.xmlsoap.org/soap/envelope/}Body"/>
</jaxws:properties>
</jaxws:client>
<!-- It will dynamically set the WSA signing parts if required, depending if they contain any value. See: http://davidvaleri.wordpress.com/2010/09/15/signing-ws-addressing-headers-in-apache-cxf/ -->
<bean id="preProductionWsaSignaturePartsInterceptor" class="com.company.StaxDynamicWsaSignaturePartsInterceptor"/>
<bean id="preProductionSigningInterceptorOut" class="org.apache.cxf.ws.security.wss4j.WSS4JStaxOutInterceptor">
<constructor-arg>
<map>
<entry key="action" value="Timestamp Signature"/>
<entry key="timeToLive" value="300" />
<entry key="user" value="${pre.production.keystore.private.sign.key.alias}"/>
<entry key="passwordCallbackRef" value-ref="preProductionPwdCallback"/>
<entry key="signatureKeyIdentifier" value="DirectReference" />
<bean id="preProductionSigningInterceptorIn" class="org.apache.cxf.ws.security.wss4j.WSS4JStaxInInterceptor">
<constructor-arg>
<map>
<entry key="action" value="Timestamp Signature"/>
<entry key="signaturePropRefId" value="cryptoProperties"/>
<entry key="cryptoProperties" value-ref="preProductionCryptoProperties"/>
</map>
</constructor-arg>
</bean>
<bean id="preProductionPwdCallback" class="com.company.ClientKeystorePasswordCallback">
<property name="passwords">
<util:map key-type="java.lang.String" value-type="java.lang.String">
<entry key="${pre.production.keystore.private.sign.key.alias}" value="${pre.production.keystore.private.sign.key.pwd}"/>
</util:map>
</property>
</bean>
<util:properties id="preProductionCryptoProperties">
<prop key="org.apache.wss4j.crypto.merlin.keystore.file">${pre.production.keystore.private}</prop>
<prop key="org.apache.wss4j.crypto.merlin.keystore.password">${pre.production.keystore.private.pwd}</prop>
<prop key="org.apache.wss4j.crypto.merlin.truststore.file">${pre.production.keystore.trusted}</prop>
<prop key="org.apache.wss4j.crypto.merlin.truststore.password">${pre.production.keystore.trusted.pwd}</prop>
</util:properties>