SAP开发Restful api 接口(不使用PO/PI,使用SICF)
1.自定义REST处理程序(主要定义路由和重写X-CSRF-Token检查)
1.1.SE24创建类继承CL_REST_HTTP_HANDLER
1.2.重写以下方法(IF_REST_APPLICATION~GET_ROOT_HANDLER & HANDLE_CSRF_TOKEN)。
如果全是GET、HEAD、OPTIONS,不使用POST、PUT、DELETE等http方法,可不重写HANDLE_CSRF_TOKEN。
IF_REST_APPLICATION~GET_ROOT_HANDLER 主要是定义访问路由及处理类,iv_template 表示路径,iv_handler_class表示处理类。
method IF_REST_APPLICATION~GET_ROOT_HANDLER.
*CALL METHOD SUPER->IF_REST_APPLICATION~GET_ROOT_HANDLER
*  RECEIVING
*    RO_ROOT_HANDLER =
*    .
" 重载处理请求路径
data(lo_router) = new cl_rest_router( ).
" iv_template 设置 Path
" iv_handler_class 设置handler class
"获取用户Token
lo_router->attach( iv_template = `/UserToken` iv_handler_class = 'ZCL_SGC_USERAUTH_RESOURCE' ).
"10.10.10.22:8000/sap/zrest/MaterialTypes?sap-client=330
lo_router->attach( iv_template = `/MaterialTypes` iv_handler_clas s = 'ZCL_SGC_MATTYPE_RESOURCE' ). "物料类型
"10.10.10.20:8000/sap/zrest/Materials?sap-
client=800&MatType=Z001&Search=900122&PageIndex=1&PageSize=100  Searc h:物料编码OR客户OR终端客户
lo_router->attach( iv_template = `/Materials` iv_handler_class = 'ZCL_SGC_MATERIAL_RESOURCE' ).    "物料
*    lo_router->attach( iv_template = `/Materials/{MatType:[Z][0-
9][0-9][0-9]}/{Search:}/{PageIndex:[1-9][0-9]*}/{PageSize:[1-9][0-
9]*}` iv_handler_class = 'ZCL_SGC_MATERIAL_RESOURCE' ).
*    lo_router->attach( iv_template = `/Materials/MatType{\=?}{MatTyp e:[Z][0-9][0-9][0-
9]}{&}Search{A:[\=]}{Search}{&}PageIndex{\=?}{PageIndex:[1-9][0-
9]*}{&}PageSize{\=?}{PageSize:[1-9][0-9]*}` iv_handler_class =
*'ZCL_SGC_MATERIAL_RESOURCE' ).
ro_root_handler = lo_router.
endmethod.
HANDLE_CSRF_TOKEN方法是重写CSRF检查,关于CSRF请参考answers.sap/questions/10288247/in-create-csrf-token-validation-failed.html,我直接返回abap_true绕过,简单粗暴
METHOD handle_csrf_token.
DATA:
lv_method TYPE string,
lv_csrf_token TYPE string,
lv_csrf_token_valid TYPE abap_bool VALUE abap_false.
lv_method = io_request->get_method( ).
lv_csrf_token = io_request->get_header_field( if_rest_request=>gc _header_csrf_token ).
CASE lv_method.
WHEN if_rest_request=>gc_method_get OR
if_rest_request=>gc_method_head OR
if_rest_request=>gc_method_options.
lv_csrf_token = to_lower( lv_csrf_token ).
IF lv_csrf_token = 'fetch' ##no_text.
io_response->set_header_field(
iv_name  = if_rest_request=>gc_header_csrf_token
iv_value =  io_csrf_handler->get_csrf_token( )
).
ENDIF.
WHEN OTHERS.
lv_csrf_token_valid = abap_true."io_csrf_handler->validate_cs rf_token( lv_csrf_token )."简单返回True,绕过csrf
IF lv_csrf_token_valid <> abap_true.
io_response->set_header_field(
iv_name  = if_rest_request=>gc_header_csrf_token
iv_value = 'Required' ) ##no_text.
RAISE EXCEPTION TYPE cx_rest_resource_exception
EXPORTING
status_code = cl_rest_status_code=>gc_client_error_forb idden
textid      = cx_rest_resource_exception=>csrf_token_va lidation_failed.
ENDIF.
ENDCASE.
ENDMETHOD.
2.自定义请求处理类继承CL_REST_RESOURCE,可按实际照需求重写GET,PUT,POST
等http的操作方法。
class ZCL_SGC_MATTYPE_RESOURCE definition
public
inheriting from CL_REST_RESOURCE
final
create public .
public section.
methods IF_REST_RESOURCE~GET
redefinition .
methods IF_REST_RESOURCE~POST
redefinition .
protected section.
private section.
ENDCLASS.
CLASS ZCL_SGC_MATTYPE_RESOURCE IMPLEMENTATION.
* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Public Method ZCL_SGC_MATTYPE_RESOURCE->IF_REST_RESOURCE ~GET
* +-------------------------------------------------------------------------------------------------+
* +--------------------------------------------------------------------------------------</SIGNATURE>
method IF_REST_RESOURCE~GET.
*CALL METHOD SUPER->IF_REST_RESOURCE~GET
*    .
" 实现GET请求响应
DATA: "serializer TYPE REF TO zcl_trex_json_serializer,
"LO_RES TYPE REF TO ZCL_SGC_REST_RESPONSE,
lv_offset type i,lv_size type i,lv_page type i,
lv_search type string,
lv_json TYPE string.
DATA: BEGIN OF ls_json,
MTART TYPE T134T-MTART,    "物料类型
MTBEZ TYPE T134T-MTBEZ,    "物料类型描述
END OF ls_json.
DATA: lt_json LIKE STANDARD TABLE OF ls_json.
data(lv_client)  = mo_request->GET_URI_QUERY_PARAMETER( iv_name = 'sap-client' ).
DATA(LO_RES) = NEW ZCL_SGC_REST_RESPONSE( ).
"LO_RES->RES_MSG = LV_SEARCH1.
LO_RES->RES_CODE = 'E'.
lo_res->RES_COUNT = 0.
LO_RES->RES_PAGEINDEX = 1."LV_PAGE.
LO_RES->RES_PAGESIZE = 1."LV_SIZE.
LO_RES->RES_PAGETOTAL = 1.
restful接口调用实例
LO_RES->REQ_METHOD = MO_REQUEST->GET_METHOD( ).
LO_RES->REQ_URI = MO_REQUEST->GET_URI( ).
"LO_RES->RES_MSG = |{ SY-LANGU }|.
DATA(LV_SEARCH1) = |{ '%' }{ LV_SEARCH }{ '%' }|.
SELECT  FROM T134T AS A
FIELDS A~MTART,A~MTBEZ
WHERE A~SPRAS = '1'"@SY-LANGU 始终是E,不知道原因
AND A~MTART LIKE 'Z%'
INTO CORRESPONDING FIELDS OF TABLE @LT_JSON.
DATA(LV_REPLACE) = |{ 'SGC' }{ SY-DATUM }{ SY-UZEIT }|.
IF SY-SUBRC = 0 AND LT_JSON[] IS NOT INITIAL.