Skip to Content
Technical Articles
Author's profile photo Andre Fischer

jsonPrettyPrinter

How to print out a nicely formatted JSON string?

When working on a POC where I developed a plain REST service where I had to provide a json payload as an output I was struggling with getting my json payload nicely formatted.

Searching for a pretty printer for json strings did not delivery any results immediately.

After searching around I found the class CL_DEMO_OUTPUT_STREAM that has been developed by my colleague Horst Keller which he has presented in the following two blogs.

https://blogs.sap.com/2016/05/10/cldemooutput-part-1-of-2-usage/
https://blogs.sap.com/2016/05/10/cldemooutput-part-2-of-2-a-look-behind/

There I found the method write_json( ) which inspired me to carve out the coding and migrate it such that it also works in ABAP language version 5 which is used in the SAP BTP ABAP environment.

The class cl_demo_output_stream uses the class cl_abap_codepage which is not released for the use in cloud development. There is however a class cl_abap_conv_codepage that offers a similar functionality and that is released for cloud development.

Using the code below you can simply copy the code of the method get_formatted_json_string( ) and use it in your coding.

Solution

So when you have a json string like the following (which I took from Wikipedia) and from which I removed the nice formatting.

{ "firstName": "John", "lastName": "Smith", "isAlive": true, "age": 27,
  "address": { "streetAddress": "21 2nd Street", "city": "New York", "state": "NY",
    "postalCode": "10021-3100" }, "phoneNumbers": [  { "type": "home",
      "number": "212 555-1234"  },  { "type": "office",  "number": "646 555-4567" }   ],
  "children": [],   "spouse": null }

You can use the class mentioned below with the method

get_formatted_json_string( json_string ).

and get the following output.

json%20pretty%20printer

json pretty printer

 

On premise and cloud

When you want to use the helper method in an on premise system you simply comment out the cloud specific code and uncomment the on premise specific code.

"cloud
DATA(json_formatted_string) = cl_abap_conv_codepage=>create_in( )->convert( CAST cl_sxml_string_writer( writer )->get_output( ) ).
"on premise
"DATA(json_formatted_string) = cl_abap_codepage=>convert_from( CAST cl_sxml_string_writer( writer )->get_output( ) ).

Sourcecode

 

CLASS z_pretty_print_json DEFINITION
  PUBLIC
  FINAL
  CREATE PUBLIC .

  PUBLIC SECTION.

    INTERFACES if_oo_adt_classrun .

    METHODS get_formatted_json_string
      IMPORTING json_string_in         TYPE string
      RETURNING VALUE(json_string_out) TYPE string
      RAISING   cx_sxml_parse_error.

  PROTECTED SECTION.
  PRIVATE SECTION.
ENDCLASS.



CLASS z_pretty_print_json IMPLEMENTATION.


  METHOD if_oo_adt_classrun~main.

    DATA json_string  TYPE string .
    DATA formatted_json_string TYPE string.

    json_string = '{ "firstName": "John", "lastName": "Smith", "isAlive": true, "age": 27,' && |\r\n|  &&
                  '  "address": { "streetAddress": "21 2nd Street", "city": "New York", "state": "NY",' && |\r\n|  &&
                  '    "postalCode": "10021-3100" }, "phoneNumbers": [  { "type": "home",' && |\r\n|  &&
                  '      "number": "212 555-1234"  },  { "type": "office",  "number": "646 555-4567" }   ],' && |\r\n|  &&
                  '  "children": [],   "spouse": null }'.
    TRY.
        formatted_json_string = get_formatted_json_string( json_string ).
      CATCH cx_sxml_parse_error.
        out->write( 'parse error' ).
        EXIT.
    ENDTRY.

    out->write( formatted_json_string ).

  ENDMETHOD.

  METHOD get_formatted_json_string.

    "cloud
    DATA(json_xstring) = cl_abap_conv_codepage=>create_out( )->convert( json_string_in ).
    "on_premise
    "DATA(json_xstring) = cl_abap_codepage=>convert_to( json_string_in ).

    "Check and pretty print JSON

    DATA(reader) = cl_sxml_string_reader=>create( json_xstring ).
    DATA(writer) = CAST if_sxml_writer(
                          cl_sxml_string_writer=>create( type = if_sxml=>co_xt_json ) ).
    writer->set_option( option = if_sxml_writer=>co_opt_linebreaks ).
    writer->set_option( option = if_sxml_writer=>co_opt_indent ).
    reader->next_node( ).
    reader->skip_node( writer ).

    "cloud
    DATA(json_formatted_string) = cl_abap_conv_codepage=>create_in( )->convert( CAST cl_sxml_string_writer( writer )->get_output( ) ).
    "on premise
    "DATA(json_formatted_string) = cl_abap_codepage=>convert_from( CAST cl_sxml_string_writer( writer )->get_output( ) ).

    json_string_out = escape( val = json_formatted_string format = cl_abap_format=>e_xml_text  ).

  ENDMETHOD.

ENDCLASS.

Assigned tags

      5 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo AjeethKumar R
      AjeethKumar R

      This what exactly I have done few days back when I was searching for pretty print JSON Data and grabbed the piece of code while researching on CL_DEMO_OUTPUT=>WRITE_JSON .

      Thanks for bringing this up. 

      Author's profile photo Andre Fischer
      Andre Fischer
      Blog Post Author

      I should have published this earlier ...

      Author's profile photo Errol Sayre
      Errol Sayre

      In general you want your API JSON output to be as concise as possible. Most browsers will present JSON hierarchically for you natively or via plugin. Most times when that doesn't happen it is due to the HTTP response not including the "Content-Type" header specifying that the content is  "application/json".

      For this reason I intentionally do not pretty print JSON output unless I'm displaying it in some SAP context where lines matter (e.g. debugging/log viewing in a report). Seeing plain-text in a browser then becomes an immediate clue that the headers aren't correct.

      Your proposed solution does look like a good option for viewing JSON within an ABAP context though.

      Author's profile photo Andre Fischer
      Andre Fischer
      Blog Post Author

      Hi Errol,

      thank you for this comment.

      My intention was to use this tool to have a JSON file being shown in a formatted way within a textbox of a SAP Fiori Elements UI. There the JSON otherwise only shows up as a long string.

      Kind regards,

      Andre

      Author's profile photo Errol Sayre
      Errol Sayre

      Ah, this would be similar to an ABAP context then 😉

      Once in your Fiori app though, you could make use of any number of JS based pretty-printers.