ABAP ve JSON

JSON formatı bugünlerde yaygın olarak kullanılıyor. SAP ABAP kullanarak geliştirme yaparken JSON formatlı veriyi yorumlama, okuma ya da oluşturmaya ihtiyaç duyabiliyoruz. Bu blog yazısında ihtiyaç duyduğumuz işlemleri nasıl yapabileceğimizi anlatmaya çalışacağım.

 ABAP ve JSON

ABAP kullanımına başlamadan önce JSON (JavaScript Object Notation) hakkında biraz bilgi vermek gerekirse:

  • JavaScript programlama dili standardının bir alt kümesini temel alır.
  • Programcılar için okuması ve yazması kolaydır.
  • Makinelerin ayrıştırması ve oluşturması kolaydır.
  • İki yapı üzerine kuruludur:
    • Ad-değer çiftlerinden oluşan bir koleksiyon
    • Sıralı bir değerler listesi

JSON Örnekleri

İlk örnek, ad ve değer çiftlerinden oluşan bir koleksiyona sahiptir. Bu çiftler malzeme(matnr), malzeme tanımı(maktx), temel ölçü birimini(meins) ve değerlerini içeren aşağıdaki yapıda gösterilmiştir. 

 {   "matnr": "50065557",   "maktx": "Test Malzeme",   "meins": "ST" } 

Aşağıdaki ikinci örnek, ilk örnekteki koleksiyonların listesini gösterir.

 {   "materials": [     {       "matnr": "50065557",       "maktx": "Test Malzeme",       "meins": "ST"     },     {       "matnr": "50065558",       "maktx": "Test Malzeme2",       "meins": "ST"     },     {       "matnr": "50065559",       "maktx": "Test Malzeme3",       "meins": "ST"     }   ] } 

JSON ve XML

JSON, XML'e benzer şekilde çalışır. Her ikisi de programcı tarafından okunabilir, her ikisi de hiyerarşiktir ve çeşitli programlama dillerinde kullanılmaktadır. Ancak JSON, XML'den daha basittir, tagleri kullanmaz ve bu nedenle daha kısadır, okuması ve yazması kolaydır.

Şimdi JSON'un ABAP'ta nasıl işlenebileceğine geri dönelim.

ABAP'ta JSON Verilerinin Doğrulanması

CL_SXML_STRING_READER sınıfını kullanarak verinin doğruluğunu kontrol edeceğiz. Yukarıda bahsettiğim gibi JSON ve XML benzer olduğundan, her ikisi için de aynı sınıf kullanılabilir.

 DATA lv_json TYPE string VALUE '{"matnr":"50065557","maktx":"Test Malzeme","meins":"ST"}'.  DATA(lo_reader) = cl_sxml_string_reader=>create( cl_abap_codepage=>convert_to( lv_json ) ).  TRY.     lo_reader->next_node( ).     lo_reader->skip_node( ).     cl_demo_output=>display( 'JSON is valid' ).   CATCH cx_sxml_parse_error INTO DATA(lx_parse_error).     cl_demo_output=>display( lx_parse_error->get_text( ) ). ENDTRY. 

JSON geçerli olduğunda, “JSON is valid” çıktısını alırız.

Ardından, JSON stringimizi hata alacak şekilde değiştirelim ve yeniden deneyelim.

 DATA lv_json TYPE string VALUE '{"matnr":"50065557","maktx":"Test Malzeme","meins":"ST"ASL}'.  DATA(lo_reader) = cl_sxml_string_reader=>create( cl_abap_codepage=>convert_to( lv_json ) ).  TRY.     lo_reader->next_node( ).     lo_reader->skip_node( ).     cl_demo_output=>display( 'JSON is valid' ).   CATCH cx_sxml_parse_error INTO DATA(lx_parse_error).     cl_demo_output=>display( lx_parse_error->get_text( ) ). ENDTRY. 

Programı yürüttüğümüzde “Error while parsing an XML stream: '',' or '}' expected at 'ASL}''.” Çıktısını alırız.

ABAP’ta JSON Verilerinin Okunması

