Objects serialization for RFC forms
As it was shown previously there are some limitations on usage of RFC enabled forms. Most of it is easily avoidable, but the main limitation is that it’s impossible to pass references into such forms. Currently import/export routines doesn’t allow to pass references, so here is the problem.
An option to bypass such limitation is to serialize objects into some string container. Lucky us, SAP developed transformation called “id” that could handle everything. But, at the same time, such transformation creates an XML, so there is a big overhead. But, it could be handled as well, as SAP developed kernel-based methods for compression of strings. In this test length of the original XML is 586 bytes, and length of compressed one is 302. Pretty impressive, huh ?
Only thing that should be highlighted is that class used for serialization must implement interface IF_SERIALIZABLE_OBJECT. Actually this interface doesn’t declare any methods, so you have to put it in interfaces section. That’s it !
Another addition : this method is works pretty well if object contains nested objects, after deserialization objects would be recreated and references would be set properly. So, for example this method would work well for linked links. There is no example here, to keep things simple, but it works.
So, here is the code (there is no exceptions handling for the simplicity, but in productive software you have to always handle such exceptions):
REPORT Z_BINARY_TRANSFORM3. class z_ser_data definition. PUBLIC SECTION. INTERFACES: IF_SERIALIZABLE_OBJECT. data: member type string read-only. METHODS: constructor IMPORTING in_val type string, get_val RETURNING VALUE(out_val) type string, change_val IMPORTING new_val type string. endclass. class z_ser_data implementation. METHOD constructor. member = in_val. ENDMETHOD. method get_val. out_val = me->member. endmethod. method change_val. me->member = new_val. endmethod. endclass. data: lr_class type ref to z_ser_data, lv_ser_xml type string, lv_x_gzip type xstring. FIELD-SYMBOLS: <fs> type any. INITIALIZATION. create object lr_class exporting in_val = 'String from calling program'. CALL TRANSFORMATION id SOURCE model = lr_class RESULT XML lv_ser_xml. CL_ABAP_GZIP=>compress_text( exporting text_in = lv_ser_xml " Input Text * text_in_len = -1 " Input Length compress_level = 9 " Level of Compression * conversion = 'DEFAULT' " Conversion to UTF8 (UC) importing gzip_out = lv_x_gzip " Compressed output * gzip_out_len = " Output Length ). * catch cx_parameter_invalid_range. " Parameter with Invalid Range * catch cx_sy_buffer_overflow. " System Exception: Buffer too Short * catch cx_sy_conversion_codepage. " System Exception Converting Character Set * catch cx_sy_compression_error. " System Exception: Compression Error perform describe_buffer using lv_x_gzip. form describe_buffer using in_buffer type xstring. data: lr_another_obj type ref to z_ser_data, lv_str type string. CL_ABAP_GZIP=>decompress_text( exporting gzip_in = in_buffer " Input of Zipped Data * gzip_in_len = -1 " Input Length * conversion = 'DEFAULT' " Conversion to UTF8 (UC) importing text_out = lv_str " Decompessed Output * text_out_len = " Output Length ). * catch cx_parameter_invalid_range. " Parameter with Invalid Range * catch cx_sy_buffer_overflow. " System Exception: Buffer too Short * catch cx_sy_conversion_codepage. " System Exception Converting Character Set * catch cx_sy_compression_error. " System Exception: Compression Error CALL TRANSFORMATION id SOURCE XML lv_str RESULT model = lr_another_obj. write: 'Received val:', lr_another_obj->member. NEW-LINE. lr_another_obj->change_val( new_val = 'New val' ). write: 'Changed val:', lr_another_obj->member. new-line. endform.
Thanks Alexey for showing a option available for RFC limitation. I have to try once.