WSO2 EI处理HTML响应时出现DOCTYPE不允许异常的解决方法
解决Axis2/Synapse中HTML响应被当作XML解析引发的DOCTYPE异常
你猜的完全没错,这个问题的核心就是:你的服务调用返回了带<!DOCTYPE html>的HTML响应,但Synapse/Axis2默认会把响应当作XML来解析,而Axiom的StAX解析器默认禁止处理DOCTYPE声明,直接触发了javax.xml.stream.XMLStreamException: DOCTYPE is not allowed错误,最终导致AxisFault。
下面是几种针对性的解决方法,按推荐优先级排序:
1. 配置正确的消息构建器(推荐)
如果你的服务确实会返回HTML响应,需要在Axis2的核心配置文件(axis2.xml)中添加HTML对应的消息构建器,让系统用正确的解析器处理这类响应:
<messageBuilder contentType="text/html" class="org.apache.axis2.builder.ApplicationXMLBuilder"/>
也可以使用专门的HTML构建器(如果你的环境中有),这样系统就能准确识别HTML内容,不会再用XML解析器强行处理。
2. 启用纯透传模式(无需解析响应时使用)
如果你的业务不需要解析响应内容,只是要把HTML响应原样返回给调用方,可以在Synapse序列中设置属性,让系统跳过XML解析逻辑,直接透传二进制流:
<sequence name="passthrough-html-sequence" xmlns="http://ws.apache.org/ns/synapse"> <!-- 禁用分块传输,避免解析环节出问题 --> <property name="DISABLE_CHUNKING" value="true" scope="axis2"/> <!-- 设置消息类型为二进制流,告诉系统不要解析内容 --> <property name="messageType" value="application/octet-stream" scope="axis2"/> <send/> </sequence>
这种方法简单直接,完全绕开XML解析步骤,自然也就不会遇到DOCTYPE的限制。
3. 允许DOCTYPE声明(不推荐,存在安全风险)
如果必须解析带DOCTYPE的内容,可以通过设置系统属性来放开Axiom的限制,但这会引入XXE(XML外部实体注入)的安全风险,仅在完全信任服务端响应的场景下使用:
# 启动服务时添加JVM参数 -Dorg.apache.axiom.disallowDoctypeDecl=false
或者在代码中动态设置:
System.setProperty("org.apache.axiom.disallowDoctypeDecl", "false");
你遇到的完整异常栈
org.apache.axis2.AxisFault: Error while building Passthrough stream at org.apache.synapse.transport.passthru.util.RelayUtils.handleException(RelayUtils.java:384) at org.apache.synapse.transport.passthru.util.RelayUtils.builldMessage(RelayUtils.java:196) at org.apache.synapse.transport.passthru.util.RelayUtils.buildMessage(RelayUtils.java:113) at org.apache.synapse.mediators.AbstractListMediator.buildMessage(AbstractListMediator.java:145) at org.apache.synapse.mediators.AbstractListMediator.mediate(AbstractListMediator.java:94) at org.apache.synapse.mediators.base.SequenceMediator.mediate(SequenceMediator.java:260) at org.apache.synapse.core.axis2.Axis2SynapseEnvironment.mediateFromContinuationStateStack(Axis2SynapseEnvironment.java:774) at org.apache.synapse.core.axis2.Axis2SynapseEnvironment.injectMessage(Axis2SynapseEnvironment.java:281) at org.apache.synapse.core.axis2.SynapseCallbackReceiver.handleMessage(SynapseCallbackReceiver.java:570) at org.apache.synapse.core.axis2.SynapseCallbackReceiver.receive(SynapseCallbackReceiver.java:193) at org.apache.axis2.engine.AxisEngine.receive(AxisEngine.java:180) at org.apache.synapse.transport.passthru.ClientWorker.run(ClientWorker.java:263) at org.apache.axis2.transport.base.threads.NativeWorkerPool$1.run(NativeWorkerPool.java:172) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:748) Caused by: org.apache.axiom.om.OMException: javax.xml.stream.XMLStreamException: DOCTYPE is not allowed at org.apache.axiom.om.impl.builder.StAXOMBuilder.next(StAXOMBuilder.java:296) at org.apache.axiom.om.impl.llom.OMDocumentImpl.getOMDocumentElement(OMDocumentImpl.java:109) at org.apache.axiom.om.impl.builder.StAXOMBuilder.getDocumentElement(StAXOMBuilder.java:570) at org.apache.axiom.om.impl.builder.StAXOMBuilder.getDocumentElement(StAXOMBuilder.java:566) at org.apache.synapse.transport.passthru.util.DeferredMessageBuilder.getDocument(DeferredMessageBuilder.java:165) at org.apache.synapse.transport.passthru.util.RelayUtils.builldMessage(RelayUtils.java:160) ... 14 more Caused by: javax.xml.stream.XMLStreamException: DOCTYPE is not allowed at org.apache.axiom.util.stax.dialect.DisallowDoctypeDeclStreamReaderWrapper.next(DisallowDoctypeDeclStreamReaderWrapper.java:36) at org.apache.axiom.om.impl.builder.StAXOMBuilder.parserNext(StAXOMBuilder.java:681) at org.apache.axiom.om.impl.builder.StAXOMBuilder.next(StAXOMBuilder.java:214) ... 19 more
内容的提问来源于stack exchange,提问作者ashok
相关产品推荐
相关产品推荐

