当我通过WSO2 API Manager调用WSO2 ESB中实现的API时,为什么会出现这种奇怪的行为? ("接受:application / json"标题问题)

时间:2018-04-17 14:23:54

标签: wso2 wso2esb wso2-am wso2dss

我是 WSO2 API Manager 中的新手,我在旧的 WSO2 API Manager上注册了一些API(使用 WSO2 ESB 组件实现)时出现以下问题版本1.9.0 )。

问题如下:

我在API管理器上注册API,并在try it工具中生成并执行如下请求:

curl -X GET --header "Accept: application/json" --header "Authorization: Bearer c86b19dac9dfd7406ebe9013373c9de9" "https://api.MY-COMPANY.org/api/dsa2/v1.0.0/market/12?lang=1"

此请求将发送到表示 ESB API实现的端点(我在日志中看到它)。此ESB实现包含一个脚本调解器,它可以对API将返回给用户的JSON对象执行一些操作。

为了清晰起见,我附上了API的代码:

<?xml version="1.0" encoding="UTF-8"?>
<api context="/market" name="market_details" xmlns="http://ws.apache.org/ns/synapse">
    <resource methods="GET" protocol="http" uri-template="/{marketId}?lang={lang_id}">
        <inSequence>
            <log level="full"/>
            <property expression="get-property('uri.var.marketId')" name="marketId" scope="default" type="STRING"/>
            <property expression="get-property('uri.var.lang_id')" name="lang_id" scope="default" type="STRING"/>
            <log level="custom">
                <property expression="$ctx:marketId" name="Market ID"/>
                <property expression="$ctx:lang_id" name="Lang ID"/>
            </log>
            <property name="messageType" scope="axis2" type="STRING" value="application/xml"/>
            <payloadFactory media-type="xml">
                <format>
                    <ds:GetMarketDetails xmlns:ds="http://ws.wso2.org/dataservice">
                        <ds:market_id>$1</ds:market_id>
                        <ds:language_id>$2</ds:language_id>
                    </ds:GetMarketDetails>
                </format>
                <args>
                    <arg evaluator="xml" expression="$ctx:marketId"/>
                    <arg evaluator="xml" expression="$ctx:lang_id"/>
                </args>
            </payloadFactory>
            <header name="Action" scope="default" value="urn:GetMarketDetails"/>
            <call>
                <endpoint key="agrimarketprice_Endpoint"/>
            </call>
            <property name="messageType" scope="axis2" type="STRING" value="application/json"/>
            <property expression="json-eval($.)" name="JSONPayload" scope="default" type="STRING"/>
            <script language="js"><![CDATA[var log = mc.getServiceLog();
                    // Problem is: null values returned from DSS as @nil=true and converted as Object into JSON.
                    // See https://wso2.org/jira/browse/ESBJAVA-4467 as example of bug, reported into JIRA
                    // So, we need convert values, what may be nulls with using this function
                    function checkForNull(value) {
                    if (value instanceof Object && "@nil" in value) {
                        return null;
                    }

                    return value;
                }

                // stange workaround for getting JSON Payload. getPayloadJSON returned null. 
                var pl_string = mc.getProperty("JSONPayload"); 
                log.info("PAYLOAD STRING: " + pl_string);
                var payload = JSON.parse(pl_string);

                // create new response          
                var response = payload.Markets.Market;
                //log.info("RESPONSE: " + JSON.stringify(response));

                //response.id = mc.getProperty("MarketId");

                response.id = mc.getProperty("marketId");

                // convert null values
                response.id = checkForNull(response.id);
                response.regione = checkForNull(response.regione);
                response.province = checkForNull(response.province);
                response.city = checkForNull(response.city);
                response.district = checkForNull(response.district);
                response.town = checkForNull(response.town);
                response.village = checkForNull(response.village);

                if(response.commodities && response.commodities.commoditiesList) {

                    // convert array of commodities into required HATEOS format
                    var commodity = new Array();

                    for (i = 0; i < response.commodities.commoditiesList.length; ++i) {
                        var el = response.commodities.commoditiesList[i];  
                        var newEl = new Object();
                        newEl.commodity_details_id = checkForNull(el.commodity_details_id);
                        newEl.commodity_name_en = checkForNull(el.commodity_name_en);
                        newEl.commodity_name = checkForNull(el.commodity_name);
                        newEl.description = checkForNull(el.description);
                        newEl.image_link = checkForNull(el.image_link);
                        newEl.market_commodity_details_id = checkForNull(el.market_commodity_details_id);
                        newEl.price_series_id = checkForNull(el.price_series_id);
                        newEl.last_price_date = checkForNull(el.last_price_date);
                        newEl.last_avg_price = checkForNull(el.last_avg_price);
                        newEl.currency = checkForNull(el.currency);
                        newEl.measure_unit = checkForNull(el.measure_unit);

                        commodityDetailsLinks = [];

                        commodityDetailsRefObj = {};

                        commodityDetailsRefObj.rel = "commodity_details";
                        commodityDetailsRefObj.href = "http://5.249.148.180:8280/commodity_details/" + checkForNull(el.commodity_details_id);
                        commodityDetailsRefObj.type = "GET";

                        commodityDetailsLinks.push(commodityDetailsRefObj);

                        newEl.links = commodityDetailsLinks;

                        commodity.push(newEl);

                    }

                    response.commodities.commoditiesList = commodity;

                }

                log.info("PROCESSED RESPONSE:");
                //var jsonStr = JSON.stringify(response, null, 2); // spacing level = 2
                //log.info(jsonStr);

                selfLinks = [];

                selfsRefObj = {};

                selfsRefObj.rel = "self";
                selfsRefObj.href = "http://5.249.148.180:8280/market/" + checkForNull(response.id);
                selfsRefObj.type = "GET";

                selfLinks.push(selfsRefObj);

                response.links = selfLinks;

                delete response.id;

                var jsonStr = JSON.stringify(response, null, 2); // spacing level = 2
                log.info("RESPONSE PROCESSED:");
                log.info(jsonStr);


                // put payload back
                mc.setPayloadJSON(response);
                log.info("This is the end");]]></script>
            <property name="RESPONSE" scope="default" type="STRING" value="true"/>
            <header action="remove" name="To" scope="default"/>
            <send/>
        </inSequence>
        <outSequence>
            <send/>
        </outSequence>
        <faultSequence/>
    </resource>
