wso2 - WSO2 ESB/EI - Pass JSON body from API to DataService
问题描述
I'm trying to set up an API in Integrator that targets a DataService. I've gotten the GET routes setup, but not the PUT route.
The API accepts a large JSON string, which I pass into the API via the body of the request. It seems that I couldn't have the DataService directly get the data from the body, it looks like it HAS to be a query parameter. That's annoying, but I can deal with it, so I attempted to send the large JSON string as a query parameter to the DataService.
I couldn't figure out how to send the data as a JSON string. I can send it easily enough as XML, but the DataService is complaining that it's not receiving a string.
So, how do I send this as a JSON string? Even better - is there a way to get the DataService to accept a body payload instead of exclusively query parameters?
I'm also working with Eclipse and json-eval doesn't seem to work, so I've been avoiding it. Hoping that's not part of the problem.
json-eval(.)
Save Failed
com.jayway.jsonpath.JsonPath.compile(Ljava/lang/String;[Lcom/jayway/jsonpath/Predicate;)Lcom/jayway/jsonpath/JsonPath;
My current API resource in Integrator:
<?xml version="1.0" encoding="UTF-8"?>
<sequence name="orders.put.IN" trace="disable" xmlns="http://ws.apache.org/ns/synapse">
<property expression="get-property('query.param.ID')" name="uri.var.id"/>
<property expression="json-eval($.)" name="uri.var.full_data"/>
<property value="1" name="uri.var.last_updated_by"/>
<log level="custom">
<property name="MESSAGE" value="Executing orders.put.IN sequence"/>
<property expression="get-property('uri.var.id')" name="ID"/>
<property expression="get-property('uri.var.full_data')" name="FULL_DATA"/>
<property expression="get-property('uri.var.last_updated_by')" name="LAST_UPDATED_BY"/>
</log>
<property name="messageType" scope="axis2" type="STRING" value="application/json"/>
<property name="Content-Type" scope="transport" type="STRING" value="application/json"/>
<send>
<endpoint name="orders.put.byuserid">
<http method="put" statistics="enable" trace="enable"
uri-template="https://________:8243/services/ORDERS_DataService/{uri.var.id}?LAST_UPDATED_BY={uri.var.last_updated_by}&FULL_DATA={uri.var.full_data}"/>
</endpoint>
</send>
</sequence>
My current DataService:
<data description="____.ORDERS" disableLegacyBoxcarringMode="false" enableBatchRequests="false" enableBoxcarring="false" name="ORDERS_DataService" serviceNamespace="____" serviceStatus="active" transports="http https">
<config enableOData="false" id="default">
<property name="carbon_datasource_name">____</property>
</config>
<query id="update_ORDERS_query" useConfig="default">
<sql>UPDATE ____.ORDERS SET FULL_DATA=?, LAST_UPADTE_DATE=SYSDATE, LAST_UPDATED_BY=? WHERE ID=?</sql>
<param name="FULL_DATA" ordinal="1" sqlType="STRING"/>
<param name="LAST_UPDATED_BY" ordinal="2" sqlType="STRING" />
<param name="ID" ordinal="3" sqlType="STRING"/>
</query>
<resource method="PUT" path="/{ID}">
<call-query href="update_ORDERS_query">
<with-param name="FULL_DATA" query-param="FULL_DATA" />
<with-param name="LAST_UPDATED_BY" query-param="LAST_UPDATED_BY" />
<with-param name="ID" query-param="ID" />
</call-query>
</resource>
</data>
Full error:
java.lang.IllegalArgumentException: Value type miss match, Expected value type - '', but found - 'STRING'
at org.apache.axis2.json.gson.GsonXMLStreamReader.nextValue(GsonXMLStreamReader.java:750)
at org.apache.axis2.json.gson.GsonXMLStreamReader.readValue(GsonXMLStreamReader.java:625)
at org.apache.axis2.json.gson.GsonXMLStreamReader.stateTransition(GsonXMLStreamReader.java:531)
at org.apache.axis2.json.gson.GsonXMLStreamReader.next(GsonXMLStreamReader.java:177)
at org.apache.axiom.om.impl.builder.StAXOMBuilder.parserNext(StAXOMBuilder.java:681)
at org.apache.axiom.om.impl.builder.StAXOMBuilder.next(StAXOMBuilder.java:214)
at org.apache.axiom.om.impl.llom.OMSerializableImpl.build(OMSerializableImpl.java:78)
at org.apache.axiom.om.impl.llom.OMElementImpl.build(OMElementImpl.java:722)
at org.apache.axiom.om.impl.llom.OMElementImpl.detach(OMElementImpl.java:700)
at org.apache.axiom.om.impl.llom.OMNodeImpl.setParent(OMNodeImpl.java:105)
at org.apache.axiom.om.impl.llom.OMElementImpl.addChild(OMElementImpl.java:296)
at org.apache.axiom.om.impl.llom.OMElementImpl.addChild(OMElementImpl.java:212)
at org.apache.axiom.soap.impl.llom.SOAPBodyImpl.addChild(SOAPBodyImpl.java:231)
at org.apache.axis2.json.gson.JSONMessageHandler.invoke(JSONMessageHandler.java:84)
at org.apache.axis2.engine.Phase.invokeHandler(Phase.java:340)
at org.apache.axis2.engine.Phase.invoke(Phase.java:313)
at org.apache.axis2.engine.AxisEngine.invoke(AxisEngine.java:261)
at org.apache.axis2.engine.AxisEngine.receive(AxisEngine.java:167)
at org.apache.synapse.transport.passthru.ServerWorker.processNonEntityEnclosingRESTHandler(ServerWorker.java:338)
at org.apache.synapse.transport.passthru.ServerWorker.processEntityEnclosingRequest(ServerWorker.java:383)
at org.apache.synapse.transport.passthru.ServerWorker.run(ServerWorker.java:152)
at org.apache.axis2.transport.base.threads.NativeWorkerPool$1.run(NativeWorkerPool.java:172)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
解决方案
Found the answer myself. Need to enrich the sequence and clone the body, apparently.
<enrich description="Get Body Payload from original REST request">
<source clone="true" type="body"/>
<target property="payload" type="property"/>
</enrich>
From there it can be used as the property named "payload"
<arg evaluator="xml" expression="get-property('payload')"/>
推荐阅读
- c - 递归计算标准差
- mysql - 查询错误结果 JPA Spring Boot
- c++ - 如何重新着色二进制图像中的形状以进行索引(填充)?
- java - 寻求有关使用 DAWG 实现文字游戏的建议
- mysql - mysql从3个表中更新列值
- pyspark - PySpark 应用程序中的 Hive 查询
- javascript - 无法使用 indexof 函数获取值
- python - 在 Python matplotlib 中设置 boxplot 'boxes' facecolor 透明度
- swiftui - 为什么 SwiftUI Image 添加额外的填充来封闭 VStack?
- php - php artisan optimize NULL.ERROR: Symfony\Component\Debug\Exception\FatalThrowableError: Call to undefined method Illuminate\Foundation\Bootstrap