【SAP-MOM项目】二、接口对接(中)

目录

章节介绍:

开发RESTFUL接口原因:

开发RESTFUL接口步骤:

一、SE37开发接口

二、SE24创建类

三、SICF服务配置

四、POSTMAN调用接口

五、参数文档结构

结尾:


章节介绍:

之前已经和大家分享了SAP系统和MOM系统的整体设计,以及数据交互时系统的接口对接。上个章节重点讲的是RFC接口,当外围系统调用SAP的RFC接口时,SAP如何创建RFC接口、如何提供不同的参数结构文档给外围系统,这次我们来讲解另一种接口类型,RESTFUL接口类型,这也是SAP和外围系统对接时非常常用的接口类型。

因为本次项目中接口对接类型比较多,所以整个第二章节和大家分享SAP和MOM的接口对接时,我分成了三个内容来讲,分别是:

接口对接(上)------外围系统调用SAP的RFC接口,SAP如何创建RFC接口

接口对接(中)------外围系统调用SAP的RESTFUL接口,SAP如何创建restful接口

接口对接(下)------SAP调用外围系统的RESTFUL接口,SAP如何写代码调用

这次我们来讲【接口对接(中)------外围系统调用SAP的RESTFUL接口,SAP如何创建restful接口】

开发RESTFUL接口原因:

先来讲为什么我将这个接口做成了restful接口

如果大家有看我的前面几篇文章,就可以知道我在做这个项目时,时间是非常紧迫的,我优先选择的都是RFC接口,那为什么我偏偏将这个接口设计成了restful接口呢?答案就是参数类型问题。

两个系统需要传输的数据简化后如下:

在SAP系统中,这种关系的数据很多,AUFK和RESB表,EKKO和EKPO表,MSEG和MKPF表,都是可以通过A表的一个字段和B表做连接就可以获取对应关系。但是MOM系统反馈说,如果SAP返回两个表的话,MOM系统就不好处理两个表的数据,需要我这边将两个表放在一个表里面返回。因为我本身对JAVA不太熟悉,所以我没有什么可以提供的建议,那就开做吧。

MOM想要的SAP返回数据是像下面这种表结构:

放到SAP系统中,如下:

我们在RFC接口里面引用这个结构,在表参数里面,使用LIKE和TYPE都是不行的,分别是下面这样的报错:

LIKE:只能参考扁平结构

TYPE: RFC 中仅允许使用含扁平行结构的表

原因就是因为这个接口是远程RFC接口的话,RFC接口的表参数只能是扁平的结构类型,不能有下层的表展开

这时候,一种简单的处理方式,就是可以将表参数放到导出参数这里来,如下:

这时候,这个远程RFC接口是能够正常处理数据的,但是SAP系统会有一个警告:

警告是:T_TAB(类型 ZPPS0019)可削弱 RFC 中的性能(通过典型序列化)

总所周知,SAP系统中,警告约等于没警告,并且因为接口的数据没多少,我对这个接口的性能是不太在意的。

只不过我在使用POSTMAN测试的时候,发现了一个问题:如果像上面这样设置的话,SAP传出的数据是乱码(忘了保存截图了)。

所以我直接没让MOM开发接收数据测试了,我还是老老实实重新设计成RESTFUL接口吧。

开发RESTFUL接口步骤:

一、SE37开发接口

首先将接口设置成常规函数:

导入参数如下:

导出参数如下:

导入导出的参数设置都大差不差,就只是将远程RFC接口变成了常规函数。

二、SE24创建类

接下来构建类对象:

创建时的界面:

然后会让我们选择包,我们不放在本地包里面,因为我们之后要传到正式机的。

创建后如下:

接口使用IF_HTTP_EXTENSION

属性是自带的:

方法使用IF_HTTP_EXTENSION~HANDLE_REQUEST

方法的参数是SERVER

类型如下:

类型里面放的就可以理解为传入传出参数了,点进去看一下:

上面的设置对于每个restful接口的设计来说,都是大差不差基本一致的,就是类型那里需要设置成我们需要的样子就行。

接下来,我们点击方法,进入源代码,这里就是实现逻辑的地方:

代码如下,可以直接复制使用:

复制代码
method IF_HTTP_EXTENSION~HANDLE_REQUEST.

    DATA: ls_input   TYPE  ty_input.
    DATA:T_TAB TYPE ZPPS0019.
    TYPES:BEGIN OF TY_OUTPUT,
          T_TAB  TYPE ty_out,
      E_TYPE TYPE BAPI_MTYPE,
      E_MSEG TYPE BAPI_MSG,
      END OF TY_OUTPUT.
      DATA:LS_OUTPUT TYPE TY_OUTPUT,
          ls_message TYPE uj0_s_message.
    DATA: lv_verb TYPE string,
          lv_json TYPE string.
    DATA: lo_request      TYPE REF TO if_http_request.
    DATA: lt_fields TYPE tihttpnvp,
          lv_data   TYPE string.
    FIELD-SYMBOLS: <fs_field>       LIKE LINE OF lt_fields.

    lo_request = server->request.
    "Only handles Post method
    lv_verb = lo_request->get_header_field( name = '~request_method' ).
    "get HEADER fields
    lo_request->get_header_fields( CHANGING fields = lt_fields ).   "Header fields
    "body
    lv_data = lo_request->if_http_entity~get_cdata( ).

    REPLACE ALL OCCURRENCES OF cl_abap_char_utilities=>cr_lf IN lv_data WITH space.
    REPLACE ALL OCCURRENCES OF cl_abap_char_utilities=>horizontal_tab IN lv_data WITH space.
    REPLACE ALL OCCURRENCES OF cl_abap_char_utilities=>vertical_tab IN lv_data WITH space.
    REPLACE ALL OCCURRENCES OF cl_abap_char_utilities=>newline IN lv_data WITH space.
    REPLACE ALL OCCURRENCES OF '#' IN lv_data WITH space.
    TRY.
        /ui2/cl_json=>deserialize(
         EXPORTING
           json = lv_data
           pretty_name = /ui2/cl_json=>pretty_mode-camel_case
           CHANGING data = ls_input
                  ).
