如何回应WSO2 ESB中的application / pdf内容

时间:2017-06-18 07:24:47

标签: wso2 wso2esb synapse

我正在尝试回复来自wso2 esb PDF的{​​{1}}内容,并希望在浏览器中rest api。我也为view启用了messageFormattermessageBuilder。但是当我从浏览器调用我的api时,我在wso2 esb中得到了例外。

axis2.xml:

application/pdf

例外:

<messageBuilder contentType="application/pdf" class="org.wso2.carbon.relay.BinaryRelayBuilder"/>

<messageFormatter contentType="application/pdf" class="org.wso2.carbon.relay.ExpandingMessageFormatter"/>

API内容:

ERROR {org.apache.synapse.transport.passthru.PassThroughHttpSender} -  Failed to submit the response {org.apache.synapse.transport.passthru.PassThroughHttpSender}
java.lang.RuntimeException: ContentID is null
    at org.apache.axiom.om.impl.llom.OMTextImpl.getDataHandler(OMTextImpl.java:381)
    at org.wso2.carbon.relay.ExpandingMessageFormatter.findAndWrite2OutputStream(ExpandingMessageFormatter.java:179)
    at org.wso2.carbon.relay.ExpandingMessageFormatter.writeTo(ExpandingMessageFormatter.java:97)
    at org.apache.synapse.transport.passthru.PassThroughHttpSender.submitResponse(PassThroughHttpSender.java:573)
    at org.apache.synapse.transport.passthru.PassThroughHttpSender.invoke(PassThroughHttpSender.java:264)
    at org.apache.axis2.engine.AxisEngine.send(AxisEngine.java:442)
    at org.apache.synapse.core.axis2.Axis2Sender.sendBack(Axis2Sender.java:230)
    at org.apache.synapse.core.axis2.Axis2SynapseEnvironment.send(Axis2SynapseEnvironment.java:531)
    at org.apache.synapse.mediators.builtin.SendMediator.mediate(SendMediator.java:118)
    at org.apache.synapse.mediators.AbstractListMediator.mediate(AbstractListMediator.java:97)
    at org.apache.synapse.mediators.AbstractListMediator.mediate(AbstractListMediator.java:59)
    at org.apache.synapse.mediators.base.SequenceMediator.mediate(SequenceMediator.java:158)
    at org.apache.synapse.rest.Resource.process(Resource.java:343)
    at org.apache.synapse.rest.API.process(API.java:338)
    at org.apache.synapse.rest.RESTRequestHandler.apiProcess(RESTRequestHandler.java:123)
    at org.apache.synapse.rest.RESTRequestHandler.dispatchToAPI(RESTRequestHandler.java:101)
    at org.apache.synapse.rest.RESTRequestHandler.process(RESTRequestHandler.java:56)
    at org.apache.synapse.core.axis2.Axis2SynapseEnvironment.injectMessage(Axis2SynapseEnvironment.java:304)
    at org.apache.synapse.mediators.builtin.LoopBackMediator.mediate(LoopBackMediator.java:63)
    at org.apache.synapse.mediators.AbstractListMediator.mediate(AbstractListMediator.java:97)
    at org.apache.synapse.mediators.AbstractListMediator.mediate(AbstractListMediator.java:59)
    at org.apache.synapse.config.xml.AnonymousListMediator.mediate(AnonymousListMediator.java:37)
    at org.apache.synapse.config.xml.SwitchCase.mediate(SwitchCase.java:69)
    at org.apache.synapse.mediators.filters.SwitchMediator.mediate(SwitchMediator.java:148)
    at org.apache.synapse.mediators.AbstractListMediator.mediate(AbstractListMediator.java:97)
    at org.apache.synapse.mediators.base.SequenceMediator.mediate(SequenceMediator.java:260)
    at org.apache.synapse.core.axis2.Axis2SynapseEnvironment.mediateFromContinuationStateStack(Axis2SynapseEnvironment.java:775)
    at org.apache.synapse.core.axis2.Axis2SynapseEnvironment.injectMessage(Axis2SynapseEnvironment.java:282)
    at org.apache.synapse.core.axis2.SynapseCallbackReceiver.handleMessage(SynapseCallbackReceiver.java:554)
    at org.apache.synapse.core.axis2.SynapseCallbackReceiver.receive(SynapseCallbackReceiver.java:188)
    at org.apache.axis2.engine.AxisEngine.receive(AxisEngine.java:180)
    at org.apache.synapse.transport.passthru.ClientWorker.run(ClientWorker.java:262)
    at org.apache.axis2.transport.base.threads.NativeWorkerPool$1.run(NativeWorkerPool.java:172)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
