2017-06-18 317 views
3

我正試圖在瀏覽器中響應PDF內容來自wso2 esb rest api並且想要view。我也啓用了messageFormattermessageBuilderapplication/pdf。但是,當我從瀏覽器調用我的api時,我在wso2 esb中得到了異常。如何響應來自WSO2的應用程序/ pdf內容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和它工作正常。

+0

實際上試圖存檔的是什麼?什麼是傳入消息? – simar

+0

什麼情況?你想要esb服務接收與PDF文件後的http請求並在soap響應中使用base64編碼內容進行響應? – simar

+0

嗨simar謝謝你的回覆。我的方案是將數據庫中的pdf文件保存爲二進制文件,並在瀏覽器中以可讀文件的形式再次檢索PDF文件。 –

回答

2

找出最終如何去做。

我在我的實驗中使用postgres。讓我們創建將存儲文件內容的表格。這很簡單。無論如何,有2例。文件可能被存儲爲base64或blob(bytea在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'); 

我在數據庫中得到這個:

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(主鍵)要求

<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

+0

感謝simar爲您的時間和精力。 –

相關問題