1. ABAP RSA签名- SAP调用上上签API(1)

       SAP上创建合同后,把合同上的甲方、乙方、合同金额、税率等信息需要传输到上上签系统上进行创建法务合同,并让上上签签署合同后把合同状态更新会SAP。

       CSDN上有两位朋友写的很详细了,比如:

https://blog.csdn.net/xiefireworks/article/details/124809161

https://blog.csdn.net/BinGeneral/article/details/125270841

但是用这些例子进行测试的过程,也是磕磕碰碰,从上周接手与上上签的对接任务后,前后碰到好几个问题,弄了大概4-5天后,终于测试通过的,以下我把碰到问题过程和具体的做法列下:

1. ABAP上调用API 通过代理服务器

通常,SAP系统是不与外网进行通信的,SAP服务器也安装在DMZ区,所以,为了在ECC上调用公网的API,需要通过内网的代理服务器,方法如下:

     把代理服务器的IP 和 端口作为参数,创建http client:

CALL METHOD CL_HTTP_CLIENT=>CREATE_BY_URL
  EXPORTING
    URL                = LV_URL
    PROXY_HOST         = '223.122.12.26'
    PROXY_SERVICE      = '8798'
  IMPORTING
    CLIENT             = LO_HTTP_CLIENT
  EXCEPTIONS
    ARGUMENT_NOT_FOUND = 1
    PLUGIN_NOT_ACTIVE  = 2
    INTERNAL_ERROR     = 3
    OTHERS             = 4.
 

2. 调用上上签的refresh token 方法'

上上签的Token获取不需要签名,所以比较简单:


REPORT ZZZZZZ5.

*&---------------------------------------------------------------------*
*& Report  ZSRM0011
*&
*&---------------------------------------------------------------------*
*&
*&   本程序用于获取API接口的Access Token
*&---------------------------------------------------------------------*


DATA: LO_HTTP_CLIENT TYPE REF TO IF_HTTP_CLIENT,
      LO_CONV    TYPE REF TO CL_ABAP_CONV_IN_CE,
      LV_REQUEST_BODY TYPE STRING,
      LV_URL       TYPE STRING,
      LV_XSTR      TYPE XSTRING,
      LV_STR       TYPE STRING,
      LV_RESULT    TYPE STRING.
DATA:   LC_CODE      TYPE STRING,
        LC_MSG      TYPE STRING,
        LV_CODE      TYPE SY-SUBRC,
        LV_CODEC     TYPE C LENGTH 10,
        LV_ERR       TYPE STRING,
        LV_MSG       TYPE STRING.
DATA: LV_GRANT_TYPE TYPE STRING,
      LV_CLIENT_ID TYPE STRING,
      LV_CLIENT_SECRET TYPE STRING,
      LV_TIMESTAMP TYPE STRING,
      LV_USERNAME TYPE STRING,
      LV_PASSWORD TYPE STRING,
      LV_SCOPE TYPE STRING,
      LV_SIGN TYPE STRING.
DATA: LV_DATE(10) TYPE C,
      LV_TIME(8) TYPE C,
      LV_USERNAME2 TYPE STRING,
      LV_TIMESTAMP_TMP TYPE TIMESTAMP,
      LV_HASH_MD5 TYPE HASH160 .

DATA: LT_RESULT_TAB TYPE TABLE OF STRING WITH HEADER LINE.
DATA: LV_LINE_DATA TYPE STRING,
      LV_KEY TYPE STRING,
      LV_TEXT TYPE STRING.
TYPES: BEGIN OF TY_RESULT,
         VALUE TYPE STRING,
         TEXT TYPE STRING,
      END OF TY_RESULT.

DATA: LT_RESULT TYPE TABLE OF TY_RESULT,
      LS_RESULT TYPE TY_RESULT.

LV_URL = 'https://api.bestsign.info/api/oa2/client-credentials/token'.

"Timestamp
GET TIME STAMP FIELD LV_TIMESTAMP_TMP.
LV_TIMESTAMP = LV_TIMESTAMP_TMP.

WRITE SY-DATUM TO LV_DATE USING EDIT MASK '____-__-__'.
WRITE SY-UZEIT TO LV_TIME USING EDIT MASK '__:__:__'.
CONCATENATE LV_DATE LV_TIME INTO LV_TIMESTAMP SEPARATED BY SPACE.