/UI2/CL_JSON sınıfını kullanarak veriyi okuyacak ve ayrıştıracağız. Bunu yapabilmek için farklı alternatiflerimiz de var ama başlangıç için iyi bir seçenek. 

 TYPES:   BEGIN OF ty_material,     matnr TYPE string,     maktx TYPE string,     meins TYPE string,   END OF ty_material.  DATA:   lv_json     TYPE string,   lr_data     TYPE REF TO data,   ls_material TYPE ty_material,   lt_material TYPE STANDARD TABLE OF ty_material.  FIELD-SYMBOLS  TYPE ANY TABLE.  lv_json = '{"materials": [{"matnr":"50065557","maktx":"Test Malzeme","meins":"ST"},' &&                          '{"matnr":"50065558","maktx":"Test Malzeme2","meins":"ST"},' &&                          '{"matnr":"50065559","maktx":"Test Malzeme3","meins":"ST"} ] } '.  /ui2/cl_json=>deserialize(   EXPORTING     json         = lv_json     pretty_name  = /ui2/cl_json=>pretty_mode-user     assoc_arrays = abap_true   CHANGING     data         = lr_data ).  IF lr_data IS BOUND.   ASSIGN lr_data->* TO FIELD-SYMBOL().   ASSIGN COMPONENT 'MATERIALS' OF STRUCTURE  TO FIELD-SYMBOL().   ASSIGN ->* TO .   LOOP AT  ASSIGNING FIELD-SYMBOL().     DO 3 TIMES.       CASE sy-index.         WHEN 1.           DATA(lv_fname) = 'MATNR'.         WHEN 2.           lv_fname = 'MAKTX'.         WHEN 3.           lv_fname = 'MEINS'.       ENDCASE.        ASSIGN COMPONENT sy-index OF STRUCTURE ls_material TO FIELD-SYMBOL().       ASSIGN ->* TO FIELD-SYMBOL().       ASSIGN COMPONENT lv_fname OF STRUCTURE  TO FIELD-SYMBOL().       IF  IS ASSIGNED AND  IS ASSIGNED.         ASSIGN ->* TO FIELD-SYMBOL().         IF  IS ASSIGNED.            = .         ENDIF.       ENDIF.     ENDDO.     APPEND ls_material TO lt_material.   ENDLOOP.   cl_demo_output=>display( lt_material ). ENDIF. 

Çalıştırdığımızda programın çıktısı aşağıdaki gibi olacaktır.

ABAP’ta JSON Verilerinin Oluşturulması

 SELECT * FROM scarr INTO TABLE @DATA(lt_scarr).  DATA(lv_json) = /ui2/cl_json=>serialize(   data        = lt_scarr   compress    = abap_true   pretty_name = /ui2/cl_json=>pretty_mode-camel_case ).  " Display JSON in ABAP CALL TRANSFORMATION sjson2html SOURCE XML lv_json                            RESULT XML DATA(lvc_html). cl_abap_browser=>show_html(   title       = 'Sample JSON'   html_string = cl_abap_codepage=>convert_from( lvc_html ) ). 

Programın çıktısı aşağıdaki gibi olacaktır.

Yukarıdaki örnekte, JSON'u HTML olarak görüntülemek için CALL TRANSFORMATION kullandık. Burada internal table -> JSON dönüşümü olarak kullanacağız.

 DATA lv_json TYPE string. SELECT * FROM scarr INTO TABLE @DATA(lt_scarr).  DATA(lo_writer) =   cl_sxml_string_writer=>create(   type = if_sxml=>co_xt_json ).  CALL TRANSFORMATION id   SOURCE values = lt_scarr   RESULT XML lo_writer.  cl_abap_conv_in_ce=>create( )->convert(   EXPORTING     input = lo_writer->get_output( )   IMPORTING     data = lv_json ). 

JSON stringi, debugta aşağıdaki gibi görünür.

Oluşturduğumuz stringi CALL TRANSFORMATION yoluyla hala dönüştürebiliriz.

 CLEAR lt_scarr. CALL TRANSFORMATION id   SOURCE XML lv_json   RESULT values = lt_scarr.  cl_demo_output=>display( lt_scarr ). 

Programın çıktısı aşağıdaki gibi olacaktır.

Daha fazla bilgiye erişmek için CL_SXML_TABLE_READER sınıfını ve nasıl kullanılacağını araştırabilirsiniz. Ayrıca SABAPDEMOS paketinde DEMO_JSON_* ile başlayan demo programları inceleyebilirsiniz.