S4HANA For ABAP(8):ABAP Odata Service

8 篇文章 3 订阅

ABAP Odata Service

1.What's Odata Service

OData (Open Data Protocol)是OASIS标准,其定义了基于HTTP的,用于构建和使用RESTful API的协议。

相关链接:

https://www.oasis-open.org/committees/tc_home.php?wg_abbrev=odata

https://www.odata.org/

https://github.com/SAP/C4CODATAAPIDEVGUIDE

https://blogs.sap.com/2023/03/26/implementing-all-odata-query-uri-options-part-1/

https://blogs.sap.com/2023/03/26/implementing-all-odata-query-uri-options-part-2/

https://blogs.sap.com/2020/08/05/odata-batch-processing-part-1/

https://blogs.sap.com/2020/08/06/odata-batch-processing-part-2/

https://blogs.sap.com/2020/08/19/batch-call-processing-in-sap-netweaver-gateway/

https://blogs.sap.com/2014/09/23/file-uploaddownload-through-netweaver-gateway/

https://blogs.sap.com/2021/05/19/a-step-by-step-process-to-post-odata-services-in-sap-sap-hana-system/

相关Tcode:

SEGW:SAP Gateway Service Builder

/IWFND/TRACES:SAP Gateway:Tracing Tools

/IWFND/STATS:SAP Gateway Statistics

/IWFND/MAINT_SERVICE:Activate and Maintain Service

/IWFND/GW_CLIENT:SAP Gateway Client

2.Create a SAP Gateway Service

SAP Gateway Service Builder

Tcode:SEGW,SAP Gateway Service Builder

1.选择Create Service

2.选择Data Model->Import->DDIC Structure;

通过ABAP DDIC字典中Table,Structure创建工作区,结构表;

3.指定创建的Entity Type,默认勾选Create Default Entity Set,这里Entity Set相当于工作表,Entity Type相当于工作区;

4.选择需要使用到的栏位;

5.指定那些栏位是key值;

6.选择Entity Types,点击Properties,指定每个字段设置;

7.点击Generate Runtime Objects;

8.重写Create,Delete,GetEntity(Read),GetEntitySet(Query),Update方法;

Generate生成对应类可以在Runtime Artifacts中看到;

选择要Redefine的方法,右键->Go to ABAP WorkBench;

对应重写方法代码,需要结合URL请求。

Tcode:/IWFND/MAINT_SERVICE

注意:如果开启不了,提示User no longer logged on,选择/n/IWFND/MAINT_SERVICE执行Tcode;

激活和维护SAP Gateway Service;

如果新建Service,需要点击Add Service,将创建的Service添加,<Service名称>_SRV;

点击SAP Gateway Client,跳转到SAP Gateway Client测试URL请求;

注意:如果跳转不了那么可以选择导航栏,Goto->SAP GW Client;

Tcode: /IWFND/GW_CLIENT

可以直接打开SAP Gateway Client;

注意:如果开启不了,提示User no longer logged on,选择/n方式执行Tcode;

默认返回XML格式数据;

2.1URL Query Option

$batch:执行HTTP POST查询,创建,更新和删除多笔记录;

$format:指定返回数据格式,示例:/EntitySet?$format=json;

$count:返回EntitySet记录数,示例:/EntitySet/$count;

$orderby:排序记录,示例:/EntitySet?$orderby=date desc,time asc;

search:指定查询条件,示例:/EntitySet?search='test';

$select:指定查询栏位,示例:/EntitySet?$select=name,test;

$filter:筛选指定记录,实例:/Entityset?$filter=date eq '20020102' and name eq 'jim';

$top:返回top记录,示例:/EntitySet?$top=10;

$skip:指定跳过指定数量记录,示例:/Entityset?$skip=10;

$inlinecount:返回EntitySet记录数,示例: /EntitySet?$top=10&$inlinecount=allpages;

通过ABAP Code获取对应值;

示例:

   "获取URL参数
*   DATA:lv_top TYPE string.
*   DATA:lv_skip TYPE string.
*   DATA:lv_search TYPE string.
*   DATA:lv_orderby TYPE /iwbep/t_mgw_tech_order.
*   DATA:lv_select TYPE /iwbep/t_mgw_tech_field_names.
*   DATA:lv_filter TYPE REF TO /iwbep/if_mgw_req_filter.
*   DATA:lv_select_option TYPE /iwbep/t_mgw_select_option.
*   DATA:lv_select_string TYPE string.
*   "获取$top字符串
*   lv_top = io_tech_request_context->get_top( ).
*   "获取$skip字符串
*   lv_skip = io_tech_request_context->get_skip( ).
*   "获取?search字符串
*   lv_search = io_tech_request_context->get_search_string( ).
*   "获取$order by
*   lv_orderby = io_tech_request_context->get_orderby( ).
*   "获取$select
*   lv_select = io_tech_request_context->get_select( ).
*   "获取$filter
*   lv_filter = io_tech_request_context->get_filter( ).
*   lv_select_option = lv_filter->get_filter_select_options( ).
*   lv_select_string = lv_filter->get_filter_string( ).
*   "获取keys table
*   "lt_key_tab = io_tech_request_context->get_keys( ).

