1

我正在尝试从 plsql 调用 REST Web 服务,使用 POST 方法,并尝试将参数作为查询字符串中的 json 发送。不幸的是,我失败可能是因为我没有正确使用 utl_http(这里是 plsql 新手)。

恐怕我没有正确发送请求并且我没有在查询字符串中提交 json。

实际上,Web 服务的提供者期望这样的东西:BASE URL/postPayment/jsonstring,而恐怕我没有做那件事。

实际上我收到一个 HTTP 405 错误:“请求的资源 () 不允许指定的 HTTP 方法。”

我试图四处搜索,发送 json 的最佳方式是什么(最初我尝试使用 APEX_WEB_SERVICE.MAKE_REST_REQUEST 但返回的结果为空)但似乎我找不到关于我的情况的进一步指导。

有人可以通过在我的情况下指出正确的 uttl_http 使用形式,或者通过在下面指出我的错误来指导我应该如何进行?

create or replace procedure another_way

( 
customerNo        IN   VARCHAR2,  
invoiceNo        IN   VARCHAR2,
agreementNo        IN   VARCHAR2,
instance        IN   VARCHAR2,
paymentRefId        IN   VARCHAR2,
paymentDate        IN   VARCHAR2,
principalAmt        IN   VARCHAR2,
interest        IN   VARCHAR2,
totalAmt        IN   VARCHAR2,
passCode        IN   VARCHAR2,
invoiceType        IN   VARCHAR2,
phoneNo        IN   VARCHAR2

) is

req utl_http.req;
res utl_http.resp;
url varchar2(4000) := 'http://baseurl:7474/mpower/rest/postPayment/';
name varchar2(4000);
buffer varchar2(4000); 
content varchar2(4000) := '{"customerNo":"'||customerNo||'","invoiceNo":"'||invoiceNo||'","agreementNo":"","instance":"'||instance||'","paymentRefId":"'||paymentRefId||'","paymentDate":"'||paymentDate||'","principalAmt":'||principalAmt||',"interest":'||interest||',"totalAmt":'||totalAmt||',"passCode":"'||passCode||'","invoiceType":"'||invoiceType||'","phoneNo":"'||phoneNo||'"}';

begin

   /* just to indicate it started */
    dbms_output.put_line('START'); 

    /* to check if your JSON content is okay and has correct values */
    dbms_output.put_line(content); 

dbms_output.put_line(url||content);


req := utl_http.begin_request(url||content, 'POST',' HTTP/1.1');
utl_http.set_authentication( req, 'abi','oshee', 'Basic' );
--utl_http.set_header(req, 'user-agent', 'mozilla/4.0'); 
--utl_http.set_header(req, 'content-type', 'application/json'); 
--utl_http.set_header(req, 'Content-Length', length(content));




/* not sure if this will work but try to print the utl_http */


res := utl_http.get_response(req);

    begin
    loop
    utl_http.read_line(res, buffer);
    dbms_output.put_line(buffer);

    end loop;
    utl_http.end_response(res);
    exception
    when utl_http.end_of_body then
    utl_http.end_response(res);
    end;

 /* just to indicate it ended */
    dbms_output.put_line('END');
exception
    when utl_http.end_of_body 
    then
        utl_http.end_response(res);

        /* just to indicate it went to exception part */
    DBMS_OUTPUT.put_line (SQLERRM); 
    dbms_output.put_line('EXCEPTION');
    end;

--end another_way;
4

2 回答 2

1

我以前没有在 PLSQL 中尝试过,但我可以为您提供以下内容:

