This is a test message to test the length of the message box.
Login
ABAP Quick Convert JSON to internal
Created by Software-Heroes

ABAP Quick - Convert JSON to internal

In this little tip, we'll go into how you can convert a JSON stream to an internal format and then use it properly.

If you think about the interface landscape today, you won't be able to get around OData for better or for worse. Likewise if you want to connect a cloud system like Ariba or Successfactors. What all these systems have in common is that they communicate with REST interfaces. But how do you process the response data when you address such a service with an HTTP request from ABAP? We'll go into that in a little more detail today.

 

Preperation

In the first step, we build a suitable JSON that consists of different data types and uses a table internally so that we can also work with a deep/nested structure. Our example structure could look like this:

 

Now that we have a JSON string to be converted, we also want to convert this within a program run and fill an internal structure. We can also set up this structure in ABAP, for which we need different types.

TYPES:
  BEGIN OF ts_subdata,
    key   TYPE string,
    value TYPE string,
  END OF ts_subdata,
  tt_subdata TYPE STANDARD TABLE OF ts_subdata WITH EMPTY KEY,

  BEGIN OF ts_data,
    text   TYPE string,
    number TYPE i,
    bool   TYPE abap_bool,
    table  TYPE tt_subdata,
  END OF ts_data.

 

Structure assignment

This is the easiest form of conversion, but you always have to know what your data looks like in order to access the content. Building nested structures can also take some time. In the next step we can already parse the string with the method.

DATA:
  ls_data TYPE ts_data.

/ui2/cl_json=>deserialize(
  EXPORTING
    json             = id_json
  CHANGING
    data             = ls_data
).

 

We create a structure of our target type and then use the DESERIALIZE method of the class /UI2/CL_JSON to carry out the conversion. The data is neatly mapped into the fields and the table, elements that are missing in our structure are simply skipped and we can concentrate on the important content.

 

The ADD_TEXT field is not mapped, but does not lead to an error either. The BOOL field was properly converted to ABAP_TRUE. This provides us with a simple type of conversion.

 

Generic way

We can also perform a conversion completely generically; the method can also generate a reference to the data if we do not pass a structured type. The result of such a conversion looks like this in the Eclipse debugger.

 

We cannot simply access such completely generic data at runtime because the system does not know how the data type is structured. However, we can access and map the data via generic processing. In our example we want to access our unneeded element and map the table within the structure.

DATA:
  lr_data     TYPE REF TO data,
  ld_add_text TYPE string,
  lt_subdata  TYPE tt_subdata.
FIELD-SYMBOLS:
  <lt_table> TYPE STANDARD TABLE.

/ui2/cl_json=>deserialize(
  EXPORTING
    json             = id_json
  CHANGING
    data             = lr_data
).

ASSIGN lr_data->* TO FIELD-SYMBOL(<ls_data>).

" Map the ADD_TEXT field
ASSIGN COMPONENT 'ADD_TEXT' OF STRUCTURE <ls_data> TO FIELD-SYMBOL(<ld_add>).
ASSIGN <ld_add>->* TO FIELD-SYMBOL(<ld_add_value>).
ld_add_text = <ld_add_value>.

" Map internal table 
ASSIGN COMPONENT 'TABLE' OF STRUCTURE <ls_data> TO FIELD-SYMBOL(<lt_table_ref>).
ASSIGN <lt_table_ref>->* TO <lt_table>.

LOOP AT <lt_table> ASSIGNING FIELD-SYMBOL(<ls_line>).
  ASSIGN <ls_line>->* TO FIELD-SYMBOL(<ls_line_value>).

  ASSIGN COMPONENT 'KEY' OF STRUCTURE <ls_line_value> TO FIELD-SYMBOL(<ld_key>).
  ASSIGN COMPONENT 'VALUE' OF STRUCTURE <ls_line_value> TO FIELD-SYMBOL(<ld_value>).

  ASSIGN <ld_key>->* TO FIELD-SYMBOL(<ld_key_value>).
  ASSIGN <ld_value>->* TO FIELD-SYMBOL(<ld_value_value>).

  INSERT VALUE #(
    key   = <ld_key_value>
    value = <ld_value_value>
  ) INTO TABLE lt_subdata.
ENDLOOP.

 

You will certainly think of a lot of code and many ASSIGNs. Each element is a reference and must be double-bound in order to get to the actual value and the actual data. You will surely agree with us that this path is not particularly easy and that it has many pitfalls. Likewise, the entire error handling in the upper part of the source code is still missing, this would take away the same number of lines again.

 

Example

Here again the complete example class as we use it in the examples.