Unexpected error sending message back {org.apache.synapse.core.axis2.Axis2Sender}
org.apache.axis2.AxisFault: Failed to submit the response
    at org.apache.synapse.transport.passthru.PassThroughHttpSender.handleException(PassThroughHttpSender.java:632)
    at org.apache.synapse.transport.passthru.PassThroughHttpSender.invoke(PassThroughHttpSender.java:266)
    at org.apache.axis2.engine.AxisEngine.send(AxisEngine.java:442)
    at org.apache.synapse.core.axis2.Axis2Sender.sendBack(Axis2Sender.java:230)
    at org.apache.synapse.core.axis2.Axis2SynapseEnvironment.send(Axis2SynapseEnvironment.java:531)
    at org.apache.synapse.mediators.builtin.SendMediator.mediate(SendMediator.java:118)
    at org.apache.synapse.mediators.AbstractListMediator.mediate(AbstractListMediator.java:97)
    at org.apache.synapse.mediators.AbstractListMediator.mediate(AbstractListMediator.java:59)
    at org.apache.synapse.mediators.base.SequenceMediator.mediate(SequenceMediator.java:158)
    at org.apache.synapse.rest.Resource.process(Resource.java:343)
    at org.apache.synapse.rest.API.process(API.java:338)
    at org.apache.synapse.rest.RESTRequestHandler.apiProcess(RESTRequestHandler.java:123)
    at org.apache.synapse.rest.RESTRequestHandler.dispatchToAPI(RESTRequestHandler.java:101)
    at org.apache.synapse.rest.RESTRequestHandler.process(RESTRequestHandler.java:56)
    at org.apache.synapse.core.axis2.Axis2SynapseEnvironment.injectMessage(Axis2SynapseEnvironment.java:304)
    at org.apache.synapse.mediators.builtin.LoopBackMediator.mediate(LoopBackMediator.java:63)
    at org.apache.synapse.mediators.AbstractListMediator.mediate(AbstractListMediator.java:97)
    at org.apache.synapse.mediators.AbstractListMediator.mediate(AbstractListMediator.java:59)
    at org.apache.synapse.config.xml.AnonymousListMediator.mediate(AnonymousListMediator.java:37)
    at org.apache.synapse.config.xml.SwitchCase.mediate(SwitchCase.java:69)
    at org.apache.synapse.mediators.filters.SwitchMediator.mediate(SwitchMediator.java:148)
    at org.apache.synapse.mediators.AbstractListMediator.mediate(AbstractListMediator.java:97)
    at org.apache.synapse.mediators.base.SequenceMediator.mediate(SequenceMediator.java:260)
    at org.apache.synapse.core.axis2.Axis2SynapseEnvironment.mediateFromContinuationStateStack(Axis2SynapseEnvironment.java:775)
    at org.apache.synapse.core.axis2.Axis2SynapseEnvironment.injectMessage(Axis2SynapseEnvironment.java:282)
    at org.apache.synapse.core.axis2.SynapseCallbackReceiver.handleMessage(SynapseCallbackReceiver.java:554)
    at org.apache.synapse.core.axis2.SynapseCallbackReceiver.receive(SynapseCallbackReceiver.java:188)
    at org.apache.axis2.engine.AxisEngine.receive(AxisEngine.java:180)
    at org.apache.synapse.transport.passthru.ClientWorker.run(ClientWorker.java:262)
    at org.apache.axis2.transport.base.threads.NativeWorkerPool$1.run(NativeWorkerPool.java:172)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

我尝试使用在线工具将二进制文件转换为pdf,并且工作正常。

1 个答案:

答案 0 :(得分:2)

最终了解如何做到这一点。

我在实验中使用了postgres。让我们创建一个存储文件内容的表。这很简单。无论如何有2个案例。文件可能存储为base64或blob(postgres中的bytea)。 当文件以base64格式存储在数据库中时,我实现了大小写。