(1)首先,测试您使用的URL是否真的可以捕获您的POST请求和请求正文。为此,您可以使用 POSTMAN(它是我用来测试 API 的应用程序 - 在您的情况下,此网址为“ http://10.211.47.98:7474/rest/postPayment/ ”)。免费。您也可以在不登录的情况下按原样使用它。

在 POSTMAN 中,您只需在 url 左侧的下拉列表中使用“POST”,然后在 url 字段中提供您的 url,然后在正文中提供您的 JSON 内容。(如果端点需要,还有授权标头)

以下是邮递员的网址和网站的示例截图: https ://www.getpostman.com/downloads/ 这是 POSTMAN 的示例屏幕

(2) 在您的代码中,您还可以添加额外的 DBMS_OUT.put_line() 代码,以便您可以在运行时验证触发代码时发生的情况。

示例(我刚刚在您的代码中添加了一些 DBMS_OUT 行和注释):

/*<"create or replace", name and other variables used by your code here>*/
req utl_http.req;
res utl_http.resp;
url varchar2(4000) := 'http://10.211.47.98:7474/rest/postPayment/';
name varchar2(4000);
buffer varchar2(4000); 
content varchar2(4000) := '{"customerNo":"' || customerNo || '","invoiceNo":"' || invoiceNo || '","agreementNo":"","instance":"' || instance || '","paymentRefId":"' ||paymentRefId || '","paymentDate":"' || paymentDate || '","principalAmt":' || principalAmt || ',"interest":' || interest|| ',"totalAmt":' || totalAmt || ',"passCode":"' || passCode || '","invoiceType":"' || invoiceType || '","phoneNo":"' || phoneNo || '"}';

begin
    /* just to indicate it started */
    dbms_output.put_line("START"); 

    /* to check if your JSON content is okay and has correct values */
    dbms_output.put_line(content); 

    req := utl_http.begin_request(url, 'POST',' HTTP/1.1');
    utl_http.set_header(req, 'user-agent', 'mozilla/4.0'); 
    utl_http.set_header(req, 'content-type', 'application/json'); 
    utl_http.set_header(req, 'Content-Length', length(content));

    utl_http.write_text(req, content);

    /* not sure if this will work but try to print the utl_http */
    dbms_output.put_line(utl_http);

    res := utl_http.get_response(req);

    begin
    loop
        utl_http.read_line(res, buffer);
        dbms_output.put_line(buffer);
    end loop;

    utl_http.end_response(res);

    /* just to indicate it ended */
    dbms_output.put_line("END");
exception
    when utl_http.end_of_body 
    then
        utl_http.end_response(res);

        /* just to indicate it went to exception part */
    dbms_output.put_line("EXCEPTION");
    end;
end /*<name of package/procedure>*/;

(3) 关于 oracle 的 utl_http 的更多技术细节,您也可以参考本文档。 https://docs.oracle.com/database/121/ARPLS/u_http.htm#ARPLS70957

希望这可以帮助。

如果您遇到任何其他问题,请在此处告知我们,以便我们分享更多详细信息。

于 2019-11-11T14:25:02.077 回答
0

基本上,使用 POST 方法调用 REST Web 服务,通过 plsql 在查询字符串中传递 json 参数,可以通过 APEX_WEB_SERVICE.MAKE_REST_REQUEST 成功执行,但应牢记 url 编码,因为 json 是使用保留字符构建的。可以使用 UTL_URL.ESCAPE 包/函数。我的例子如下:

L_BASE_URL VARCHAR2 (4000) :='http://baseurl:7474/mpower/rest/postPayment/' ; PAR := '{"customerNo":"'||customerNo||'","invoiceNo":"'||invoiceNo||'","agreementNo":"","instance":"'||instanceNo||'","paymentRefId":"'||paymentRefId||'","paymentDate":"'||paymentDate||'","principalAmt":'||principalAmt||',"interest":'||interest||',"totalAmt":'||totalAmt||',"passCode":"'||passCode||'","invoiceType":"'||invoiceType||'","phoneNo":"'||phoneNo||'"}'; l_base_url := l_base_url ||URL_ENCODE(PAR,'ASCII'); l_result := APEX_WEB_SERVICE.make_rest_request( p_url => l_base_url, p_http_method => 'POST', p_username => 'username', p_password => 'password' ); 其中 URL_ENCODE 函数如下:

create or replace FUNCTION url_encode ( data IN VARCHAR2, charset IN VARCHAR2) RETURN VARCHAR2 AS BEGIN RETURN utl_url.escape(data, TRUE, charset); -- note use of TRUE END;

于 2019-11-18T14:03:41.607 回答