SAP OData(一)简单创建与发布odata

一,事务码SEGW

该事务码以project的概念来组织OData服务,并以project为整体来生成并发布。系统中预置了一些project可供我们参考,例如crm_opportunity,crm_task等等。

新建project,我们需要填写project名字以及所属package,还需要关注的是下图ProjectType和GenerationStrategy的可选项。

SAP OData(一)简单创建与发布odata_第1张图片

Project Type:1&2主要区别是维护注解的方式不同,4为OData4.0

Generate Strategy:1-Standard 2-for OData4.0

二,EntityType

EntityType可以理解为接口的结构,有点类似PI中配置的MessageType。右键【Entity Types】创建,或者导入(表,结构)或参考CDS

Properties:是结构的各个字段。

NavigationProperties:可选,建立Association之后会出现,用于entity之间导航。

SAP OData(一)简单创建与发布odata_第2张图片

【Name】暴露到接口的字段名,区分大小写。注意与后面的AbapFieldName用途各异

【IsKey】是否关键字

【EdmType】Edm预定义的元数据

【Precision】有效数位数;【Scale】小数位数;如123.45,有效位数5小数位数2

【MaxLength】用于限定字符型长度,abap ddic中的char和string都是对应ODataEntityType中的Edm.String

【UnitProperty】用于指定数量或金额列所参考的单位字段

【Create,Update】OData接口字段行为的限制,例如主键字段通常可创建,不可修改

【Sorted】字段是否支持$orderby操作

【Nullable】edm属性,Null可作为字段初始值,如主键字段不可空

【Filter】字段支持OData的$filter操作

【Lable】文本描述;【LableEdit】可以参考数据元素等带出文本描述

【CompType】用于嵌入下一级结构,此时EdmType就不能填了;DataModel右键--创建--CompType也是结构,不过没有Key字段指定

【ABAP Field Name】【ABAPType】Gateway内部运行时使用,为entity生成的abap数据结构是按这个名字,在后续abap编程也是用这个字段名

【Semantics】元数据的语义

 
 

三,EntitySet

EntitySet都是基于EntityType的,就像表基于结构一样,EntitySet也是接口暴露出来的对象,该对象又具有增删改查等动作

【Lable】【LableEdit】【Semantics】与上一小节一样

【增,改,删】接口实体允许动作

【Pageable】分页

【Address】允许用URL直接访问对象,否则只能从父节点开始逐步导航到对象

【Search】支持OpenSearch,在Get请求中使用查询条件

【Subscription】允许订阅,在DataObject改变时会收到通知

【RequiredFilter】对象不能直接访问,必须带$filter表达式

 
ItemSet 
Item 

四,生成运行时对象

在创建EntitySet时,下图Service Implementation会自动生成对应同名项目。

右键--生成运行时对象,系统会根据已定义的EntitySet生成ModelProvider类(MPC,MPC_EXT)以及DataProvider类(DPC,DPC_EXT);

MPC模型提供类将上面配置字段行为等数据对象化,帮助生成metadata。我们通常不用修改它们,改上面配置重新生成就好

DPC数据提供类中生成的方法分别对应了【Create,Delete,GetEntity,GetEntitySet,Update】;

_DPC为抽象父类,如果实体已经确定了数据源如CDS,生成方法将具有取数内容,这些方法是protected可继承重写的

_DPC_EXT为子类可以重写方法来实现我们自己的逻辑。Odata重生成不会覆盖*_EXT方法

服务对象_SRV,用于注册服务,服务路径中也能看到它 https://.../sap/opu/odata/sap/Y_TEST_ODATA4_SRV/ItemSet

模型对象_MDL,注释模型_ANNO_MDL通常来自CDS的生成

SAP OData(一)简单创建与发布odata_第3张图片

五,重写方法

不同的HTTP方法会调用不同的entity方法,GET会根据参数不同调用get_entity或get_entityset,POST会调用create_entity创建一个entity,PUT调用update_entity用于更新一个entity注意没传值的字段会被覆盖为空,PATCH会先调用get_entity查到一个entity(查不到直接报错返回)然后调用update_entity据说只会修改报文中给定的值不会出现覆盖为空值,DELETE调用delete_entity删除一个entity。

5.1 重写get_entityset

该方法是返回一个实体集的(多行),我们重写*_DPC_EXT~*_GET_ENTITYSET,默认返回xml报文,想要json用【?$format=json】

      • IT_FILTER_SELECT_OPTIONS该参数用于OData的$filter方法【http://..._srv/entityset?$filter=(MATNR eq 'XA01' and QUANT le '2')】注意字段名大小写也要根据EntityType,eq/and/or/not等操作符必须小写,eq不能用=来代替,其他操作符还有【ne不等,lt小于,le小等,gt大于,ge大等】。注意IT_FILTER_SELECT_OPTIONS不支持or操作符,因为它会把条件拆成但是字段之间的or/and却没有办法表示,对于这种情况请直接用参数IV_FILTER_STRING,因为它就是URL中原始的没解析的filter条件
      • IS_PAGING用于限定取数位置【http://..._srv/entityset?$inlinecount=allpages&$top=1&$skip=2】,$top取多少行,$skip跳过多少行再取数,URL后面的指令都已$开始,指令之间用&连接