2.2Get EntitySet

获取数据集,调用GET_ENTITYSET方法;

URL:/sap/opu/odata/ZTOM_GS1_SRV/ZT_SFLIGHTSet;

重写GET_ENTITYSET方法;

示例:ZT_SFLIGHTSET_GET_ENTITYSET方法;

  method ZT_SFLIGHTSET_GET_ENTITYSET.

"查询所有数据
   SELECT * INTO CORRESPONDING FIELDS OF TABLE et_entityset
     FROM ztom_sflight.

endmethod.

2.3Get Entity

获取指定key值条件记录,调用GET_ENTITY方法;

URL:/sap/opu/odata/sap/ZTOM_GS1_SRV/ZT_SFLIGHTSet(Carrid='AA',Connid='0017',Fldate=datetime'2022-11-17T00%3A00%3A00');

注意:当使用这种方式访问资源时,必须指定每个key的值,不能只放Carrid某一个key值;

    这里key值栏位必须和定义Properties中一致,通常首字母大写,其余小写;

重写GET_ENTITY方法;

示例:ZT_SFLIGHTSET_GET_ENTITY方法

 

 method ZT_SFLIGHTSET_GET_ENTITY.
   "input parameter
   DATA:lv_entity_name TYPE string.
   DATA:lv_entity_set_name TYPE string.
   DATA:lv_source_name TYPE string.
   "(key=value,key2=value2)
   DATA:lt_key_tab TYPE /iwbep/t_mgw_name_value_pair.
   DATA:ls_key_tab LIKE LINE OF lt_key_tab.
   DATA:lo_request_object TYPE REF TO /iwbep/if_mgw_req_entity.
   DATA:lo_tech_request_context TYPE REF TO /iwbep/if_mgw_req_entity.
   DATA:lt_navigation_path TYPE /iwbep/t_mgw_navigation_path.
   "动态where
   DATA:lt_where TYPE TABLE OF string.
   DATA:ls_where LIKE LINE OF lt_where.

   lv_entity_name = iv_entity_name.
   lv_entity_set_name = iv_entity_set_name.
   lv_source_name = iv_source_name.
   lt_key_tab = it_key_tab.
   lo_request_object = io_request_object.
   lo_tech_request_context = io_tech_request_context.
   lt_navigation_path = it_navigation_path.
   "key参数
   LOOP AT lt_key_tab INTO ls_key_tab.
     IF sy-tabix = 1.
       CLEAR ls_where.
       ls_where = ls_key_tab-name && ' = ''' && ls_key_tab-value && ''''.
       APPEND ls_where TO lt_where.
     ELSE.
       CLEAR ls_where.
       ls_where = `AND ` && ls_key_tab-name && ' = ''' && ls_key_tab-value && ''''.
       APPEND ls_where TO lt_where.
     ENDIF.
   ENDLOOP.
   IF lt_key_tab IS NOT INITIAL.
     SELECT SINGLE * INTO CORRESPONDING FIELDS OF er_entity
       FROM ztom_sflight
       WHERE (lt_where).
   ELSE.
     SELECT SINGLE * INTO CORRESPONDING FIELDS OF er_entity
       FROM ztom_sflight.
   ENDIF.
  endmethod.

2.4Get EntitySet,指定$filter

筛选指定条件记录,调用GET_ENTITYSET方法;

URL: /sap/opu/odata/sap/ZTOM_GS1_SRV/ZT_SFLIGHTSet?$filter=Carrid eq 'AA' and Connid eq '0017'&$format=json;

filter条件:

eq

is equal

ne

is not equal

gt

is greater than

ge

is greater than or equal

lt

is less than

le

is less than or equal

'&'是特殊字符可以使用%26替换;

'#'是特殊字符可以使用%23替换;

Error URL: /sap/opu/odata/sap/ZTOM_GS1_SRV/ZT_SFLIGHTSet?$filter=Planetype eq '747#400' &$format=json;

Success URL: /sap/opu/odata/sap/ZTOM_GS1_SRV/ZT_SFLIGHTSet?$filter=Planetype eq '747%23400' &$format=json;

filter支持字符Function:

URL:/sap/opu/odata/sap/ZTOM_GS1_SRV/ZT_SFLIGHTSet?$filter=substringof('747',Planetype)&$format=json;

支持语法:substringof('747-100',Planetype);

转换后where语句:PLANETYPE like '%747%' 

URL:/sap/opu/odata/sap/ZTOM_GS1_SRV/ZT_SFLIGHTSet?$filter=startswith(Planetype,'747')&$format=json

支持语法:startswith(Planetype,'747')

转换后where语句: ( PLANETYPE like '747%' )

重写GET_ENTITYSET方法

示例:ZT_SFLIGHTSET_GET_ENTITYSET方法;

    "获取$filter
    DATA:lv_filter_string TYPE string.
    lv_filter_string = io_tech_request_context->get_filter( )->get_filter_string( ).
    IF lv_filter_string IS NOT INITIAL.
      "方式1:根据筛选器查询数据
*      SELECT * INTO CORRESPONDING FIELDS OF TABLE et_entityset
*        FROM ztom_sflight
*        WHERE (lv_filter_string).

      "方式2:使用util方法筛选
      "需要先查询所有数据
      SELECT * INTO CORRESPONDING FIELDS OF TABLE et_entityset
        FROM ztom_sflight.
      /iwbep/cl_mgw_data_util=>filtering(
        EXPORTING
          it_select_options = it_filter_select_options
        CHANGING
          ct_data = et_entityset
      ).
    ELSE.
      "查询所有数据
      SELECT * INTO CORRESPONDING FIELDS OF TABLE et_entityset
        FROM ztom_sflight.
    ENDIF.

2.5Get EntitySet,指定$orderby

指定排序,调用GET_ENTITYSET方法;

URL:/sap/opu/odata/sap/ZTOM_GS1_SRV/ZT_SFLIGHTSet?$orderby=Carrid desc,Connid asc&$format=json;

重写GET_ENTITYSET方法

示例:ZT_SFLIGHTSET_GET_ENTITYSET方法;

不需要转换,直接使用传入it_order参数类型;

    "获取$orderby
    DATA:lt_orderby TYPE /iwbep/t_mgw_tech_order.
    lt_orderby = io_tech_request_context->get_orderby( ).
    "排序
    /iwbep/cl_mgw_data_util=>orderby(
      EXPORTING
        it_order = it_order
      CHANGING
        ct_data = et_entityset
    ).

动态Sort代码

示例:

  DATA: lt_otab  TYPE abap_sortorder_tab,
        ls_oline TYPE abap_sortorder.
  DATA: ls_order LIKE LINE OF it_order.

  LOOP AT it_order INTO ls_order.
    ls_oline-name = ls_order-property.
    TRANSLATE ls_oline-name TO UPPER CASE.               "#EC TRANSLANG
    IF ls_order-order = gcs_sorting_order-descending.
      ls_oline-descending = 'X'.
    ENDIF.
    APPEND ls_oline TO lt_otab.
    CLEAR ls_oline.
  ENDLOOP.
  SORT ct_data BY (lt_otab).

2.6Get EntitySet,指定$top,$skip

获取top笔数记录,skip排除指定记录数,调用GET_ENTITYSET方法;

URL:/sap/opu/odata/sap/ZTOM_GS1_SRV/ZT_SFLIGHTSet?$top=5&$skip=10&$format=json;

重写GET_ENTITYSET方法

示例:ZT_SFLIGHTSET_GET_ENTITYSET方法;

    "获取$top,$skip
    "paging方法,先skip,后取top记录
    DATA:lv_top TYPE string.
    DATA:lv_skip TYPE string.
    "获取$top字符串
    lv_top = io_tech_request_context->get_top( ).
    "获取$skip字符串
    lv_skip = io_tech_request_context->get_skip( ).
    "直接调用方式实现paging
    /iwbep/cl_mgw_data_util=>paging(
      EXPORTING
        is_paging = is_paging
      CHANGING
        ct_data = et_entityset
    ).

2.7Get EntitySet,指定$inlinecount

返回符合条件记录数,调用GET_ENTITYSET方法;

URL: /sap/opu/odata/sap/ZTOM_GS1_SRV/ZT_SFLIGHTSet?$filter=Carrid eq 'AA'&$inlinecount=allpages&$format=json;

返回结果会有count的值;

重写GET_ENTITYSET方法

示例:ZT_SFLIGHTSET_GET_ENTITYSET方法;

    "获取$inlinecount
    IF io_tech_request_context->has_inlinecount( ) = abap_true.
      "获取符合条件总记录数
      DESCRIBE TABLE et_entityset LINES DATA(lv_lines).
      es_response_context-inlinecount = lv_lines.
    ENDIF.

2.8Get EntitySet,指定$count

获取EntitySet记录笔数,调用GET_ENTITYSET方法;

正确URL: /sap/opu/odata/sap/ZTOM_GS1_SRV/ZT_SFLIGHTSet/$count?$filter=Carrid eq 'AA'

错误URL: /sap/opu/odata/sap/ZTOM_GS1_SRV/ZT_SFLIGHTSet/$count?$filter=Carrid eq 'AA'&$format=json;

Error: "System query options '$expand,$format,$skiptoken,$inlinecount,$select' are not allowed in the requested URI"

$format和$count不能同时存在;

2.9Get EntitySet,指定$select

查询指定栏位,调用GET_ENTITYSET方法;

URL: /sap/opu/odata/sap/ZTOM_GS1_SRV/ZT_SFLIGHTSet?$filter=Carrid eq 'AA'&$select=Carrid,Connid&$format=json;

示例:只查询Carrid,Connid栏位;

2.10Get EntitySet,指定$format

指定返回格式,调用GET_ENTITYSET方法;

默认返回XML格式;

URL:/sap/opu/odata/sap/ZTOM_GS1_SRV/ZT_SFLIGHTSet?$filter=Carrid eq 'AA'&$format=json

URL: /sap/opu/odata/sap/ZTOM_GS1_SRV/ZT_SFLIGHTSet?$filter=Carrid eq 'AA'&$format=xml

2.11Get Entity,指定$value

返回指定栏位值,调用GET_ENTITY方法;

URL:/sap/opu/odata/sap/ZTOM_GS1_SRV/ZT_SFLIGHTSet(Carrid='AA',Connid='0017',Fldate=datetime'2023-07-31T00%3A00%3A00')/Price/$value;

2.12Get EntitySet,指定$expand,$links

展开association栏位,调用GET_ENTITYSET方法;

创建一个新的Entity Type,Entity Set;

ZT_SCARR包含CARRID,CARRNAME,URL等属性;

创建Associations;

这种从SFLIGHT作为起点,需要指定SFLIGHT key值对应的栏位,无法实现;

从SCARR作为起点,指定SCARR key值CARRID对应SFLIGHT的CARRID;

同样重写SCARR的GET_ENTITY方法;

示例:

  method ZT_SCARRSET_GET_ENTITY.
   "动态where
   DATA:lt_where TYPE TABLE OF string.
   DATA:ls_where LIKE LINE OF lt_where.
   DATA:ls_key_tab LIKE LINE OF it_key_tab.
   "key参数
   LOOP AT it_key_tab INTO ls_key_tab.
     IF sy-tabix = 1.
       CLEAR ls_where.
       ls_where = ls_key_tab-name && ' = ''' && ls_key_tab-value && ''''.
       APPEND ls_where TO lt_where.
     ELSE.
       CLEAR ls_where.
       ls_where = `AND ` && ls_key_tab-name && ' = ''' && ls_key_tab-value && ''''.
       APPEND ls_where TO lt_where.
     ENDIF.
   ENDLOOP.
   IF it_key_tab IS NOT INITIAL.
     SELECT SINGLE * INTO CORRESPONDING FIELDS OF er_entity
       FROM scarr
       WHERE (lt_where).
   ELSE.
     SELECT SINGLE * INTO CORRESPONDING FIELDS OF er_entity
       FROM scarr.
   ENDIF.
  endmethod.

重新SCARR的GET_ENTITYSET方法;

示例:

  method ZT_SCARRSET_GET_ENTITYSET.

    "查询所有数据
    SELECT * INTO CORRESPONDING FIELDS OF TABLE et_entityset
      FROM scarr.

    "获取$top,$skip
    "paging方法,先skip,后取top记录
    "直接调用方式实现paging
    IF is_paging IS NOT INITIAL.
      /iwbep/cl_mgw_data_util=>paging(
        EXPORTING
          is_paging = is_paging
        CHANGING
          ct_data = et_entityset
      ).
    ENDIF.

    "获取$filter
    IF it_filter_select_options IS NOT INITIAL.
      "方式2:使用util方法筛选
      /iwbep/cl_mgw_data_util=>filtering(
        EXPORTING
          it_select_options = it_filter_select_options
        CHANGING
          ct_data = et_entityset
      ).
    ENDIF.

    "获取$orderby,排序
    IF it_order IS NOT INITIAL.
      /iwbep/cl_mgw_data_util=>orderby(
        EXPORTING
          it_order = it_order
        CHANGING
          ct_data = et_entityset
      ).
    ENDIF.

    "获取$inlinecount
    IF io_tech_request_context->has_inlinecount( ) = abap_true.
      "获取符合条件总记录数
      DESCRIBE TABLE et_entityset LINES DATA(lv_lines).
      es_response_context-inlinecount = lv_lines.
    ENDIF.
  endmethod.

使用$expand,通过SCARR-CARRID查询到SFLIGHT对应CARRID所有数据信息;

URL: /sap/opu/odata/sap/ZTOM_GS1_SRV/ZT_SCARRSet(Carrid='AA')?$expand=TO_SFLIGHT;

使用$links,通过SCARR-CARRID查询返回所有SFLIGHT对应CARRID的所有URL;

URL: /sap/opu/odata/sap/ZTOM_GS1_SRV/ZT_SCARRSet(Carrid='AA')/$links/TO_SFLIGHT

2.13Update Entity

URL: /sap/opu/odata/sap/ZTOM_GS1_SRV/ZT_SCARRSet('AA')?$format=json;

执行GET方法,获取json格式结果;

选择Use as Request,将Get结果放到Request Body中;

执行一下POST,获取HTTP Header参数X-CSRF-Token;

设置Content-Type: application/json; charset=utf-8;

URL:/sap/opu/odata/sap/ZTOM_GS1_SRV/ZT_SCARRSet('AA')

修改非key栏位值,执行PUT方法;

 "d" : {
    "__metadata" : {
      "id" "<host>/sap/opu/odata/sap/ZTOM_GS1_SRV/ZT_SCARRSet('AA')",
      "uri" "<host>/sap/opu/odata/sap/ZTOM_GS1_SRV/ZT_SCARRSet('AA')",
      "type" "ZTOM_GS1_SRV.ZT_SCARR"
    },
    "Carrid" "AA",
    "Carrname" "American Airlines S",
    "Currcode" "USD",
    "Url" "http://www.aa.com",
    "TO_SFLIGHT" : {
      "__deferred" : {
        "uri" "<host>/sap/opu/odata/sap/ZTOM_GS1_SRV/ZT_SCARRSet('AA')/TO_SFLIGHT"
      }
    }
  }
}

执行UPDATE_ENTITY方法;

示例:

method ZT_SCARRSET_UPDATE_ENTITY.
    DATA:lt_scarr TYPE TABLE OF scarr.
    DATA:ls_scarr LIKE LINE OF lt_scarr.
    "读取输入数据
    io_data_provider->read_entry_data( IMPORTING es_data = ls_scarr ).
    "保存数据
    MODIFY scarr FROM ls_scarr.
  endmethod.

2.14Create Entity

URL: /sap/opu/odata/sap/ZTOM_GS1_SRV/ZT_SCARRSet;

使用POST方法,执行新增记录;

同样需要GET请求带过来的HTTP Header参数X-CSRF-Token,Content-Type: application/json; charset=utf-8;

示例:HTTP POST请求头,设置需要插入数据的值

{
  "d" : {
    "__metadata" : {
      "uri" "<host>/sap/opu/odata/sap/ZTOM_GS1_SRV/ZT_SCARRSet",
      "type" "ZTOM_GS1_SRV.ZT_SCARR"
    },
    "Carrid" "ZF",
    "Carrname" "test Airlines",
    "Currcode" "USD",
    "Url" "http://www.zf.com"
  }
}

执行CREATE_ENTITY方法

示例:

  method ZT_SCARRSET_CREATE_ENTITY.
    DATA:lt_scarr TYPE TABLE OF scarr.
    DATA:ls_scarr LIKE LINE OF lt_scarr.
    DATA:lv_msg TYPE string.
    "读取输入数据
    io_data_provider->read_entry_data( IMPORTING es_data = ls_scarr ).
    "保存数据
    INSERT scarr FROM ls_scarr.
    IF sy-subrc <> 0.
      lv_msg = 'Insert duplicate keys record!'.
      RAISE EXCEPTION TYPE /IWBEP/CX_MGW_BUSI_EXCEPTION
        EXPORTING
           textid = /IWBEP/CX_MGW_BUSI_EXCEPTION=>RESOURCE_DUPLICATE
           entity_type = lv_msg.
    ELSE.
      "成功插入,er_entity有值
      MOVE-CORRESPONDING ls_scarr TO er_entity.
    ENDIF.
  endmethod.

2.15Delete Entity

URL: /sap/opu/odata/sap/ZTOM_GS1_SRV/ZT_SCARRSet('ZF');

使用DELETE方法,执行删除记录;

执行DELETE_ENTITY方法

示例:

  method ZT_SCARRSET_DELETE_ENTITY.
    DATA:ls_key_tab LIKE LINE OF it_key_tab.
    DATA:lv_msg TYPE string.
   "根据输入参数删除对应carrid记录
   CLEAR ls_key_tab.
   READ TABLE it_key_tab INTO ls_key_tab WITH KEY name = 'Carrid'.
   IF ls_key_tab IS NOT INITIAL.
     DELETE FROM scarr WHERE carrid = ls_key_tab-value.
     IF sy-subrc = 0.
       "删除成功
     ELSE.
       "删除记录不存在
       lv_msg = 'carrid=' && ls_key_tab-value && ',not found!'.
       RAISE EXCEPTION TYPE /IWBEP/CX_MGW_BUSI_EXCEPTION
        EXPORTING
           textid = /IWBEP/CX_MGW_BUSI_EXCEPTION=>RESOURCE_NOT_FOUND
           entity_type = lv_msg.
     ENDIF.
   ELSE.
      "没有指定carrid
      lv_msg = 'No carrid=' && ls_key_tab-value && ',not allowed!'.
      RAISE EXCEPTION TYPE /IWBEP/CX_MGW_BUSI_EXCEPTION
       EXPORTING
          textid = /IWBEP/CX_MGW_BUSI_EXCEPTION=>RESOURCE_NOT_FOUND
          entity_type = lv_msg.
   ENDIF.
  endmethod.

2.16$batch

示例1:$batch基本实现过程

URL: /sap/opu/odata/sap/ZTOM_GS1_SRV/;

选择POST请求,点击Add URI Option;

URL: /sap/opu/odata/sap/ZTOM_GS1_SRV/$batch;

Request Header参数:

Content-Type:multipart/mixed; boundary=batch

Request Header Body batch定义

一个batch任务定义:包含header部分,请求内容部分;

Accept: application/json

指定返回json格式结果;

示例:

--batch
Content-Type: application/http
Content-Transfer-Encoding: binary

GET ZT_SCARRSet(Carrid='AA') HTTP/1.1


--batch
Content-Type: multipart/mixed; boundary=changeset

--changeset
Content-Type: application/http
Content-Transfer-Encoding: binary

POST ZT_SCARRSet HTTP/1.1
Content-Type: application/json

{
  "d" : {
    "__metadata" : {
      "uri" "<host>/sap/opu/odata/sap/ZTOM_GS1_SRV/ZT_SCARRSet",
      "type" "ZTOM_GS1_SRV.ZT_SCARR"
    },
    "Carrid" "ZK",
    "Carrname" "test1 Airlines",
    "Currcode" "USD",
    "Url" "http://www.zk.com"
  }
}

--changeset--

--batch--

注意:每一个--batch和上一个GET,POST请求之间至少空两行;

    --batch,表示batch开始;

    --batch--,表示batch结束;

    每一个batch之间执行结果互相不影响;

    --changeset,表示create,update,delete批量process,只要一个失败,都失败;

示例2:$batch changeset,批量Create

示例:

--batch
Content-Type: multipart/mixed; boundary=changeset

--changeset
Content-Type: application/http
Content-Transfer-Encoding: binary

POST ZT_SCARRSet HTTP/1.1
Content-Type: application/json
Accept: application/json

{
  "d" : {
    "__metadata" : {
      "uri" "<host>/sap/opu/odata/sap/ZTOM_GS1_SRV/ZT_SCARRSet",
      "type" "ZTOM_GS1_SRV.ZT_SCARR"
    },
    "Carrid" "ZK",
    "Carrname" "test1 Airlines",
    "Currcode" "USD",
    "Url" "http://www.zk.com"
  }
}

--changeset
Content-Type: application/http
Content-Transfer-Encoding: binary

POST ZT_SCARRSet HTTP/1.1
Content-Type: application/json
Accept: application/json

{
  "d" : {
    "__metadata" : {
      "uri" "<host>/sap/opu/odata/sap/ZTOM_GS1_SRV/ZT_SCARRSet",
      "type" "ZTOM_GS1_SRV.ZT_SCARR"
    },
    "Carrid" "ZH",
    "Carrname" "test1 Airlines",
    "Currcode" "USD",
    "Url" "http://www.zh.com"
  }
}

--changeset--

注意:默认一个batch只支持一个--changeset,当设置多个chanegset时,报错:"Default changeset implementation allows only one operation"

可以将多个POST请求分别放到多个batch;

当需要支持一个batch多个--changeset时,需要修改下面三个Method:

/IWBEP/IF_MGW_APPL_SRV_RUNTIME~CHANGESET_BEGIN

/IWBEP/IF_MGW_APPL_SRV_RUNTIME~CHANGESET_END

/IWBEP/IF_MGW_APPL_SRV_RUNTIME~CHANGESET_PROCESS

Step1:Redefine /IWBEP/IF_MGW_APPL_SRV_RUNTIME~CHANGESET_BEGIN

示例:

  method /IWBEP/IF_MGW_APPL_SRV_RUNTIME~CHANGESET_BEGIN.
    cv_defer_mode = abap_true.
  endmethod.

Step2:Redefine /IWBEP/IF_MGW_APPL_SRV_RUNTIME~CHANGESET_END

示例:

  method /IWBEP/IF_MGW_APPL_SRV_RUNTIME~CHANGESET_END.
    COMMIT WORK.
  endmethod.

Step3:Redefine /IWBEP/IF_MGW_APPL_SRV_RUNTIME~CHANGESET_PROCESS

根据operation type,处理不同请求

CD  Create Deep Entity

CE  Create Entity

CM  Create Stream

DE  Delete Entity

DM  Delete Stream

EA  Execute Action

XE  Expand Entity

XS  Expand Entity Set

GE  Get Entity

GS  Get Entity Set

GD  Get Entity Set Delta

GM  Get Stream

PE  Patch Entity

UE  Update Entity

UM  Update Stream

HB  Changeset Begin

HE  Changeset End

HP  Changeset Process

IC  Get Is Conditional Implemented

示例:

  method /IWBEP/IF_MGW_APPL_SRV_RUNTIME~CHANGESET_PROCESS.
    "request /IWBEP/IF_MGW_APPL_TYPES=>TY_T_CHANGESET_REQUEST
    FIELD-SYMBOLS:<fs_changeset_request> LIKE LINE OF it_changeset_request.
    "response list
    DATA:ls_changeset_response TYPE /iwbep/if_mgw_appl_types=>ty_s_changeset_response.

    DATA:lo_data TYPE REF TO data.
    FIELD-SYMBOLS:<fs_data> TYPE ANY.
    DATA:lo_struct_descr   TYPE REF TO cl_abap_structdescr.
    DATA:lo_expand_node TYPE REF TO /iwbep/cl_mgw_expand_node.
    DATA:lv_entity_type TYPE /iwbep/mgw_tech_name.
    "input parameter
    DATA:lv_entity_name TYPE string.
    DATA:lv_entity_set_name TYPE string.
    DATA:lv_source_name TYPE string.
    DATA:lt_key_tab TYPE /iwbep/t_mgw_name_value_pair.
    DATA:ls_key_tab LIKE LINE OF lt_key_tab.
    DATA:lo_request_object TYPE REF TO /iwbep/if_mgw_req_entity.
    DATA:lo_tech_request_context TYPE REF TO /iwbep/if_mgw_req_entity.
    DATA:lt_navigation_path TYPE /iwbep/t_mgw_navigation_path.
    "request create
    DATA:lo_request_c TYPE REF TO /iwbep/if_mgw_req_entity_c.

    "根据operation,处理不同请求
    LOOP AT it_changeset_request ASSIGNING <fs_changeset_request>.
      CASE <fs_changeset_request>-operation_type.
        WHEN 'CE'.
          "create entity
          "获取请求数据
          lo_expand_node ?= <fs_changeset_request>-expand_node.
          lo_struct_descr ?= lo_expand_node->create_data_descriptor( ).
          CREATE DATA lo_data TYPE HANDLE lo_struct_descr.
          ASSIGN lo_data->* TO <fs_data>.
          <fs_changeset_request>-entry_provider->read_entry_data( IMPORTING es_data = <fs_data> ).

          "获取entity name
          "执行更新
          lo_request_c ?= <fs_changeset_request>-request_context.
          lv_entity_type = lo_request_c->get_entity_type_name( ).
          IF lv_entity_type = 'ZT_SCARR'.
            CLEAR <fs_data>.
            zt_scarrset_create_entity(
              EXPORTING
                iv_entity_name = lv_entity_name
                iv_entity_set_name = lv_entity_set_name
                iv_source_name = lv_source_name
                it_key_tab = lt_key_tab
                io_tech_request_context = lo_request_c
                it_navigation_path = lt_navigation_path
                io_data_provider = <fs_changeset_request>-entry_provider
              IMPORTING
                er_entity = <fs_data>
            ).
          ENDIF.

          "Create成功,设置response
          IF <fs_data> IS NOT INITIAL.
            CLEAR ls_changeset_response.
            copy_data_to_ref(
              EXPORTING
                is_data = <fs_changeset_request>
              CHANGING
                cr_data = ls_changeset_response-entity_data
            ).
            ls_changeset_response-headers = <fs_changeset_request>-request_headers.
            ls_changeset_response-operation_no = <fs_changeset_request>-operation_no.
            APPEND ls_changeset_response TO ct_changeset_response.
          ENDIF.

        WHEN OTHERS.
      ENDCASE.
    ENDLOOP.

  endmethod.

示例3:$batch changeset,混合Create,Update数据请求

URL: /sap/opu/odata/sap/ZTOM_GS1_SRV/$batch;

POST方法;

Request Body:

示例:

--batch
Content-Type: multipart/mixed; boundary=changeset

--changeset
Content-Type: application/http
Content-Transfer-Encoding: binary

POST ZT_SCARRSet HTTP/1.1
Content-Type: application/json
Accept: application/json

{
  "d" : {
    "__metadata" : {
      "uri" "<host>/sap/opu/odata/sap/ZTOM_GS1_SRV/ZT_SCARRSet",
      "type" "ZTOM_GS1_SRV.ZT_SCARR"
    },
    "Carrid" "ZK",
    "Carrname" "test1 Airlines",
    "Currcode" "USD",
    "Url" "http://www.zk.com"
  }
}

--changeset
Content-Type: application/http
Content-Transfer-Encoding: binary

PUT ZT_SCARRSet(Carrid='ZH') HTTP/1.1
Content-Type: application/json
Accept: application/json

{
  "d" : {
    "__metadata" : {
      "uri" "<host>/sap/opu/odata/sap/ZTOM_GS1_SRV/ZT_SCARRSet",
      "type" "ZTOM_GS1_SRV.ZT_SCARR"
    },
    "Carrid" "ZH",
    "Carrname" "change Airlines",
    "Currcode" "USD",
    "Url" "http://www.zh.com"
  }
}

--changeset--

--batch--

示例: /IWBEP/IF_MGW_APPL_SRV_RUNTIME~CHANGESET_PROCESS方法实现Update

 

       WHEN 'UE'.
          "request update
          DATA:lo_request_u TYPE REF TO /iwbep/if_mgw_req_entity_u.
          "执行更新
          lo_request_u ?= <fs_changeset_request>-request_context.
          lv_entity_type = lo_request_c->get_entity_type_name( ).
          IF lv_entity_type = 'ZT_SCARR'.
            "how to get free data type
            CREATE DATA lo_data TYPE scarr.
            ASSIGN lo_data->* TO <fs_data>.
            zt_scarrset_update_entity(
              EXPORTING
                iv_entity_name = lv_entity_name
                iv_entity_set_name = lv_entity_set_name
                iv_source_name = lv_source_name
                it_key_tab = lt_key_tab
                io_tech_request_context = lo_request_u
                it_navigation_path = lt_navigation_path
                io_data_provider = <fs_changeset_request>-entry_provider
              IMPORTING
                er_entity = <fs_data>
            ).
          ENDIF.

示例4:$batch changeset,混合Create,Update,Delete数据请求

--batch
Content-Type: application/http
Content-Transfer-Encoding: binary

GET ZT_SCARRSet(Carrid='AA') HTTP/1.1
Accept: application/json


--batch
Content-Type: multipart/mixed; boundary=changeset

--changeset
Content-Type: application/http
Content-Transfer-Encoding: binary

POST ZT_SCARRSet HTTP/1.1
Content-Type: application/json
Accept: application/json

{
  "d" : {
    "__metadata" : {
      "uri" "<host>/sap/opu/odata/sap/ZTOM_GS1_SRV/ZT_SCARRSet",
      "type" "ZTOM_GS1_SRV.ZT_SCARR"
    },
    "Carrid" "ZF",
    "Carrname" "test1 Airlines",
    "Currcode" "USD",
    "Url" "http://www.zf.com"
  }
}

--changeset
Content-Type: application/http
Content-Transfer-Encoding: binary

PUT ZT_SCARRSet(Carrid='ZH') HTTP/1.1
Content-Type: application/json
Accept: application/json

{
  "d" : {
    "__metadata" : {
      "uri" "<host>/sap/opu/odata/sap/ZTOM_GS1_SRV/ZT_SCARRSet",
      "type" "ZTOM_GS1_SRV.ZT_SCARR"
    },
    "Carrid" "ZH",
    "Carrname" "changes Airlines",
    "Currcode" "USD",
    "Url" "http://www.zh.com"
  }
}

--changeset
Content-Type: application/http
Content-Transfer-Encoding: binary

DELETE ZT_SCARRSet(Carrid='ZE') HTTP/1.1
Content-Type: application/json
Accept: application/json


--changeset--

--batch--

示例:/IWBEP/IF_MGW_APPL_SRV_RUNTIME~CHANGESET_PROCESS方法实现Delete

        WHEN 'DE'.
          "request delete
          DATA:lo_request_d TYPE REF TO /iwbep/if_mgw_req_entity_d.
          "执行删除
          lo_request_d ?= <fs_changeset_request>-request_context.
          lv_entity_type = lo_request_c->get_entity_type_name( ).
          IF lv_entity_type = 'ZT_SCARR'.
            DATA:lt_keys TYPE /iwbep/t_mgw_tech_pairs.
            DATA:ls_keys LIKE LINE OF lt_keys.
            lt_keys = lo_request_d->get_keys( ).
            LOOP AT lt_keys INTO ls_keys.
              CLEAR ls_key_tab.
              ls_key_tab-name = ls_keys-name.
              ls_key_tab-value = ls_keys-value.
              APPEND ls_key_tab TO lt_key_tab.
            ENDLOOP.
            "调用复位义方法
            zt_scarrset_delete_entity(
              EXPORTING
                iv_entity_name = lv_entity_name
                iv_entity_set_name = lv_entity_set_name
                iv_source_name = lv_source_name
                it_key_tab = lt_key_tab
                io_tech_request_context = lo_request_d
                it_navigation_path = lt_navigation_path
            ).
          ENDIF.
          "删除没有返回,没有exception,即删除成功
          ls_changeset_response-operation_no = <fs_changeset_request>-operation_no.
          APPEND ls_changeset_response TO ct_changeset_response.

  • 14
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

偶是不器

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

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

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

打赏作者

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

抵扣说明:

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

余额充值