*      CATCH cx_root.
         CATCH cx_root INTO DATA(lx_error).
      " 更好的错误处理
      ls_message-MSGTY = 'E'.
      ls_message-message = lx_error->get_text( ).
    ENDTRY.

    CASE lv_verb.
      WHEN 'POST'.
        CALL FUNCTION 'ZPP_IMS_ORDERNEW1'
          EXPORTING
            I_WERKS       = ls_input-i_werks
            I_GLTRP       = ls_input-i_gltrp
            I_FEVOR       = ls_input-i_fevor
            I_TEMPS       = ls_input-i_temps
            I_TEMPE       = ls_input-i_tempe
         IMPORTING
           E_TYPE        = ls_output-e_type
           E_MSEG        = ls_output-e_mseg
           T_TAB         = T_TAB
                  .

" 如果没有数据,设置空表
      IF T_TAB IS INITIAL.
        CLEAR ls_output-t_tab.
        ELSE.
          APPEND LINES OF T_TAB TO ls_output-t_tab.
      ENDIF.

      WHEN OTHERS.
        "如果不是get请求,则返回错误
        server->response->set_status( code = 405 reason = '请使用POST方法' ).
        RETURN.
    ENDCASE.

***
try.
    lv_json = /ui2/cl_json=>serialize(
    data = ls_output
          compress = abap_true
          pretty_name = /ui2/cl_json=>pretty_mode-none
           ).
     CATCH cx_root INTO lx_error.
      " 序列化错误处理
      lv_json = `{"error": "序列化输出失败"}`.
  ENDTRY.
    server->response->set_status( code = 200 reason = 'Ok' ).
    server->response->set_content_type( 'application/json' ).
    server->response->set_cdata( data = lv_json ).

  endmethod.

这里有两个地方需要注意:

第一个地方就是我们需要在这里重新声明一下参数

第二个地方就是我们调用常规函数的地方是这里:

上面的代码写成这样也是可以的,反正就是这些参数在赋值嘛。

反正最后,返回参数最后起作用的语句是这个:

类里面检查没有语法报错后,就可以开始进行SICF服务配置了。

三、SICF服务配置

这一步是让我们的接口真正成为restful接口,步骤如下:

首先使用事务代码SICF进入下面这个界面:

右键点击这个sap,选择新的子元素

会弹出下面这个消息,不用管,点勾

在创建的时候像下面这样选择:

服务是管理服务,描述根据自己要求来设置

服务数据参数如下:

登录数据如下:

用户名和密码都一起配置上去,外围系统连接接口的时候就不需要输入密码和用户名

处理器清单这里就填写我们上一步使用SE24创建的那个类的名字

错误页的参数如下:

管理页如下:

配置完后进行保存,可以看到我们刚才创建的服务是灰色的,界面如下:

然后我们来激活这个服务,右键点击:

激活服务:

激活服务后,测试服务:

测试的界面如下:

四、POSTMAN调用接口

虽然提示的是该页面无法正常运作,但这是正常的,上面那个就是接口地址。我们直接在postman里面调用一下试试看。

好了,看来我们成功创建了sap系统的restful接口,真棒。

五、参数文档结构

再看一下接口参数文档吧:

结尾:

最后也是一些注意点:

1、 SAP的RFC接口和RESTFUL接口,他们对应的端口号一般是不一致的,如果接口联不通的话,这个要和BASIS顾问确认或者和公司网络管理的同事确认一下;

2、在配置服务时,那个用户名和参数也要设置完整,如果对方保存没权限的话,要设置权限高一点的账号,可以直接修改,不用包请求。

那么本章就结束啦,下一章我们接着讲解【接口对接(下)------SAP调用外围系统的RESTFUL接口,SAP如何写代码调用】

相关推荐
零度@2 小时前
专为 Java 开发者 整理的《Python编程:从入门到实践》前8章核心内容
java·开发语言·windows·python
规划酱2 小时前
Arcgis中pip安装ezdxf部分GIS有pyparsing安装失败的情况处理
python·arcgis·pip·规划酱
witAI2 小时前
**AI漫剧一键生成2025指南,解锁零门槛动画创作新体验*
人工智能·python
ktoking2 小时前
Stock Agent AI 模型的选股器实现 [七]
人工智能·python·django
nbsaas-boot2 小时前
架构设计怎么做:一套可复用、可落地的方法论
java·开发语言·微服务
骆驼爱记录2 小时前
Word表格题注自动设置全攻略
开发语言·c#·自动化·word·excel·wps·新人首发
wbs_scy2 小时前
C++:智能指针完全指南(原理、用法与避坑实战,从 RAII 到循环引用)
开发语言·c++·算法
无人装备硬件开发爱好者2 小时前
Python + Blender 5.0 几何节点全栈实战教程1
开发语言·python·blender
u0109272712 小时前
C++中的对象池模式
开发语言·c++·算法