</api>

在JavaScript中介发生了一些非常奇怪的事情。

通过API管理器调用我的API尝试它的工具(重要提示:问题似乎是 - 标题&#34;接受:application / json&#34; 标题):< / p>

curl -X GET --header "Accept: application/json" --header "Authorization: Bearer c86b19dac9dfd7406ebe9013373c9de9" "https://api.MY-COMPANY.org/api/dsa2/v1.0.0/market/12?lang=1"

我将此错误的JSON视为有效负载值的值(我的 pl_string 的值):

{
    "Markets": {
        "Market": [{
                "market_id": 12,
                "market_name": "Kouthiaba",
                "market_description": "Kouthiaba Market",
                "localization_id": "2",
                "long": null,
                "lat": null,
                "country": "Senegal",
                "regione": null,
                "province": null,
                "city": null,
                "district": null,
                "town": null,
                "village": null,
                "commodities": {
                    "commoditiesList": [{
                            "commodity_details_id": 43,
                            "commodity_name_en": "Millet",
                            "commodity_name": "Millet",
                            "description": "Millet",
                            "image_link": "https://firebasestorage.googleapis.com/v0/b/my-company-digital-services-portfolio.appspot.com/o/img%2Ficons%2Fagrimarket%2Fcommodity%2Fmillet.png?alt=media&token=ff9c67ab-e07a-4097-95ae-826fe1aa49ed",
                            "market_commodity_details_id": 178,
                            "price_series_id": 2494,
                            "last_price_date": "2018-03-18+01:00",
                            "last_avg_price": "150.0000",
                            "currency": "XOF",
                            "measure_unit": "kilogram"
                        }, {
                            "commodity_details_id": 13,
                            "commodity_name_en": "Sorghum",
                            "commodity_name": "Sorghum",
                            "description": "Sorghum",
                            "image_link": "https://firebasestorage.googleapis.com/v0/b/my-company-digital-services-portfolio.appspot.com/o/img%2Ficons%2Fagrimarket%2Fcommodity%2Fsorghum.png?alt=media&token=ae33f8e8-50c4-4b8e-868f-1997d50d7ad4",
                            "market_commodity_details_id": 179,
                            "price_series_id": 2495,
                            "last_price_date": "2018-03-18+01:00",
                            "last_avg_price": "160.0000",
                            "currency": "XOF",
                            "measure_unit": "kilogram"
                        }, {
                            "commodity_details_id": 11,
                            "commodity_name_en": "Maize",
                            "commodity_name": "Maize",
                            "description": "Maize is a staple food in many parts of the world, with a total production of 1040M tonnes. However, not all of the maize produced is for human consumption but it is also utilised in bio fuel production. Some of the maize produced is used for corn ethanol, animal feed and other maize products such as corn-starch and corn syrup. Maize for human consumption is used in five different forms 1) Popcorn 2) Flint corn 3) Dent corn 4) Floury corn and 5) Sweet corn.",
                            "image_link": "https://firebasestorage.googleapis.com/v0/b/my-company-digital-services-portfolio.appspot.com/o/img%2Ficons%2Fagrimarket%2Fcommodity%2Fmaize.png?alt=media&token=34d5a149-1721-47e9-863b-c939c7fd7419",
                            "market_commodity_details_id": 180,
                            "price_series_id": 2496,
                            "last_price_date": "2018-03-18+01:00",
                            "last_avg_price": "125.0000",
                            "currency": "XOF",
                            "measure_unit": "kilogram"
                        }, {
                            "commodity_details_id": 38,
                            "commodity_name_en": "Rice Ordinary",
                            "commodity_name": "Rice Ordinary",
                            "description": "Rice Ordinary",
                            "image_link": "https://firebasestorage.googleapis.com/v0/b/my-company-digital-services-portfolio.appspot.com/o/img%2Ficons%2Fagrimarket%2Fcommodity%2Friz.png?alt=media&token=c35e7648-1793-423b-acd2-52d8a1e58c53",
                            "market_commodity_details_id": 181,
                            "price_series_id": 2497,
                            "last_price_date": "2018-03-18+01:00",
                            "last_avg_price": "285.0000",
                            "currency": "XOF",
                            "measure_unit": "kilogram"
                        }, {
                            "commodity_details_id": 39,
                            "commodity_name_en": "Rice Perfumed",
                            "commodity_name": "Rice Perfumed",
                            "description": "Rice Perfumed",
                            "image_link": "https://firebasestorage.googleapis.com/v0/b/my-company-digital-services-portfolio.appspot.com/o/img%2Ficons%2Fagrimarket%2Fcommodity%2Friz.png?alt=media&token=c35e7648-1793-423b-acd2-52d8a1e58c53",
                            "market_commodity_details_id": 182,
                            "price_series_id": 2498,
                            "last_price_date": "2018-03-18+01:00",
                            "last_avg_price": "450.0000",
                            "currency": "XOF",
                            "measure_unit": "kilogram"
                        }, {
                            "commodity_details_id": 40,
                            "commodity_name_en": "Black Eyed Pea",
                            "commodity_name": "Black Eyed Pea",
                            "description": "Black Eyed Pea",
                            "image_link": "https://firebasestorage.googleapis.com/v0/b/my-company-digital-services-portfolio.appspot.com/o/img%2Ficons%2Fagrimarket%2Fcommodity%2Fblack_eyed_pea.png?alt=media&token=ab397785-68da-413a-978b-e0ebab8407b4",
                            "market_commodity_details_id": 183,
                            "price_series_id": 2499,
                            "last_price_date": "2018-03-18+01:00",
                            "last_avg_price": "325.0000",
                            "currency": "XOF",
                            "measure_unit": "kilogram"
                        }, {
                            "commodity_details_id": 42,
                            "commodity_name_en": "Peanut with Shell",
                            "commodity_name": "Peanut with Shell",
                            "description": "Peanut with Shell",
                            "image_link": "https://firebasestorage.googleapis.com/v0/b/my-company-digital-services-portfolio.appspot.com/o/img%2Ficons%2Fagrimarket%2Fcommodity%2Fpeanut.png?alt=media&token=6d5ded68-3126-44df-b429-89fe32483d2d",
                            "market_commodity_details_id": 184,
                            "price_series_id": 2500,
                            "last_price_date": "2018-03-18+01:00",
                            "last_avg_price": "175.0000",
                            "currency": "XOF",
                            "measure_unit": "kilogram"
                        }, {
                            "commodity_details_id": 41,
                            "commodity_name_en": "Peanut without Shell",
                            "commodity_name": "Peanut without Shell",
                            "description": "Peanut without Shell",
                            "image_link": "https://firebasestorage.googleapis.com/v0/b/my-company-digital-services-portfolio.appspot.com/o/img%2Ficons%2Fagrimarket%2Fcommodity%2Fpeanut_open.png?alt=media&token=d5af0a5c-6327-418e-9fac-19d34fcedaf5",
                            "market_commodity_details_id": 185,
                            "price_series_id": 2501,
                            "last_price_date": "2018-03-18+01:00",
                            "last_avg_price": "325.0000",
                            "currency": "XOF",
                            "measure_unit": "kilogram"
                        }
                    ]
                }
            }
        ]
    }
}

这个JSON打破了我的脚本,因为我有:

{
    "Markets": {
        "Market": [
            ..................
         ]
    }
}

(正如预期的那样):

{     &#34;市场&#34;:{         &#34;市场&#34;:{              ................          }      } }

奇怪的是,如果我对我的API管理器执行相同的调用(在我的shell中使用cURL),而不设置 - header&#34; Accept:application / json&#34; 标头,用这种方式:

curl -X GET --header&#34;授权:bearer c86b19dac9dfd7406ebe9013373c9de9&#34; &#34; https://api.MY-COMPANY.org/api/dsa/v1.0.0/market/12?lang=1&#34;

我正在获取正确的JSON并且我的脚本没有被破坏,实际上我的JSON有效负载(我的 pl_string 的值)现在是:

{
    "Markets": {
        "Market": {
            "market_id": 12,
            "market_name": "Kouthiaba",
            "market_description": "Kouthiaba Market",
            "localization_id": 2,
            "long": {
                "@nil": "true"
            },
            "lat": {
                "@nil": "true"
            },
            "country": "Senegal",
            "regione": {
                "@nil": "true"
            },
            "province": {
                "@nil": "true"
            },
            "city": {
                "@nil": "true"
            },
            "district": {
                "@nil": "true"
            },
            "town": {
                "@nil": "true"
            },
            "village": {
                "@nil": "true"
            },
            "commodities": {
                "commoditiesList": [{
                        "commodity_details_id": 43,
                        "commodity_name_en": "Millet",
                        "commodity_name": "Millet",
                        "description": "Millet",
                        "image_link": "https://firebasestorage.googleapis.com/v0/b/my-company-digital-services-portfolio.appspot.com/o/img%2Ficons%2Fagrimarket%2Fcommodity%2Fmillet.png?alt=media&token=ff9c67ab-e07a-4097-95ae-826fe1aa49ed",
                        "market_commodity_details_id": 178,
                        "price_series_id": 2494,
                        "last_price_date": "2018-03-18+01:00",
                        "last_avg_price": 150.0000,
                        "currency": "XOF",
                        "measure_unit": "kilogram"
                    }, {
                        "commodity_details_id": 13,
                        "commodity_name_en": "Sorghum",
                        "commodity_name": "Sorghum",
                        "description": "Sorghum",
                        "image_link": "https://firebasestorage.googleapis.com/v0/b/my-company-digital-services-portfolio.appspot.com/o/img%2Ficons%2Fagrimarket%2Fcommodity%2Fsorghum.png?alt=media&token=ae33f8e8-50c4-4b8e-868f-1997d50d7ad4",
                        "market_commodity_details_id": 179,
                        "price_series_id": 2495,
                        "last_price_date": "2018-03-18+01:00",
                        "last_avg_price": 160.0000,
                        "currency": "XOF",
                        "measure_unit": "kilogram"
                    }, {
                        "commodity_details_id": 11,
                        "commodity_name_en": "Maize",
                        "commodity_name": "Maize",
                        "description": "Maize is a staple food in many parts of the world, with a total production of 1040M tonnes. However, not all of the maize produced is for human consumption but it is also utilised in bio fuel production. Some of the maize produced is used for corn ethanol, animal feed and other maize products such as corn-starch and corn syrup. Maize for human consumption is used in five different forms 1) Popcorn 2) Flint corn 3) Dent corn 4) Floury corn and 5) Sweet corn.",
                        "image_link": "https://firebasestorage.googleapis.com/v0/b/my-company-digital-services-portfolio.appspot.com/o/img%2Ficons%2Fagrimarket%2Fcommodity%2Fmaize.png?alt=media&token=34d5a149-1721-47e9-863b-c939c7fd7419",
                        "market_commodity_details_id": 180,
                        "price_series_id": 2496,
                        "last_price_date": "2018-03-18+01:00",
                        "last_avg_price": 125.0000,
                        "currency": "XOF",
                        "measure_unit": "kilogram"
                    }, {
                        "commodity_details_id": 38,
                        "commodity_name_en": "Rice Ordinary",
                        "commodity_name": "Rice Ordinary",
                        "description": "Rice Ordinary",
                        "image_link": "https://firebasestorage.googleapis.com/v0/b/my-company-digital-services-portfolio.appspot.com/o/img%2Ficons%2Fagrimarket%2Fcommodity%2Friz.png?alt=media&token=c35e7648-1793-423b-acd2-52d8a1e58c53",
                        "market_commodity_details_id": 181,
                        "price_series_id": 2497,
                        "last_price_date": "2018-03-18+01:00",
                        "last_avg_price": 285.0000,
                        "currency": "XOF",
                        "measure_unit": "kilogram"
                    }, {
                        "commodity_details_id": 39,
                        "commodity_name_en": "Rice Perfumed",
                        "commodity_name": "Rice Perfumed",
                        "description": "Rice Perfumed",
                        "image_link": "https://firebasestorage.googleapis.com/v0/b/my-company-digital-services-portfolio.appspot.com/o/img%2Ficons%2Fagrimarket%2Fcommodity%2Friz.png?alt=media&token=c35e7648-1793-423b-acd2-52d8a1e58c53",
                        "market_commodity_details_id": 182,
                        "price_series_id": 2498,
                        "last_price_date": "2018-03-18+01:00",
                        "last_avg_price": 450.0000,
                        "currency": "XOF",
                        "measure_unit": "kilogram"
                    }, {
                        "commodity_details_id": 40,
                        "commodity_name_en": "Black Eyed Pea",
                        "commodity_name": "Black Eyed Pea",
                        "description": "Black Eyed Pea",
                        "image_link": "https://firebasestorage.googleapis.com/v0/b/my-company-digital-services-portfolio.appspot.com/o/img%2Ficons%2Fagrimarket%2Fcommodity%2Fblack_eyed_pea.png?alt=media&token=ab397785-68da-413a-978b-e0ebab8407b4",
                        "market_commodity_details_id": 183,
                        "price_series_id": 2499,
                        "last_price_date": "2018-03-18+01:00",
                        "last_avg_price": 325.0000,
                        "currency": "XOF",
                        "measure_unit": "kilogram"
                    }, {
                        "commodity_details_id": 42,
                        "commodity_name_en": "Peanut with Shell",
                        "commodity_name": "Peanut with Shell",
                        "description": "Peanut with Shell",
                        "image_link": "https://firebasestorage.googleapis.com/v0/b/my-company-digital-services-portfolio.appspot.com/o/img%2Ficons%2Fagrimarket%2Fcommodity%2Fpeanut.png?alt=media&token=6d5ded68-3126-44df-b429-89fe32483d2d",
                        "market_commodity_details_id": 184,
                        "price_series_id": 2500,
                        "last_price_date": "2018-03-18+01:00",
                        "last_avg_price": 175.0000,
                        "currency": "XOF",
                        "measure_unit": "kilogram"
                    }, {
                        "commodity_details_id": 41,
                        "commodity_name_en": "Peanut without Shell",
                        "commodity_name": "Peanut without Shell",
                        "description": "Peanut without Shell",
                        "image_link": "https://firebasestorage.googleapis.com/v0/b/my-company-digital-services-portfolio.appspot.com/o/img%2Ficons%2Fagrimarket%2Fcommodity%2Fpeanut_open.png?alt=media&token=d5af0a5c-6327-418e-9fac-19d34fcedaf5",
                        "market_commodity_details_id": 185,
                        "price_series_id": 2501,
                        "last_price_date": "2018-03-18+01:00",
                        "last_avg_price": 325.0000,
                        "currency": "XOF",
                        "measure_unit": "kilogram"
                    }
                ]
            }
        }
    }
}

这并没有破坏我的剧本。

所以,我的问题是:

1)为什么要将此标题设置为我的调用我的JSON(通过以 JSON 格式转换的 DSS 查询调用的结果获得)是不同的?

2)我可以说 WSO2 API MANAGER 以避免这样设置这个**** - 标题&#34;接受:应用程序/ json&#34; **标题在通话中? 实际上,最好的办法是我的API管理器执行这样的调用:

curl -X GET --header "Authorization: Bearer c86b19dac9dfd7406ebe9013373c9de9" "https://api.MY-COMPANY.org/api/dsa/v1.0.0/market/12?lang=1"

3)目前我的API管理员正在执行此调用:

curl -X GET --header "Accept: application/json" --header "Authorization: Bearer c86b19dac9dfd7406ebe9013373c9de9" "https://api.MY-COMPANY.org/api/dsa/v1.0.0/market/12?lang=1"

我认为这个 - 标题&#34;接受:application / json&#34; 标头会传播到对我的API的 ESB 实现的调用(如果我做错了断言,请纠正我。)

如果我可以在API流程的开头将此标题删除到我的API定义中?可能是个主意吗?

1 个答案:

答案 0 :(得分:0)

  

问题似乎是--header“Accept:application / json”header

我假设您正在从API Store UI中尝试API,其中json响应类型是默认的。您可以在API Publusher的定义中更改默认值(或设置支持的值列表),填写每个资源的响应类型

  

1)为什么要将此标头设置为我的调用我的JSON(通过以JSON格式转换的DSS查询调用的结果获得)是不同的?

我相信DSS使用不同的库(或库版本)将XML转换为JSON。根据我的经验,尽可能避免这种转换(因为XML没有明确包含值类型信息)

你甚至可以在axis2的某处禁用这种自动转换。 xml(用于API,DSS和ESB)

  

2)我可以说WSO2 API MANAGER避免这样设置这个**** - 标题“Accept:application / json”**标题在通话中?实际上,最好的办法是我的API管理器

如前所述,您可以在Publisher中设置默认值或支持的值。设置的响应类型仅由API Store使用,客户端可以发送任何内容..

  

3)目前我的API管理员正在执行此调用:   ... --header“Accept:application / json”标头被传播到我的API的ESB实现的调用(如果我做错了断言,请纠正我)。

传播所有标题(授权除外)