LV_REQUEST_BODY = '{ "clientId":"1657177378014361488","clientSecret":"5889b85281234b1a80b66fcfdb1e3499"  }'.


"密码转换成MD5
CALL FUNCTION 'CALCULATE_HASH_FOR_CHAR'
  EXPORTING
    ALG            = 'MD5'
    DATA           = LV_PASSWORD
*   LENGTH         = 0
  IMPORTING
    HASH           = LV_HASH_MD5
  EXCEPTIONS
    UNKNOWN_ALG    = 1
    PARAM_ERROR    = 2
    INTERNAL_ERROR = 3
    OTHERS         = 4.
IF SY-SUBRC = 0 .
  LV_PASSWORD = LV_HASH_MD5 .
ENDIF.

"计算Sign值
CONCATENATE LV_CLIENT_SECRET LV_TIMESTAMP LV_CLIENT_ID LV_USERNAME
            LV_PASSWORD LV_GRANT_TYPE LV_CLIENT_SECRET
            INTO LV_SIGN.

CALL FUNCTION 'CALCULATE_HASH_FOR_CHAR'
  EXPORTING
    ALG            = 'MD5'
    DATA           = LV_SIGN
*   LENGTH         = 0
  IMPORTING
    HASH           = LV_HASH_MD5
  EXCEPTIONS
    UNKNOWN_ALG    = 1
    PARAM_ERROR    = 2
    INTERNAL_ERROR = 3
    OTHERS         = 4.
IF SY-SUBRC = 0 .
  LV_SIGN = LV_HASH_MD5.
ENDIF.

TRANSLATE LV_SIGN TO UPPER CASE.

*******************************************************************************
*          开始调用API
*******************************************************************************

CALL METHOD CL_HTTP_CLIENT=>CREATE_BY_URL
  EXPORTING
    URL                = LV_URL
    PROXY_HOST         = '211.144.11.22'
    PROXY_SERVICE      = '11111'
  IMPORTING
    CLIENT             = LO_HTTP_CLIENT
  EXCEPTIONS
    ARGUMENT_NOT_FOUND = 1
    PLUGIN_NOT_ACTIVE  = 2
    INTERNAL_ERROR     = 3
    OTHERS             = 4.

LO_HTTP_CLIENT->REFRESH_REQUEST( ).

LO_HTTP_CLIENT->REFRESH_RESPONSE( ).

** Set request method to GET or POST
LO_HTTP_CLIENT->REQUEST->SET_METHOD( IF_HTTP_REQUEST=>CO_REQUEST_METHOD_POST ).
LO_HTTP_CLIENT->REQUEST->SET_VERSION( IF_HTTP_ENTITY=>CO_PROTOCOL_VERSION_1_1 ).
*
CALL METHOD LO_HTTP_CLIENT->REQUEST->SET_HEADER_FIELD
  EXPORTING
    NAME  = 'Content-Type'
          "value = 'multipart/form-data'.
          "value = 'text/html;charset=utf-8'. "发送字符串时只能用utf-8编码
    VALUE = 'application/json'.

LO_HTTP_CLIENT->REQUEST->SET_CDATA( LV_REQUEST_BODY ).


"Send data
CALL METHOD LO_HTTP_CLIENT->SEND
  EXCEPTIONS
    HTTP_COMMUNICATION_FAILURE = 1
    HTTP_INVALID_STATE         = 2.

CLEAR: LV_CODE, LV_ERR.
LO_HTTP_CLIENT->GET_LAST_ERROR(
 IMPORTING
   CODE    = LV_CODE
   MESSAGE = LV_ERR   ).

IF LV_CODE IS NOT INITIAL.
  LO_HTTP_CLIENT->CLOSE( ).

  WRITE LV_CODE TO LV_CODEC LEFT-JUSTIFIED NO-SIGN NO-GROUPING.
  CONCATENATE LC_CODE LV_CODEC
  LC_MSG  LV_ERR
  INTO LV_MSG SEPARATED BY SPACE.

  "MESSAGE e001 WITH lv_msg.

  RETURN.
ENDIF.

LO_HTTP_CLIENT->REFRESH_RESPONSE( ).

CALL METHOD LO_HTTP_CLIENT->RECEIVE
  EXCEPTIONS
    HTTP_COMMUNICATION_FAILURE = 1
    HTTP_INVALID_STATE         = 2
    HTTP_PROCESSING_FAILED     = 3.
