SAP ABAP调用HTTP接口并用token进行登陆 “1024节日快乐了鸭“

调用需求

现在SAP系统需要调用.net服务器中的接口,接口是http这样式的. 但是第三方给到我们的是两个http接口,一个是用来登陆,另一个是用来获取具体的数据.
必须先使用登陆接口的http然后再使用另一个http接口获取举提数据.

postman测试可以可以正常获取到数据,但也需要在postman中先执行登陆的http接口. 因为postman这个测试工具他会把这两个域名相同的http接口的cookies进行关联,因此登陆之后可以直接再获取数据.
但在abap代码中并不可以自动进行关联cookies所以需要我们手动进行关联.

大致原理

我们需要创建两个客户端来进行连接.net服务器,A客户端用来登陆;B客户端用来获取数据.
如果说只是单纯的执行完A客户端再执行B客户端这样是不行的.所以我们需要获取到A客户端中的cookies把他给到B客户端,这样B客户端就会拿着cookis作为登陆过后的标识进行获取数据.
这里我们会用到工厂对象接口和工厂流

代码解析

我的这个登陆是POST的请求,用户名,密码及标识是放在body上的,
设置body参数方法 set_cdata( )
设置请求头,方法set_header_field( )
设置请求的方法,set_method( )

A客户端

cl_http_client=>create_by_url(
  EXPORTING
    url                = login "登陆的http接口
  IMPORTING
    client             = lo_http_client
  EXCEPTIONS
    argument_not_found = 1
    plugin_not_active  = 2
    internal_error     = 3
    OTHERS             = 4 ).

DATA var_string  TYPE string VALUE '{"u":"用户名","p":"密码","cn":"系统标识"}'.
lo_http_client->request->set_cdata( data = var_string ).


CALL METHOD lo_http_client->request->set_header_field
  EXPORTING
    name  = 'Content-Type'
    value = 'application/JSON; charset=utf-8'.

CALL METHOD lo_http_client->request->set_header_field
  EXPORTING
    name  = 'x-csrf-token'
    value = 'Fetch'.

CALL METHOD lo_http_client->request->set_method( 'POST' ).
"发送
lo_http_client->send(
  EXCEPTIONS
    http_communication_failure = 1
    http_invalid_state         = 2 ).
"接收
lo_http_client->receive(
  EXCEPTIONS
    http_communication_failure = 1
    http_invalid_state         = 2
    http_processing_failed     = 3 ).

简单的来说就是把登陆成功之后的cookies放到工厂中去,通过工程流在再把它给到B客户端

lv_result = lo_http_client->response->get_cdata( ).
lv_csrf  = lo_http_client->response->get_header_field( name = 'x-csrf-token' ).       "获取token
lo_http_client->response->get_cookies( CHANGING cookies = lt_cookies ).               "获取cookies
lo_ixml = cl_ixml=>create( ).

lo_streamfactory = lo_ixml->create_stream_factory( ).
lo_istream = lo_streamfactory->create_istream_string(
                                 lv_result ).
lo_document = lo_ixml->create_document( ).
lo_parser = lo_ixml->create_parser(
                       stream_factory = lo_streamfactory
                       istream        = lo_istream
                       document       = lo_document ).
lo_parser->parse( ).
CALL METHOD lo_http_client->close.

B客户端

和A客户端一样的操作,只是比他多了一个请求头,多的就是咱们获取到的cookies作为请求头,然后再把这个cookies给到B客户端
设置cookie方法;set_cookie( )

CALL METHOD lo_http_client1->request->set_header_field
  EXPORTING
    name  = 'x-csrf-token'
    value = lv_csrf.                

"设置cookies
LOOP AT lt_cookies ASSIGNING FIELD-SYMBOL(<cookie>).
  lo_http_client1->request->set_cookie( name = <cookie>-name
                                       value = <cookie>-value ).
ENDLOOP.

根据你的需求来发送你的请求参数,JSON格式的,也是在body中发送的,也是post的请求.

lv_json = '你要发送的请求参数'
len = strlen( lv_json ) . "请求参数的长度

CALL METHOD lo_http_client1->request->set_cdata
  EXPORTING
    data   = lv_json
    offset = 0
    length = len.

其他就没什么了.

cl_demo_output=>display( lv_result ).

总结

这个我们用到了工厂,我的个人理解是:我们把两个客户端所建立的连接放到同一个工厂中去,由工厂进行管理,在工厂中的数据是共享的,可以相互使用.

源代码

以下源码仅供参考

