問題描述
WSO2 ESB 7.1.0 二進制響應被截斷為 375B (WSO2 ESB 7.1.0 Binary response is truncated to 375B)
我在 WSO2 ESB 7.1.0 中遇到二進制響應問題 ‑ 看起來答案被截斷為 375B(正文部分 ‑ 二進制數據)。
這是我的序列片段 ‑ 響應構建:
<payloadFactory description="Build Payload Response" media‑type="xml">
<format>
<ns:binary xmlns:ns="http://ws.apache.org/commons/ns/payload">BASE64_FILE_CONTENT</ns:binary>
</format>
<args/>
</payloadFactory>
<script language="js"><![CDATA[var binaryNode = mc.getEnvelope().getBody().getFirstElement().getFirstOMChild();
binaryNode.setBinary(true);]]></script>
<propertyGroup description="Set Content‑Type">
<property action="remove" name="TRANSPORT_HEADERS" scope="axis2"/>
<property name="DISABLE_CHUNKING" scope="axis2" type="STRING" value="true"/>
<property name="messageType" scope="axis2" type="STRING" value="application/octet‑stream"/>
<property name="ContentType" scope="axis2" type="STRING" value="application/pdf"/>
</propertyGroup>
<header description="Set Content‑Disposition" name="Content‑Disposition" scope="transport" value="attachment; filename="raport.pdf""/>
當然在BASE64_FILE_CONTENT我把真實的文件內容用BASE64編碼。消息格式化程序配置(我使用 application/octeat‑stream 或 application/pdf ‑> org.wso2.carbon.relay.ExpandingMessageFormatter 具有相同的結果):
<messageFormatters>
<messageFormatter contentType="application/x‑www‑form‑urlencoded" class="org.apache.synapse.commons.formatters.XFormURLEncodedFormatter"/>
<messageFormatter contentType="multipart/form‑data" class="org.apache.axis2.transport.http.MultipartFormDataFormatter"/>
<messageFormatter contentType="application/xml" class="org.apache.axis2.transport.http.ApplicationXMLFormatter"/>
<messageFormatter contentType="text/xml" class="org.apache.axis2.transport.http.SOAPMessageFormatter"/>
<messageFormatter contentType="application/soap+xml" class="org.apache.axis2.transport.http.SOAPMessageFormatter"/>
<messageFormatter contentType="text/plain" class="org.apache.axis2.format.PlainTextFormatter"/>
<messageFormatter contentType="application/json" class="org.wso2.micro.integrator.core.json.JsonStreamFormatter"/>
<messageFormatter contentType="application/json/badgerfish" class="org.apache.axis2.json.JSONBadgerfishMessageFormatter"/>
<messageFormatter contentType="text/javascript" class="org.apache.axis2.json.JSONMessageFormatter"/>
<messageFormatter contentType="application/octet‑stream" class="org.wso2.carbon.relay.ExpandingMessageFormatter"/>
<messageFormatter contentType="application/binary" class="org.apache.axis2.format.BinaryFormatter"/>
<messageFormatter contentType="application/pdf" class="org.wso2.carbon.relay.ExpandingMessageFormatter"/>
</messageFormatters>
我嘗試了一些示例文件和結果始終相同 ‑ 標頭和二進制數據的開頭看起來不錯,但數據在 375B 上被截斷:
這個值 (375B) 是否來自任何參數?誰能建議如何在 WSO2 中正確返回文件(作為響應中的二進制數據)?
最好的問候
Marcin Orliński
參考解法
方法 1:
I have the same issue, funnily enough, the content is cut at the same byte. Took me two days, but I managed to resolve this.
The issue lies deep within WSO2, more specifically in Woodstox parser. Chances are, that you've created XMLInputFactory.properties
in the root WSO2 directory with javax.xml.stream.isCoalescing=false
to enable CDATA usage in PayloadFactory mediator.
With coalescing disabled, Woodstox takes advantage of text buffering. This unfortunately results in multiple child text nodes. If you look at the source code for org.wso2.carbon.relay.ExpandingMessageFormatter
at line 170 (in master branch at the time of writing), you can see, that only first text node is serialized as binary content.
OMNode node = contentEle.getFirstOMChild();
OMText binaryDataNode = (OMText) node;
DataHandler dh = (DataHandler) binaryDataNode.getDataHandler();
...
dh.writeTo(out);
Here is a list of more Woodstox properties. This is the one relevant:
P_MIN_TEXT_SEGMENT (default: 64): when NOT using “coalescing” mode, this setting defines smallest partial text segment (that is, part of one contiguous text segment) that may be reported — intention being to reduce likelihood of returning tiny segments while allowing parser to avoid having to buffer longer segments completely. Setting this value to Integer.MAX_VALUE will effectively prevent splitting of individual segments without forcing coalescing of adjacent segments, so that is one common override
So the solution is fortunately relatively simple, just add com.ctc.wstx.minTextSegment=2147483647
to the XMLInputFactory.properties
.
(by Marcin Orliński、Tomáš Toka Mrázek)