我正在尝试回复来自wso2 esb PDF
的{{1}}内容,并希望在浏览器中rest api
。我也为view
启用了messageFormatter
和messageBuilder
。但是当我从浏览器调用我的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,并且工作正常。
答案 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');
我在数据库中得到了这个:
首先,我尝试实施肥皂服务,这将响应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文件。