SAP 如何提供 Http Service
如果要將 SAP 應(yīng)用程序服務(wù)器 (application server)作為 http 服務(wù)提供者,需要定義一個(gè)類,這個(gè)類必須實(shí)現(xiàn) IF_HTTP_EXTENSION 接口。IF_HTTP_EXTENSION 接口只有一個(gè)方法 HANDLE_REQUEST。自定義的這個(gè)類必須實(shí)現(xiàn) HANDLE_REQUEST 方法。HANDLE_REQUEST 方法的 SERVER 參數(shù)是一個(gè) http server 對(duì)象 (類型為 ICF 框架的 IF_HTTP_SERVER 接口)。http server 對(duì)象具有的屬性和方法對(duì)請(qǐng)求和響應(yīng)進(jìn)行處理。 然后使用 SICF 事務(wù)碼創(chuàng)建服務(wù),并且將處理器(handler)設(shè)定為自定義類。 客戶端就可以訪問這個(gè)服務(wù)。REST
而是Resource Representational State Transfer的縮寫:通俗來(lái)講就是:資源在網(wǎng)絡(luò)中以某種表現(xiàn)形式進(jìn)行狀態(tài)轉(zhuǎn)移。分開來(lái)講:
1.Resource:資源,即數(shù)據(jù)(網(wǎng)絡(luò)的核心)。
2.Representational:某種表現(xiàn)形式,比如用JSON,XML,JPEG等;
3.State Transfer:狀態(tài)變化。通過(guò)HTTP動(dòng)詞實(shí)現(xiàn)。
REST描述的是在網(wǎng)絡(luò)中client和server的一種交互形式;REST本身不實(shí)用,實(shí)用的是如何設(shè)計(jì) RESTful API(REST風(fēng)格的網(wǎng)絡(luò)接口;
Server提供的RESTful API中,URL中只使用名詞來(lái)指定資源,原則上不使用動(dòng)詞。“資源”是REST架構(gòu)或者說(shuō)整個(gè)網(wǎng)絡(luò)處理的核心。
用HTTP協(xié)議里的動(dòng)詞來(lái)實(shí)現(xiàn)資源的添加,修改。
Server和Client之間傳遞某資源的一個(gè)表現(xiàn)形式,比如用JSON,XML傳輸文本,或者用JPG,WebP傳輸圖片等。
用 HTTP Status Code傳遞Server的狀態(tài)信息。比如最常用的 200 表示成功,500 表示Server內(nèi)部錯(cuò)誤等。
Web端不再用之前典型的PHP或JSP架構(gòu),而是改為前段渲染和附帶處理簡(jiǎn)單的商務(wù)邏輯。Web端和Server只使用上述定義的API來(lái)傳遞數(shù)據(jù)和改變數(shù)據(jù)狀態(tài)。格式一般是JSON。
對(duì)于資源的具體操作類型,由HTTP動(dòng)詞表示。常用的HTTP動(dòng)詞有下面五個(gè)(括號(hào)里是對(duì)應(yīng)的SQL命令):
1.GET(SELECT): 從服務(wù)器獲取資源(一項(xiàng)或多項(xiàng))
2.POST(CREATE): 在服務(wù)器新建一個(gè)資源
3.PUT(UPDATE): 在服務(wù)器更新資源(客戶端提供改變后的完整資源)
4.PATCH(UPDATE): 在服務(wù)器更新資源(客戶端提供改變的屬性)
5.DELETE(DELETE):從服務(wù)器刪除資源。
比如:
GET /zoos:列出所有動(dòng)物園
POST /zoos:新建一個(gè)動(dòng)物園
GET /zoos/ID:獲取某個(gè)指定動(dòng)物園的信息
PUT /zoos/ID:更新某個(gè)指定動(dòng)物園的信息(提供該動(dòng)物園的全部信息
PATCH /zoos/ID:更新某個(gè)指定動(dòng)物園的信息(提供該動(dòng)物園的部分信息)
DELETE /zoos/ID:刪除某個(gè)動(dòng)物園
GET /zoos/ID/animals:列出某個(gè)指定動(dòng)物園的所有動(dòng)物
DELETE /zoos/ID/animals/ID:刪除某個(gè)指定動(dòng)物園的指定動(dòng)物
SAP 發(fā)布HTTP接口(RESTful方式)
一、代碼過(guò)程
使用SE24創(chuàng)建一個(gè)類 ZLOCAL_CL_REST,并且繼承超類 CL_REST_HTTP_HANDLER 。
重構(gòu)方法 IF_REST_APPLICATION~GET_ROOT_HANDLER,HANDLE_CSRF_TOKEN,其中HANDLE_CSRF_TOKEN 是用于token驗(yàn)證的,如果不需要token驗(yàn)證則直接重構(gòu)即可,不需要代碼,需要驗(yàn)證的話可以保留,無(wú)需重構(gòu)。
重構(gòu)的代碼,其中/GET/PO 為接口路徑,ZLOCAL_CL_GET_PURCHASEORDER 為接口類
TOKEN 驗(yàn)證 如果需要進(jìn)行驗(yàn)證的,則不需要重構(gòu)方法HANDLE_CSRF_TOKEN,在原有的代碼邏輯下,使用GET 方法時(shí),在發(fā)送請(qǐng)求時(shí)登入了 Authentication賬號(hào)密碼即可正確獲取token。不需要token則直接重構(gòu)即可,不需要代碼。
上述完成后,再次使用SE24 創(chuàng)建一個(gè)類,類名為前面的接口類 ZLOCAL_CL_GET_PURCHASEORDER.并且繼承超類 CL_REST_RESOURCE。
繼承后,根據(jù)接口的不同調(diào)用方式,重構(gòu)相應(yīng)的方法
這里使用GET方式進(jìn)行演示
METHOD if_rest_resource~get.
*CALL METHOD SUPER->IF_REST_RESOURCE~GET
* .
DATA: lv_output_json TYPE string.
DATA: lv_ebeln TYPE ebeln.
DATA: BEGIN OF ls_out,
ebeln TYPE ebeln,
bukrs TYPE bukrs,
bsart TYPE bsart,
aedat TYPE aedat,
ernam TYPE ernam,
lifnr TYPE lifnr,
ekorg TYPE ekorg,
END OF ls_out.
DATA: BEGIN OF ls_output,
code TYPE char3,
clnt TYPE sy-mandt,
status TYPE char10,
content TYPE string,
data LIKE ls_out,
END OF ls_output.
DATA(rt_parameters) = mo_request->get_uri_query_parameters( )." 獲取參數(shù) "
LOOP AT rt_parameters ASSIGNING FIELD-SYMBOL(<fs_par>).
TRANSLATE <fs_par>-name TO UPPER CASE.
TRANSLATE <fs_par>-value TO UPPER CASE.
ENDLOOP.
ls_output-clnt = sy-mandt.
READ TABLE rt_parameters INTO DATA(ls_par) WITH KEY name = 'EBELN'.
IF sy-subrc IS INITIAL AND ls_par-value IS NOT INITIAL.
CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT'
EXPORTING
input = ls_par-value
IMPORTING
output = lv_ebeln.
SELECT SINGLE * INTO CORRESPONDING FIELDS OF ls_out FROM ekko
WHERE ebeln = lv_ebeln.
IF sy-subrc IS INITIAL.
ls_output-data = ls_out.
ls_output-code = cl_rest_status_code=>gc_success_ok.
ls_output-status = 'success'.
ls_output-content = '獲取成功'.
ELSE.
ls_output-data = ls_out.
ls_output-code = cl_rest_status_code=>gc_success_ok.
ls_output-status = 'fail'.
ls_output-content = '獲取失敗'.
ENDIF.
ELSE.
ls_output-data = ls_out.
ls_output-code = cl_rest_status_code=>gc_redirection_permanent.
ls_output-status = 'fail'.
ls_output-content = '參數(shù)錯(cuò)誤'.
ENDIF.
/ui2/cl_json=>serialize(
EXPORTING
data = ls_output
compress = abap_false
pretty_name = /ui2/cl_json=>pretty_mode-camel_case
RECEIVING
r_json = lv_output_json ).
" 響應(yīng)內(nèi)容"
mo_response->create_entity( )->set_string_data( lv_output_json ).
" 響應(yīng)內(nèi)容類型 : application/json"
mo_response->create_entity( )->set_content_type( iv_media_type = if_rest_media_type=>gc_appl_json ).
" 響應(yīng)狀態(tài) : 非必須"
mo_response->set_status( cl_rest_status_code=>gc_success_ok ).
" 響應(yīng)說(shuō)明 : 非必須"
mo_response->set_reason( cl_rest_status_code=>get_reason_phrase( cl_rest_status_code=>gc_success_ok ) ).
ENDMETHOD.
POST方式獲取body.
" POST 方式傳入?yún)?shù),JSON"
DATA(lv_input_json) = io_entity->get_string_data( ).
二、使用SICF配置服務(wù)
配置如下,處理器為 ZLOCAL_CL_REST ,即第一次創(chuàng)建的類。
三、Postman 測(cè)試
1、正確調(diào)用
如果路徑不正確會(huì)提示沒有合適的資源。
方法沒啟用,提示不受支持。
使用token
使用token 需要在 POST 方式調(diào)用,先對(duì)類ZLOCAL_CL_GET_PURCHASEORDER中的方法IF_REST_RESOURCE~POST 重構(gòu),為了測(cè)試這里簡(jiǎn)單重構(gòu)了。
METHOD if_rest_resource~post.
TYPES:BEGIN OF ts_indata,
matnr TYPE matnr,
maktx TYPE maktx,
END OF ts_indata.
DATA: ls_data TYPE ts_indata.
TYPES: BEGIN OF ts_outdata,
code TYPE char3.
INCLUDE TYPE ts_indata.
TYPES:
END OF ts_outdata.
DATA: ls_outdata TYPE ts_outdata.
" POST 方式傳入?yún)?shù),JSON"
DATA(lv_input_json) = io_entity->get_string_data( ).
" JSON 轉(zhuǎn)換為內(nèi)表"
/ui2/cl_json=>deserialize(
EXPORTING
json = lv_input_json
CHANGING
data = ls_data ).
CALL FUNCTION 'CONVERSION_EXIT_MATN1_INPUT'
EXPORTING
input = ls_data-matnr
IMPORTING
output = ls_data-matnr
EXCEPTIONS
length_error = 1
OTHERS = 2.
SELECT SINGLE maktx FROM makt INTO ls_data-maktx WHERE matnr = ls_data-matnr.
" 內(nèi)表轉(zhuǎn)換JSON"
DATA: lv_output_json TYPE string.
MOVE-CORRESPONDING ls_data TO ls_outdata.
ls_outdata-code = cl_rest_status_code=>gc_success_ok .
/ui2/cl_json=>serialize(
EXPORTING
data = ls_outdata
compress = abap_false
pretty_name = /ui2/cl_json=>pretty_mode-camel_case
RECEIVING
r_json = lv_output_json ).
" 響應(yīng)內(nèi)容"
mo_response->create_entity( )->set_string_data( lv_output_json ).
" 響應(yīng)狀態(tài) : 非必須"
mo_response->set_status( cl_rest_status_code=>gc_success_ok ).
" 響應(yīng)說(shuō)明 : 非必須"
mo_response->set_reason( cl_rest_status_code=>get_reason_phrase( cl_rest_status_code=>gc_success_ok ) ).
ENDMETHOD.
測(cè)試token
1、使用錯(cuò)誤的token會(huì)提示驗(yàn)證失敗
正確的token,驗(yàn)證時(shí)同樣需要Basic Authentication賬號(hào)密碼。(你也可以在sicf里面維護(hù)固定賬號(hào)密碼不推薦)
該文章在 2024/11/20 18:52:34 編輯過(guò)