//select * into table lt_db from ytest.
IF is_paging IS NOT INITIAL.
    et_entityset = VALUE #( FOR ls_db IN lt_db FROM is_paging-skip + 1 TO is_paging-skip + is_paging-top ( docno = ls_db-docno
                                                itmno = ls_db-itmno
                                                matnr = ls_db-matnr
                                                detailinfo-quant = ls_db-quant
                                                detailinfo-unit  = ls_db-unit ) ).
     
ENDIF.
      • IT_KEY_TAB:主键值,在本方法get_entityset中这个参数好像没值,在下面get_entity取单一entity时有值
      • IT_ORDER用于支持$orderby方法【http://..._srv/entityset?$orderby=ITMNO,QUANT】,默认为asc升序,可以显式为某个字段指定为降序排列【$orderby=ITMNO desc】注意中间的空格因URLcode编码要转换为【%20】
DATA:lt_otab TYPE abap_sortorder_tab. 
lt_otab = VALUE #( for ls_order in it_order ( name = ls_order-property descending = cond #( when ls_order-order eq 'desc' then abap_true else abap_false ) ) ). 
SORT et_data BY (lt_otab). //排序结果表

5.2 重写get_entity

该方法是返回单个实体(单行),在URL中指定实体的Key值就会触发这个方法【http://..._srv/entityset(DOCNO='1001',ITMNO='0020')】,每个KeyField都必须指定值(因为要唯一确定一条记录),否则服务出错。如果Key只有一个字段可以简化成【http://..._srv/entityset('1001'】

URL中指定Key值会转化为参数IT_KEY_TAB中的键值对

5.3 重写create_entity

注意只能处理一个entity,http方法使用POST,body内容可以是JSON格式也可以是XML,我们可以用get_entity得到的报文改一下

SAP OData(一)简单创建与发布odata_第4张图片

在方法中使用data_provider将报文直接反序列化为entity,然后进行常规存表等操作

DATA: ls_entity LIKE er_entity.
DATA: ls_return TYPE bapiret2,
      lt_return TYPE STANDARD TABLE OF bapiret2.

io_data_provider->read_entry_data( IMPORTING es_data = ls_entity ).
"写入数据库,此外还要将这条数据返回给消费端,参考get_entity即可"
 
"$. Region Error Msg return
ls_return-type    = 'E'.
ls_return-id      = 'F2'.
ls_return-number  = '001'.
ls_return-message = 'Save failed, line item may already exist'.
APPEND ls_return TO lt_return.

mo_context->get_message_container( )->add_messages_from_bapi(
          it_bapi_messages = lt_return
          iv_determine_leading_msg = /iwbep/if_message_container=>gcs_leading_msg_search_option-first ) .
RAISE EXCEPTION TYPE /iwbep/cx_mgw_busi_exception
  EXPORTING
    textid            = /iwbep/cx_mgw_busi_exception=>business_error
    message_container = mo_context->get_message_container( ).
"$. Endregion Error Msg return

5.4 重写update_entity

该方法用于更新一个entity,更新entity的操作对应的http方法参考SEGW建模5 OData更新操作,首先URL中要指定Key值【http://..._srv/entityset(DOCNO='1001',ITMNO='0020')】,然后报文body里面包含了entity数据(与create类似的body)

5.5 重写delete_entity

URL中要指定Key值【http://..._srv/entityset(DOCNO='1001',ITMNO='0020')】,一般不需要body

六,基于RFC生成ODATA

首先创建RFC省略,在SEGW右键DataModel--Import--RFC/BORinterface,填写EntityType名,选择RFC,RFC的参数结构会带出如下图显示,选择需要生成的结构

SAP OData(一)简单创建与发布odata_第5张图片

结构导入为EntityType之后需要设定KeyField,

七,发布OData服务

进入事务码/n/IWFND/MAINT_SERVICE,点击按钮【Add Service】,我们看到如下图右侧的窗口。

SAP OData(一)简单创建与发布odata_第6张图片

首先【系统别名】填写Local,表示在本系统搜索Odata服务的实现;【技术服务名称】填写前面生成的Odata服务名;点击3所查到的OData服务会显示在4,选中4处的服务并点击按钮5,在弹出的窗口中填写开发包并保存即可。

如果勾选【联合部署】即本地部署不再有路由配置(不勾选则填系统别名),然后点击【添加所选服务】

系统别名配置:spro--SAP NetWeaver--SAP Gateway--OData Channel--Configuration--Connection Settings--SAP Gateway to SAP System--Manage SAP System Aliases

SAP OData(一)简单创建与发布odata_第7张图片

回到维护服务页面,找到刚创建的服务,Int通讯框架节点可以看到新服务在SICF中的位置,点击GatewayClient。如果要删除服务,先需要将SICF中的服务节点删掉,然后在这个维护服务页面点【删除服务】

在Gateway Client中,我们把URL后面改为$metadata可以获得接口的描述文件(类似wsdl),点击EntitySet选择后执行,可以取得接口数据。

SAP OData(一)简单创建与发布odata_第8张图片

八,查看日志

错误日志事务码:/N/IWFND/ERROR_LOG

Gateway应用日志:/N/IWFND/APPS_LOG

系统日志:SM21

你可能感兴趣的:(SAP,sap)