drop table if exists pdf_files ;
create table pdf_files(
     id serial primary key, 
     file_name text, 
     pdf_base64 text, 
     pdf_binary bytea
 );

以base64格式将数据文件内容插入表中。 base64格式的文件可以在这里在线转换或任何其他在线工具 http://www.motobit.com/util/base64-decoder-encoder.asp

insert into pdf_files(file_name, pdf_base64)
values('title.pdf',   'JVBERi0x.....................NjMKJSVFT0YK');

现在让我们填充二进制字段

update pdf_files set pdf_binary = decode(pdf_base64, 'base64');

我在数据库中得到了这个:

Table content

首先,我尝试实施肥皂服务,这将响应pdf。 有我做的服务:

<proxy xmlns="http://ws.apache.org/ns/synapse" name="Sample" startOnLoad="true" statistics="disable" trace="disable" transports="http,https">
    <target>
        <inSequence>
            <dblookup>
                <connection>
                    <pool>
                        <dsName>pgConn</dsName>
                    </pool>
                </connection>
                <statement>
                    <sql>select pdf_base64 from pdf_files where id = ?</sql>
                    <parameter xmlns:nb="http://mru" expression="//nb:id" type="INTEGER"/>
                    <result column="pdf_base64" name="pdf_base64"/>
                </statement>
            </dblookup>
            <payloadFactory media-type="xml">
                <format>
                    <ns:binary xmlns:ns="http://ws.apache.org/commons/ns/payload">$1</ns:binary>
                </format>
                <args>
                    <arg evaluator="xml" expression="get-property('pdf_base64')"/>
                </args>
            </payloadFactory>
            <loopback/>
        </inSequence>
        <outSequence>
            <script language="js">
            var binaryNode = mc.getEnvelope().getBody().getFirstElement().getFirstOMChild();  
            binaryNode.setBinary(true);
            </script>
            <property name="messageType" scope="axis2" type="STRING" value="application/pdf"/>
            <respond/>
        </outSequence>
    </target>
    <description/>
</proxy>

它接受带有标签id的请求,该标识id是指表id(主键)

<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:nb="http://mru">
    <soap:Body>
        <nb:id>1</nb:id>
    </soap:Body>
</soap:Envelope>

让我们使用curl发出请求(我假设请求保存在文件request.xml中)

curl -v -X POST -H "Content-Type:text/xml" -d @./request.xml http://localhost:8280/services/Sample.SampleHttpSoap12Endpoint > title1.pdf

这就是我得到的

Curl request to soap service

如您所见,我可以打开服务返回的pdf文件。

现在API也一样。它实际上很简单,几乎一样。只需要配置url-template来捕获sql查询的参数id。

 <api xmlns="http://ws.apache.org/ns/synapse" name="GetPdf" context="/pdf">
    <resource methods="GET" uri-template="/id/{fileId}">
      <inSequence>
         <property name="ID" expression="get-property('uri.var.fileId')"/>
         <dblookup>
            <connection><pool><dsName>pgConn</dsName></pool></connection>
            <statement>
               <sql>select pdf_base64 from pdf_files where id = ?</sql>
               <parameter expression="get-property('ID')" type="INTEGER"/>
               <result name="pdf_base64" column="pdf_base64"/>
            </statement>
         </dblookup>
         <payloadFactory media-type="xml">
            <format>
               <ns:binary xmlns:ns="http://ws.apache.org/commons/ns/payload">$1</ns:binary>
            </format>
            <args>
               <arg evaluator="xml" expression="get-property('pdf_base64')"/>
            </args>
         </payloadFactory>
         <loopback/>
      </inSequence>
      <outSequence>
         <script language="js">
             var binaryNode = mc.getEnvelope().getBody().getFirstElement().getFirstOMChild();     
             binaryNode.setBinary(true);
         </script>
         <property name="messageType" value="application/pdf" scope="axis2" type="STRING"/>
         <respond/>
      </outSequence>
   </resource>
</api>

此api将使用适当的Content-Type标头返回PDF文件,以便浏览器理解它。

图片在下面。浏览器通过内容类型标题正确识别内容,并使用内置的pdf渲染器显示wsoesb服务器提供的pdf文件。

PDF File opened in browser