/ ui2 / cl_json =>反序列化不填充结构

时间:2019-11-17 18:04:00

标签: json abap

我有两种类型的JSON:resulterror

我试图将这两个JSON反序列化为我的内部结构,但是有一个问题。

仅对于result,该功能才能正常工作,对于error,该结构始终为空白。

有人可以帮助我解决我的问题或表明我的错误吗?

这是我的JSON:

{
    "result": [
        {
            "to": "to_somebody",
            "id": "some_id",
            "code": "some_code"
        }
    ]
}

{
    "error": {
        "name": "some_name",
        "date": [],
        "id": "11",
        "descr": "Unknown error"
    },
    "result": null
}

这是我的ABAP代码(有一个输入JSON的屏幕):

DATA go_textedit TYPE REF TO cl_gui_textedit.
PARAMETERS: json TYPE string.

AT SELECTION-SCREEN OUTPUT.
  IF go_textedit IS NOT BOUND.
    CREATE OBJECT go_textedit
      EXPORTING
        parent = cl_gui_container=>screen0.
    go_textedit->set_textstream( json ).
  ENDIF.

AT SELECTION-SCREEN.
  go_textedit->get_textstream( IMPORTING text = json ).
  cl_gui_cfw=>flush( ).
TYPES: BEGIN OF stt_result,
             to       TYPE string,
             id       TYPE string,
             code     TYPE string,
           END OF stt_result.

TYPES: BEGIN OF stt_error,
             name   TYPE string,
             date   TYPE string,
             id     TYPE string,
             descr  TYPE string,
             result TYPE string,
           END OF stt_error.

DATA: BEGIN OF ls_response_result,
       result TYPE STANDARD TABLE OF stt_result,
       error  TYPE STANDARD TABLE OF stt_error,
END OF ls_response_result.

/ui2/cl_json=>deserialize( EXPORTING json        = lv_cdata
                                     pretty_name = /ui2/cl_json=>pretty_mode-camel_case
                           CHANGING  data        = ls_response_result ).

3 个答案:

答案 0 :(得分:4)

修改您的类型声明。在一个地方,您期望结果是JSON数组(ABAP表)与JSON对象(ABAP结构)之间存在差异。

这是我使用的完整代码:

CLASS the_json_parser DEFINITION PUBLIC FINAL CREATE PUBLIC.

  PUBLIC SECTION.

    TYPES:
      BEGIN OF result_structure,
        to   TYPE string,
        id   TYPE string,
        code TYPE string,
      END OF result_structure.

    TYPES result_table TYPE
      STANDARD TABLE OF result_structure
        WITH EMPTY KEY.

    TYPES date_table TYPE
      STANDARD TABLE OF string
        WITH EMPTY KEY.

    TYPES:
      BEGIN OF error_structure,
        name   TYPE string,
        date   TYPE date_table,
        id     TYPE string,
        descr  TYPE string,
        result TYPE string,
      END OF error_structure.

    TYPES:
      BEGIN OF complete_result_structure,
        result TYPE result_table,
        error  TYPE error_structure,
      END OF complete_result_structure.

    CLASS-METHODS parse
      IMPORTING
        json          TYPE string
      RETURNING
        VALUE(result) TYPE complete_result_structure.

ENDCLASS.

CLASS the_json_parser IMPLEMENTATION.

  METHOD parse.
    /ui2/cl_json=>deserialize(
      EXPORTING
        json        = json
        pretty_name = /ui2/cl_json=>pretty_mode-camel_case
      CHANGING
        data        = result ).
  ENDMETHOD.

ENDCLASS.

通过测试类验证:

CLASS unit_tests DEFINITION FOR TESTING RISK LEVEL HARMLESS DURATION SHORT.
  PUBLIC SECTION.
    METHODS parses_result FOR TESTING.
    METHODS parses_error FOR TESTING.
ENDCLASS.

CLASS unit_tests IMPLEMENTATION.

  METHOD parses_result.
    DATA(json) = `{` &&
        `"result": [` &&
            `{` &&
                `"to": "to_somebody",` &&
                `"id": "some_id",` &&
                `"code": "some_code"` &&
            `}` &&
        `]` &&
    `}`.

    DATA(result) = the_json_parser=>parse( json ).

    cl_abap_unit_assert=>assert_not_initial( result ).
    cl_abap_unit_assert=>assert_not_initial( result-result ).
    cl_abap_unit_assert=>assert_initial( result-error ).
  ENDMETHOD.

  METHOD parses_error.
    DATA(json) = `{` &&
        `"error": {` &&
            `"name": "some_name",` &&
            `"date": [],` &&
            `"id": "11",` &&
            `"descr": "Unknown error"` &&
        `},` &&
        `"result": null` &&
    `}`.

    DATA(result) = the_json_parser=>parse( json ).

    cl_abap_unit_assert=>assert_not_initial( result ).
    cl_abap_unit_assert=>assert_initial( result-result ).
    cl_abap_unit_assert=>assert_not_initial( result-error ).
  ENDMETHOD.

ENDCLASS.

答案 1 :(得分:3)

只能通过ABAP结构映射JSON对象{...}

JSON数组[...]只能由ABAP内部表映射。

在您的代码中,error JSON是一个JSON对象,而ABAP变量是一个内部表。

因此,您应该通过删除STANDARD TABLE OF来更正ABAP变量,以使其变为结构:

DATA: BEGIN OF ls_response_result,
        result TYPE STANDARD TABLE OF stt_result,
        error  TYPE stt_error,                     " <=== "STANDARD TABLE OF" removed
      END OF ls_response_result.

答案 2 :(得分:-1)

感谢大家的建议。

我解决了我的问题。

案件是: 我从提供程序那里得到两种类型的JSON:resulterror

我无法同时获得它们。

我需要将它们反序列化为我的内部结构。

{
    "result": [
        {
            "to": "some_value",
            "id": "some_id",
            "code": "some_code"
        }
    ]
}

{
    "error": {
        "name": "some_name",
        "date": [some_date],
        "id": "some_id",
        "descr": "some_description"
    },
    "result": null
}

这是我需要的ABAP代码,该代码可以正常工作。

P.S:我的错误是我使用error就像使用内部表而不是结构。

TYPES: BEGIN OF stt_result,
             to       TYPE string,
             id       TYPE string,
             code     TYPE string,
           END OF stt_result.

    TYPES lt_data TYPE STANDARD TABLE OF string WITH EMPTY KEY.

    TYPES: BEGIN OF stt_error,
             name   TYPE string,
             date   TYPE lt_data,
             id     TYPE string,
             descr  TYPE string,
             result TYPE stt_result,
           END OF stt_error.

    DATA: BEGIN OF ls_response_result,
            result TYPE STANDARD TABLE OF stt_result,
            error  TYPE stt_error,
          END OF ls_response_result.

/ui2/cl_json=>deserialize( EXPORTING json = lv_cdata
                                     pretty_name = /ui2/cl_json=>pretty_mode-camel_case
                           CHANGING  data        = ls_response_result ).