这是我写的api(based on that simple),即使我们的用例不同,也会向您展示我的问题。
<?xml version="1.0" encoding="UTF-8" ?>
<api context="/services/users" name="ListUsersAPI" xmlns="http://ws.apache.org/ns/synapse">
<resource methods="GET" protocol="http" url-mapping="/*">
<inSequence>
<payloadFactory media-type="json">
<format>{ "persons":{ "person":[ { "Id":"1", "givenName":"ajith", "lastName":"vitharana", "age":"25", "contactInfos":[ { "InfoId":"1", "department":"1", "contactType":"email", "value":"ajith@abc.org" }, { "InfoId":"2", "department":"1", "contactType":"mobile",
"value":"111111111" }, { "InfoId":"3", "department":"1", "contactType":"home", "value":"Magic Dr,USA" } ] }, { "Id":"2", "givenName":"shammi", "lastName":"jagasingha", "age":"30", "contactInfos":[ { "InfoId":"1", "department":"1", "contactType":"email",
"value":"shammi@abc.org" }, { "InfoId":"2", "department":"1", "contactType":"mobile", "value":"2222222222" }, { "InfoId":"3", "department":"1", "contactType":"home", "value":"Magic Dr,USA" } ] } ] }}</format>
<args/>
</payloadFactory>
<property action="remove" name="NO_ENTITY_BODY" scope="axis2" />
<property name="messageType" scope="axis2" type="STRING" value="application/json" />
<respond/>
</inSequence>
<outSequence/>
<faultSequence/>
</resource>
</api>
<?xml version="1.0" encoding="UTF-8" ?>
<api context="/services/roles" name="UserRolesAPI" xmlns="http://ws.apache.org/ns/synapse">
<resource methods="GET" protocol="http" uri-template="/{personid}">
<inSequence>
<filter regex="1" source="get-property('uri.var.personid')">
<then>
<payloadFactory media-type="json">
<format>{ "Id":1, "roles":[ { "roleId":1, "personKey":1, "role":"Deverloper" }, { "roleId":2, "personKey":1, "role":"Engineer" } ]}</format>
<args/>
</payloadFactory>
<property action="remove" name="NO_ENTITY_BODY" scope="axis2" />
<property name="messageType" scope="axis2" type="STRING" value="application/json" />
<respond/>
</then>
<else/>
</filter>
<filter regex="2" source="get-property('uri.var.personid')">
<then>
<payloadFactory media-type="json">
<format>{"personId": 2,"roles": [{ "personRoleId": 1, "personKey": 2, "role": "Manager" },{ "personRoleId": 2, "personKey": 2, "role": "QA" }]}</format>
<args/>
</payloadFactory>
<property action="remove" name="NO_ENTITY_BODY" scope="axis2" />
<property name="messageType" scope="axis2" type="STRING" value="application/json" />
<respond/>
</then>
<else/>
</filter>
</inSequence>
<outSequence/>
<faultSequence/>
</resource>
</api>
<?xml version="1.0" encoding="UTF-8" ?>
<api context="/userdetails" name="UserDetailsAPI" xmlns="http://ws.apache.org/ns/synapse">
<resource methods="GET" protocol="http">
<inSequence>
<call>
<endpoint>
<http method="get" trace="disable" uri-template="http://localhost:8280/services/users" />
</endpoint>
</call>
<iterate attachPath="//jsonObject/persons" expression="//jsonObject/persons/person" id="it1" preservePayload="true" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<target>
<sequence>
<property expression="$body/jsonObject/persons/person/Id" name="uri.var.Id" scope="default" type="STRING" xmlns:ns="http://org.apache.synapse/xsd" />
<property expression="$body//jsonObject//person" name="response1" scope="default" type="STRING" xmlns:ns="http://org.apache.synapse/xsd" />
<call>
<endpoint>
<http method="get" trace="disable" uri-template="http://localhost:8280/services/roles/{uri.var.Id}" />
</endpoint>
</call>
<loopback/>
</sequence>
</target>
</iterate>
</inSequence>
<outSequence>
<send/>
</outSequence>
<faultSequence>
<sequence key="fault" />
</faultSequence>
</resource>
</api>
执行最后一个api(http://localhost:8280/userdetails)导致以下NPE:
20160408T101619.566 org.apache.synapse.transport.passthru.PassThroughHttpSender.handleException(PassThroughHttpSender.java:609) [PassThroughMessageProcessor-14] PassThroughHttpSender - Failed to submit the response
java.lang.NullPointerException
at org.apache.synapse.transport.passthru.util.SourceResponseFactory.create(SourceResponseFactory.java:64)
at org.apache.synapse.transport.passthru.PassThroughHttpSender.submitResponse(PassThroughHttpSender.java:462)
at org.apache.synapse.transport.passthru.PassThroughHttpSender.invoke(PassThroughHttpSender.java:267)
at org.apache.axis2.engine.AxisEngine.send(AxisEngine.java:442)
at org.apache.synapse.core.axis2.Axis2Sender.sendBack(Axis2Sender.java:212)
at org.apache.synapse.core.axis2.Axis2SynapseEnvironment.send(Axis2SynapseEnvironment.java:444)
at org.apache.synapse.mediators.builtin.SendMediator.mediate(SendMediator.java:102)
at org.apache.synapse.mediators.AbstractListMediator.mediate(AbstractListMediator.java:81)
at org.apache.synapse.mediators.AbstractListMediator.mediate(AbstractListMediator.java:48)
at org.apache.synapse.mediators.base.SequenceMediator.mediate(SequenceMediator.java:149)
at org.apache.synapse.rest.Resource.process(Resource.java:297)
at org.apache.synapse.rest.API.process(API.java:335)
at org.apache.synapse.rest.RESTRequestHandler.dispatchToAPI(RESTRequestHandler.java:97)
at org.apache.synapse.rest.RESTRequestHandler.process(RESTRequestHandler.java:52)
at org.apache.synapse.core.axis2.Axis2SynapseEnvironment.injectMessage(Axis2SynapseEnvironment.java:266)
at org.apache.synapse.mediators.builtin.LoopBackMediator.mediate(LoopBackMediator.java:55)
at org.apache.synapse.mediators.AbstractListMediator.mediate(AbstractListMediator.java:81)
at org.apache.synapse.mediators.eip.splitter.IterateMediator.mediate(IterateMediator.java:241)
at org.apache.synapse.mediators.base.SequenceMediator.mediate(SequenceMediator.java:267)
at org.apache.synapse.core.axis2.Axis2SynapseEnvironment.mediateFromContinuationStateStack(Axis2SynapseEnvironment.java:679)
at org.apache.synapse.core.axis2.Axis2SynapseEnvironment.injectMessage(Axis2SynapseEnvironment.java:244)
at org.apache.synapse.core.axis2.SynapseCallbackReceiver.handleMessage(SynapseCallbackReceiver.java:529)
at org.apache.synapse.core.axis2.SynapseCallbackReceiver.receive(SynapseCallbackReceiver.java:172)
at org.apache.axis2.engine.AxisEngine.receive(AxisEngine.java:180)
at org.apache.synapse.transport.passthru.ClientWorker.run(ClientWorker.java:251)
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)
20160408T101619.576 org.apache.synapse.core.axis2.Axis2Sender.handleException(Axis2Sender.java:246) [PassThroughMessageProcessor-14] Axis2Sender - Accept:*/*,Accept-Encoding:gzip, deflate, sdch,Accept-Language:fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4,Cache-Control:no-cache,Content-Type:application/json; charset=UTF-8,Host:localhost:8280,Postman-Token:3bfb96b7-0c31-964e-8c37-3b5dbd222efe,<?xml version='1.0' encoding='utf-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body><jsonObject><Id>1</Id><roles><roleId>1</roleId><personKey>1</personKey><role>Deverloper</role></roles><roles><roleId>2</roleId><personKey>1</personKey><role>Engineer</role></roles></jsonObject></soapenv:Body></soapenv:Envelope> Unexpected error sending message back
org.apache.axis2.AxisFault: Failed to submit the response
at org.apache.synapse.transport.passthru.PassThroughHttpSender.handleException(PassThroughHttpSender.java:610)
at org.apache.synapse.transport.passthru.PassThroughHttpSender.invoke(PassThroughHttpSender.java:269)
at org.apache.axis2.engine.AxisEngine.send(AxisEngine.java:442)
at org.apache.synapse.core.axis2.Axis2Sender.sendBack(Axis2Sender.java:212)
at org.apache.synapse.core.axis2.Axis2SynapseEnvironment.send(Axis2SynapseEnvironment.java:444)
at org.apache.synapse.mediators.builtin.SendMediator.mediate(SendMediator.java:102)
at org.apache.synapse.mediators.AbstractListMediator.mediate(AbstractListMediator.java:81)
at org.apache.synapse.mediators.AbstractListMediator.mediate(AbstractListMediator.java:48)
at org.apache.synapse.mediators.base.SequenceMediator.mediate(SequenceMediator.java:149)
at org.apache.synapse.rest.Resource.process(Resource.java:297)
at org.apache.synapse.rest.API.process(API.java:335)
at org.apache.synapse.rest.RESTRequestHandler.dispatchToAPI(RESTRequestHandler.java:97)
at org.apache.synapse.rest.RESTRequestHandler.process(RESTRequestHandler.java:52)
at org.apache.synapse.core.axis2.Axis2SynapseEnvironment.injectMessage(Axis2SynapseEnvironment.java:266)
at org.apache.synapse.mediators.builtin.LoopBackMediator.mediate(LoopBackMediator.java:55)
at org.apache.synapse.mediators.AbstractListMediator.mediate(AbstractListMediator.java:81)
at org.apache.synapse.mediators.eip.splitter.IterateMediator.mediate(IterateMediator.java:241)
at org.apache.synapse.mediators.base.SequenceMediator.mediate(SequenceMediator.java:267)
at org.apache.synapse.core.axis2.Axis2SynapseEnvironment.mediateFromContinuationStateStack(Axis2SynapseEnvironment.java:679)
at org.apache.synapse.core.axis2.Axis2SynapseEnvironment.injectMessage(Axis2SynapseEnvironment.java:244)
at org.apache.synapse.core.axis2.SynapseCallbackReceiver.handleMessage(SynapseCallbackReceiver.java:529)
at org.apache.synapse.core.axis2.SynapseCallbackReceiver.receive(SynapseCallbackReceiver.java:172)
at org.apache.axis2.engine.AxisEngine.receive(AxisEngine.java:180)
at org.apache.synapse.transport.passthru.ClientWorker.run(ClientWorker.java:251)
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)
Caused by: java.lang.NullPointerException
at org.apache.synapse.transport.passthru.util.SourceResponseFactory.create(SourceResponseFactory.java:64)
at org.apache.synapse.transport.passthru.PassThroughHttpSender.submitResponse(PassThroughHttpSender.java:462)
at org.apache.synapse.transport.passthru.PassThroughHttpSender.invoke(PassThroughHttpSender.java:267)
... 26 more
我担心,这与here相同(但不确定)。 在我们决定放弃wso2之前,请您帮助我快速避免吗? 更好的方法是通过答案修复第三部分(userdetails)。
非常感谢!
答案 0 :(得分:2)
在这种情况下,您的环回在迭代介体内部,并且每次迭代时都调用outSequence。
如果你将loopback mediator从迭代中移出,如下所示,这应该将迭代的最后一个响应发送给客户端。如果要聚合迭代中的响应,则应使用aggregate mediator [1] 。
[1] https://docs.wso2.com/display/ESB490/Aggregate+Mediator
<强>更新强>
不幸的是上面的解决方案不起作用,因为每次迭代完成时,流程仍然继续,所以即使我们在迭代之外有一个环回,我们也会多次调用outSequence。我们必须使用聚合才能使用完整条件来触发outSequence一次。请看下面的配置。
<api xmlns="http://ws.apache.org/ns/synapse" name="UserDetailsAPI" context="/userdetails">
<resource methods="GET">
<inSequence>
<call>
<endpoint>
<http trace="disable" method="GET" uri-template="http://localhost:8280/services/users"/>
</endpoint>
</call>
<iterate xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" id="it1" preservePayload="true" attachPath="//jsonObject/persons" expression="//jsonObject/persons/person">
<target>
<sequence>
<property xmlns:ns="http://org.apache.synapse/xsd" name="uri.var.Id" expression="$body/jsonObject/persons/person/Id" scope="default" type="STRING"/>
<property xmlns:ns="http://org.apache.synapse/xsd" name="response1" expression="$body//jsonObject//person" scope="default" type="STRING"/>
<call>
<endpoint>
<http trace="disable" method="GET" uri-template="http://localhost:8280/services/roles/{uri.var.Id}"/>
</endpoint>
</call>
</sequence>
</target>
</iterate>
<aggregate id="it1">
<completeCondition>
<messageCount min="-1" max="-1"/>
</completeCondition>
<onComplete expression="//jsonObject">
<loopback/>
</onComplete>
</aggregate>
</inSequence>
<outSequence>
<send/>
</outSequence>
<faultSequence>
<sequence key="fault"/>
</faultSequence>
</resource>
</api>