CLASS zcl_60bs_test_json_convert DEFINITION PUBLIC FINAL CREATE PUBLIC.
  PUBLIC SECTION.
    INTERFACES if_oo_adt_classrun.

  PROTECTED SECTION.
  PRIVATE SECTION.
    TYPES:
      BEGIN OF ts_subdata,
        key   TYPE string,
        value TYPE string,
      END OF ts_subdata,
      tt_subdata TYPE STANDARD TABLE OF ts_subdata WITH EMPTY KEY,

      BEGIN OF ts_data,
        text   TYPE string,
        number TYPE i,
        bool   TYPE abap_bool,
        table  TYPE tt_subdata,
      END OF ts_data.

    METHODS:
      convert_json_with_structured
        IMPORTING
          id_json TYPE string,

      convert_json_with_reference
        IMPORTING
          id_json TYPE string.
ENDCLASS.

CLASS zcl_60bs_test_json_convert IMPLEMENTATION.
  METHOD if_oo_adt_classrun~main.
    DATA(ld_json) = `{"text":"Some text","number":123, "bool":"TRUE", "add_text":"Text number 2", "table":[{"key":"One","value":"1"},{"key":"Two","value":"2"}]}`.

    convert_json_with_structured( ld_json ).
    convert_json_with_reference( ld_json ).
  ENDMETHOD.


  METHOD convert_json_with_structured.
    DATA:
      ls_data TYPE ts_data.

    /ui2/cl_json=>deserialize(
      EXPORTING
        json             = id_json
      CHANGING
        data             = ls_data
    ).
  ENDMETHOD.


  METHOD convert_json_with_reference.
    DATA:
      lr_data     TYPE REF TO data,
      ld_add_text TYPE string,
      lt_subdata  TYPE tt_subdata.
    FIELD-SYMBOLS:
      <lt_table> TYPE STANDARD TABLE.

    /ui2/cl_json=>deserialize(
      EXPORTING
        json             = id_json
      CHANGING
        data             = lr_data
    ).

    ASSIGN lr_data->* TO FIELD-SYMBOL(<ls_data>).

    ASSIGN COMPONENT 'ADD_TEXT' OF STRUCTURE <ls_data> TO FIELD-SYMBOL(<ld_add>).
    ASSIGN <ld_add>->* TO FIELD-SYMBOL(<ld_add_value>).
    ld_add_text = <ld_add_value>.

    ASSIGN COMPONENT 'TABLE' OF STRUCTURE <ls_data> TO FIELD-SYMBOL(<lt_table_ref>).
    ASSIGN <lt_table_ref>->* TO <lt_table>.

    LOOP AT <lt_table> ASSIGNING FIELD-SYMBOL(<ls_line>).
      ASSIGN <ls_line>->* TO FIELD-SYMBOL(<ls_line_value>).

      ASSIGN COMPONENT 'KEY' OF STRUCTURE <ls_line_value> TO FIELD-SYMBOL(<ld_key>).
      ASSIGN COMPONENT 'VALUE' OF STRUCTURE <ls_line_value> TO FIELD-SYMBOL(<ld_value>).

      ASSIGN <ld_key>->* TO FIELD-SYMBOL(<ld_key_value>).
      ASSIGN <ld_value>->* TO FIELD-SYMBOL(<ld_value_value>).

      INSERT VALUE #(
        key   = <ld_key_value>
        value = <ld_value_value>
      ) INTO TABLE lt_subdata.
    ENDLOOP.
  ENDMETHOD.
ENDCLASS.

 

Conclusion

Converting a JSON to ABAP can be very easy, but it can also cause a lot of headache if you try to approach it dynamically. We recommend the variant with the predefined structure, as this is much easier to implement.


Included topics:
QuickConvert JSONJSON to internal
Comments (0)

ABAP - ALV still relevant in 2022?

Category - ABAP

Today the joking question, do we still need reports that generate ALV outputs in 2022? In this article, we want to look into this question.

07/01/2022

ABAP in Change

Category - ABAP

The programming language ABAP has been changing for years and is being modernized in various concepts. In this article, we'll look at it in detail.

06/24/2022

ABAP Quick - Clean Core

Category - ABAP

In this article something about Clean Core, what does it mean for the developer, what are the requirements and what do you have to pay attention to.

06/17/2022

ABAP Quick - Processing in a new task

Category - ABAP

This tip is about asynchronous processing in a new process and what to look out for.

01/07/2022

ABAP Quick - External currency to internal

Category - ABAP

A little tip to convert data from an Excel or CSV file into the correct internal currency format. A simple conversion can quickly lead to errors.

12/03/2021