*&---------------------------------------------------------------------*
*& Report Z_HTTP_DEMO_004
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT z_http_demo_004.
DATA: lo_http_client   TYPE REF TO if_http_client,  "第一个cl_http_client 用于登陆
      lo_http_client1  TYPE REF TO if_http_client, "第二个cl_http_client  用于获取数据
      login            TYPE string,
      lv_result        TYPE string,
      lv_csrf          TYPE string,
      lt_cookies       TYPE tihttpcki,
      lo_ixml          TYPE REF TO if_ixml,
      lo_streamfactory TYPE REF TO if_ixml_stream_factory,
      lo_istream       TYPE REF TO if_ixml_istream,
      lo_document      TYPE REF TO if_ixml_document,
      lo_parser        TYPE REF TO if_ixml_parser.

login =  'http://login'.
"第一个cl_http_client使用post获取token和cookies
cl_http_client=>create_by_url(
  EXPORTING
    url                = login
  IMPORTING
    client             = lo_http_client
  EXCEPTIONS
    argument_not_found = 1
    plugin_not_active  = 2
    internal_error     = 3
    OTHERS             = 4 ).

DATA var_string  TYPE string VALUE '{"u":"用户名","p":"密码","cn":"系统标识"}'.
lo_http_client->request->set_cdata( data = var_string ).


CALL METHOD lo_http_client->request->set_header_field
  EXPORTING
    name  = 'Content-Type'
    value = 'application/JSON; charset=utf-8'.

CALL METHOD lo_http_client->request->set_header_field
  EXPORTING
    name  = 'x-csrf-token'
    value = 'Fetch'.

CALL METHOD lo_http_client->request->set_method( 'POST' ).

lo_http_client->send(
  EXCEPTIONS
    http_communication_failure = 1
    http_invalid_state         = 2 ).

lo_http_client->receive(
  EXCEPTIONS
    http_communication_failure = 1
    http_invalid_state         = 2
    http_processing_failed     = 3 ).

CLEAR lv_result .
lv_result = lo_http_client->response->get_cdata( ).
lv_csrf  = lo_http_client->response->get_header_field( name = 'x-csrf-token' ).       "获取token
lo_http_client->response->get_cookies( CHANGING cookies = lt_cookies ).               "获取cookies
lo_ixml = cl_ixml=>create( ).

lo_streamfactory = lo_ixml->create_stream_factory( ).
lo_istream = lo_streamfactory->create_istream_string(
                                 lv_result ).
lo_document = lo_ixml->create_document( ).
lo_parser = lo_ixml->create_parser(
                       stream_factory = lo_streamfactory
                       istream        = lo_istream
                       document       = lo_document ).
lo_parser->parse( ).
CALL METHOD lo_http_client->close.

"第二个cl_http_client用前面获取的token和cookies来执行POST
cl_http_client=>create_by_url(
  EXPORTING
    url                =  'http'
  IMPORTING
    client             = lo_http_client1
  EXCEPTIONS
    argument_not_found = 1
    plugin_not_active  = 2
    internal_error     = 3
    OTHERS             = 4 ).

CALL METHOD lo_http_client1->request->set_header_field
  EXPORTING
    name  = 'Content-Type'
    value = 'application/JSON; charset=utf-8'.

CALL METHOD lo_http_client1->request->set_header_field
  EXPORTING
    name  = 'x-csrf-token'
    value = lv_csrf.                "使用第一个cl_http_clien获取的token

"设置cookies
LOOP AT lt_cookies ASSIGNING FIELD-SYMBOL(<cookie>).
  lo_http_client1->request->set_cookie( name = <cookie>-name
                                       value = <cookie>-value ).
ENDLOOP.

CALL METHOD lo_http_client1->request->set_method( 'POST' ).

DATA lv_json TYPE string.
DATA: len TYPE i .
lv_json =  xxxxxxxx
len = strlen( lv_json ) .

CALL METHOD lo_http_client1->request->set_cdata
  EXPORTING
    data   = lv_json
    offset = 0
    length = len.
*发送请求
lo_http_client1->send(
  EXCEPTIONS
    http_communication_failure = 1
    http_invalid_state         = 2 ).
*接收返回参数
lo_http_client1->receive(
  EXCEPTIONS
    http_communication_failure = 1
    http_invalid_state         = 2
    http_processing_failed     = 3 ).

CLEAR lv_result .
lv_result = lo_http_client1->response->get_cdata( ). "获取接收参数
lo_ixml = cl_ixml=>create( ).

lo_streamfactory = lo_ixml->create_stream_factory( ).
lo_istream = lo_streamfactory->create_istream_string(
                                 lv_result ).
lo_document = lo_ixml->create_document( ).
lo_parser = lo_ixml->create_parser(
                       stream_factory = lo_streamfactory
                       istream        = lo_istream
                       document       = lo_document ).
lo_parser->parse( ).
CALL METHOD lo_http_client1->close.

cl_demo_output=>display( lv_result ).

在这里插入图片描述

  • 5
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

雨天行舟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值