Application Development Discussions
Join the discussions or start your own on all things application development, including tools and APIs, programming models, and keeping your skills sharp.
cancel
Showing results for 
Search instead for 
Did you mean: 

JSON Deserialization in ABAP

maklucksap
Explorer

Dear SAP community,

I hope you can help me with JSON Deserialization in SAP. I receive a JSON string and want to convert it into an internal table. Below you can see an example, which is working, but it doesn't behave like a normal JSON deserialization.

These are the issues:

  • If the fields in the JSON string are not in the exact sequence (just switch "FirstField" and "SecondField" in the JSON input file), then the transformation dumps. Usually JSON deserializations should find the match regardless of the field sequence.
  • How can I declare a real boolean value? In my example the boolean value is only working as a string with encapsuled in quotas (").
  • To test this you have to create the below report and the below transformation.

    This is the Report:

    *&---------------------------------------------------------------------*
    *& Report ZJSON_SEQUENCE
    *&---------------------------------------------------------------------*
    report zjson_sequence.
    
    parameters: p_file type string obligatory.
    
    class gcl_json definition.
      public section.
        class-methods main.
    endclass.
    
    class gcl_json implementation.
      method main.
        types: begin of lty_data,
                 firstfield  type c length 10,
                 secondfield type boole_d,
               end of lty_data.
    
        data: lt_string type table of string,
              lt_data   type table of lty_data,
              lv_string type string.
    
        call function 'GUI_UPLOAD'
          exporting
            filename = p_file
          tables
            data_tab = lt_string
          exceptions
            others   = 1.
        if sy-subrc <> 0.
          message id sy-msgid type sy-msgty number 
                     sy-msgno with sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
        endif.
    
        loop at lt_string assigning field-symbol(<lv_string>).
          concatenate lv_string <lv_string> into lv_string.
        endloop.
    
        call transformation zjson_sequence source xml lv_string
                                               result root = lt_data.
    
        loop at lt_data assigning field-symbol(<ls_data>).
          write: 'First field = ', <ls_data>-firstfield, 
                 '; Second field = ', <ls_data>-secondfield.
          skip.
        endloop.
      endmethod.
    endclass.
    
    at selection-screen on value-request for p_file.
      call function 'WS_FILENAME_GET'
        importing
          filename = p_file
        exceptions
          others   = 1.
    
    start-of-selection.
      gcl_json=>main( ).
    

    This is the Transformation:

    <?sap.transform simple?>
    <tt:transform xmlns:tt="http://www.sap.com/transformation-templates">
      <tt:root name="ROOT"/>
      <tt:template>
      <object>
        <array name="SomeData">
          <tt:loop ref=".ROOT">
            <object>
              <str name="FirstField">
    	    <tt:value ref="$ref.firstfield"/>
    	  </str>
              <str name="SecondField">
    	    <tt:value option="format(boolean)" 
    			 ref="$ref.secondfield"/>
     	  </str>
           </object>
          </tt:loop>
        </array>
      </object>
      </tt:template>
    </tt:transform>
    

    This is the JSON example, which works. It needs to be saved as a text file and uploaded by the report:

    {
     "SomeData":
     [
      {
       "FirstField": "ABCDE12345",
       "SecondField": "true"
      }
     ]
    }
    

    This is the JSON example, which doesn't work:

    {
     "SomeData":
     [
      {
       "SecondField": true,
       "FirstField": "ABCDE12345"
      }
     ]
    }
    

    Looking forward for your guidance.

    Kind Regards
    Mark André

    1 ACCEPTED SOLUTION

    Florian
    Active Contributor

    why not use something which is working well.

    For example this one:

    https://wiki.scn.sap.com/wiki/display/Snippets/One+more+ABAP+to+JSON+Serializer+and+Deserializer

    https://blogs.sap.com/2013/02/21/three-different-ways-to-serialize-and-deserialize-complex-abap-data...

    I think the issue with the boolean might be fixed, but not sure, because it's a while ago I used it (first link).

    9 REPLIES 9

    Sandra_Rossi
    Active Contributor

    When you use CALL TRANSFORMATION and the input string is JSON, it automatically converts it into XML, and then the transformation is applied. So your question is about how to allow elements in any order in a Simple Transformation -> cf <tt:group>

    Hi Sandra,

    thank you for the hint. This has solved the field sequence issue. I was also able to sort out the boolean value issue. With this transformation both issues are fixed:

    <?sap.transform simple?>
    <tt:transform xmlns:tt="http://www.sap.com/transformation-templates">
      <tt:root name="ROOT"/>
      <tt:template>
      <object>
        <array name="SomeData">
          <tt:loop ref=".ROOT">
            <object>
            <tt:group>
            <tt:d-cond frq="*">
              <str name="FirstField"><tt:value ref="$ref.firstfield"/></str>
            </tt:d-cond>
            <tt:d-cond frq="*">
              <bool name="SecondField"><tt:value option="format(boolean)" ref="$ref.secondfield"/></bool>
            </tt:d-cond>
            </tt:group>
           </object>
          </tt:loop>
        </array>
      </object>
      </tt:template>
    </tt:transform>

    I have one more problem. I want it to be possible that fields are missing in JSON or that additina fields are possible in JSON, which are just not taken into account, because they are missing in the ABAP structure. But if I try this I always get a short dump.

    In general is this the correct approach to write a transformation and deserialize the JSON directly with CALL TRANSFORMATION into an internal table? Or is the better approach maybe working with a JSON Reader class and handle the parsing in ABAP?

    Kind Regards
    Mark André

    maklucksap tt:cond is for that, the question is what dump do you get? If your transformation is too complex then deserialize with a class.

    Florian
    Active Contributor

    why not use something which is working well.

    For example this one:

    https://wiki.scn.sap.com/wiki/display/Snippets/One+more+ABAP+to+JSON+Serializer+and+Deserializer

    https://blogs.sap.com/2013/02/21/three-different-ways-to-serialize-and-deserialize-complex-abap-data...

    I think the issue with the boolean might be fixed, but not sure, because it's a while ago I used it (first link).

    0 Kudos

    /UI2/CL_JSON is what we use as per the first link and it works perfectly

    0 Kudos

    I also vote for /UI2/CL_JSON 🙂

    -- Tomas --

    0 Kudos

    I didn't use /UI2/CL_JSON, because in the second blog, which you mentioned there is an update that using this class is the old technique.

    However, when I replace these lines...

    call transformation zjson_sequence source xml lv_string
                                       result root = lt_data.

    ...in my above report with this:

    /ui2/cl_json=>deserialize( exporting json = lv_string
                                         pretty_name = /ui2/cl_json=>pretty_mode-camel_case
                                changing data = lt_data ).

    then it is still not working, because lt_data is empty after the execution.

    DoanManhQuynh
    Active Contributor
    0 Kudos

    I think to avoid this situation you can use <tt:cond> to check the name, incase field name is fixed...

    keremkoseoglu
    Contributor
    0 Kudos

    You'll find some JSON parsing ideas here: https://blogs.sap.com/2017/08/03/parsing-json-in-abap/