【问题标题】:How to respond application/pdf content from WSO2 ESB如何从 WSO2 ESB 响应应用程序/pdf 内容
【发布时间】:2017-11-20 14:42:44
【问题描述】:

我正在尝试从 wso2 esb rest api 回复 PDFcontent,并希望在浏览器中回复 view。我也为application/pdf 启用了messageFormattermessageBuilder。但是当我从浏览器调用我的 api 时,我在 wso2 esb 中遇到了以下异常。

axis2.xml:

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

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

例外:

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)

API 内容:

<payloadFactory media-type="xml">
                  <format>
                     <soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope">
                        <soapenv:Body>
                           <ns:binary xmlns:ns="http://ws.apache.org/commons/ns/payload">$1</ns:binary>
                        </soapenv:Body>
                     </soapenv:Envelope>
                  </format>
                  <args>
                     <arg evaluator="xml" expression="//*[local-name()='Binary']/text()"/>
                  </args>
               </payloadFactory>
               <property name="NO_ENTITY_BODY" scope="axis2" action="remove"/>
               <property name="ContentType" value="application/pdf" scope="axis2" type="STRING"/>
               <property name="messageType" value="application/pdf" scope="axis2" type="STRING"/>
               <respond/>

我尝试使用在线工具将二进制转换为 pdf,效果很好。

【问题讨论】:

  • 真正想要达到的目标是什么?什么是传入消息?
  • 什么场景?您希望 esb 服务接收带有 pdf 文件的 post http 请求并在 soap 响应中使用 base64 编码内容进行响应?
  • 嗨 simar 感谢您的回复。我的方案是将 db 中的 pdf 文件保存为二进制文件,然后在浏览器中再次检索 pdf 文件作为可读文件。
  • 我确实成功地将 pdf 文件加载到 ESB,但我找不到将其发回的方法
  • 我也卡在同一点上..

标签: wso2 wso2esb synapse


【解决方案1】:

最终找出如何去做。

我在实验中使用 postgres。让我们创建将存储文件内容的表。这很简单。反正有2种情况。文件可能存储为 base64 或 blob(postgres 中的字节)。 我实现了文件在数据库中以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');

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

首先我尝试实现将响应 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

这是我得到的

正如你看到的,我可以打开服务返回的 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 文件。

【讨论】:

  • 感谢 simar 的时间和精力。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-23
  • 1970-01-01
  • 2016-03-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多