LO_HTTP_CLIENT->GET_LAST_ERROR(
 IMPORTING
   CODE    = LV_CODE
   MESSAGE = LV_ERR   ).

IF LV_CODE IS NOT INITIAL.
  LO_HTTP_CLIENT->CLOSE( ).

  WRITE LV_CODE TO LV_CODEC LEFT-JUSTIFIED NO-SIGN NO-GROUPING.
  CONCATENATE LC_CODE LV_CODEC
  LC_MSG  LV_ERR
  INTO LV_MSG SEPARATED BY SPACE.

  "MESSAGE e001 WITH lv_msg.

  RETURN.
ENDIF.

CLEAR LV_RESULT .

LV_XSTR = LO_HTTP_CLIENT->RESPONSE->GET_DATA( ).

IF SY-SUBRC = 0 .
  LO_HTTP_CLIENT->CLOSE( ).
ENDIF.

CALL METHOD CL_ABAP_CONV_IN_CE=>CREATE
  EXPORTING
    INPUT       = LV_XSTR
    ENCODING    = 'UTF-8'
    REPLACEMENT = '?'
    IGNORE_CERR = ABAP_TRUE
  RECEIVING
    CONV        = LO_CONV.

TRY.
    CALL METHOD LO_CONV->READ
      IMPORTING
        DATA = LV_STR.
  CATCH CX_SY_CONVERSION_CODEPAGE.
  CATCH CX_SY_CODEPAGE_CONVERTER_INIT.
  CATCH CX_PARAMETER_INVALID_TYPE.
  CATCH CX_PARAMETER_INVALID_RANGE.
ENDTRY.

*******************************************************************************
*          返回结果处理
*******************************************************************************

 ZUI2_CL_JSON=>DESERIALIZE( EXPORTING JSON = LV_STR CHANGING DATA = LS_RESULT ).

 WRITE: /(10) 'Code:',
         (10) LV_STR-code,
         (16) 'Message:',
         (40) LV_STR-message.

 "更新数据
 if LV_STR-code = '0'.

 endif.

 message s001 with 'Refresh Token 接口调用成功'.

以上是基础部分,私钥签署文章,请查阅第二部分

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
《从实例学SAP ABAP编程1-10章》是一本SAP ABAP编程的经典入门教材。本书从简单的SAP ABAP编程入手,通过多个实例向读者展示了SAP ABAP编程的核心概念和语法。 在第一章中,本书通过一个简单的例子介绍了SAP ABAP编程的基础知识,讲解了ABAP编辑器、ABAP数据字典和ABAP Workbench等重要工具的用法。 在第二章中,本书通过一个简单的例子向读者介绍了ABAP表格的创建和维护,并讲解了一些与表格相关的SAP ABAP编程的语法和概念。 在第三章中,本书介绍了SAP ABAP编程中的面向对象编程,通过几个例子向读者展示了如何使用类、对象和继承等概念进行SAP ABAP编程。 在第四章中,本书介绍了SAP ABAP编程中的函数模块,向读者讲解了如何创建和调用函数模块,以及如何在SAP系统中使用函数模块。 在第五章中,本书介绍了SAP ABAP编程中的异常处理,向读者讲解了如何使用TRY/CATCH语句处理SAP系统中的异常情况。 在第六章中,本书介绍了SAP ABAP编程中的Web服务,向读者讲解了如何创建和使用SAP系统中的Web服务,以及如何使用HTTP和SOAP协议进行数据通信。 在第七章中,本书介绍了SAP ABAP编程中的ALV报表,向读者讲解了如何创建和维护SAP系统中的ALV报表,以及如何对报表进行数据操作和定制。 在第八章中,本书介绍了SAP ABAP编程中的BADI和Enhancement点,向读者讲解了如何使用BADI和Enhancement点扩展和修改SAP系统中的业务逻辑。 在第九章中,本书介绍了SAP ABAP编程中的Smart Form,向读者讲解了如何使用Smart Form创建和维护SAP系统中的表单。 在第十章中,本书介绍了SAP ABAP编程中的SAP HANA数据库,向读者讲解了如何使用SAP HANA数据库进行高效的数据处理和分析。 通过阅读本书,读者可以快速掌握SAP ABAP编程的核心知识和技能,从而能够独立进行SAP系统的开发和维护工作。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值