使用/ui/cl_json和私有或受保护的数据序列化json

2020-08-24 01:00发布

         点击此处--->   EasySAP.com群内免费提供SAP练习系统(在群公告中)

加入QQ群:457200227(SAP S4 HANA技术交流) 群内免费提供SAP练习系统(在群公告中)


你好

我创建了一个类(让它称为class1),它带有一些用于私有属性的getter和setter方法。

另一个类(我们称其为class2)具有一个公共属性,该属性在内部表中保存class1的对象引用。

数据:lt_class1_objects引用ZCL_CLASS1的类型标准表。

当我使用以下命令序列化时:

DATA(lv_json)=/ui2/cl_json =>序列化(data = lr_task pretty_name =/ui2/cl_json => pretty_mode-low_case name_mappings = lt_mapping),class2对象的内容未序列化。

是否可以通过某种方式告诉序列化程序要序列化的属性? 当我使用CALL TRANSFORMATION时,私有属性会被序列化,但是在生成的json上还有其他格式问题。

我需要的格式应如下所示:

{

//信息:类2的公共属性(内部表),该属性保存对class1实例的引用

" lt_class2_attr":[

{

" lv_example_attr":"一些示例字符串",

" lv_example_attr2":"另一个字符串"

},

{

" lv_example_attr":"一些示例字符串",

" lv_example_attr2":"另一个字符串"

}

]

}

但是序列化后我得到的是这样的:

{

" lt_class2_attr":[

{

},

{

}

]

}

当我将属性复制/粘贴到公共部分时,它会按预期工作。

我可以公开属性,但是对我来说,二传手和getter的概念还不清楚。

我想念什么吗?

边注:

-"调用转换"存在的问题是,我无法摆脱它作为JSON输出生成的堆引用语法。 因此,创建的JSON格式与上面的示例不同。 与/ui2/cl_json一起使用时,它就像一个符咒,在我需要的low_case中也可以用作pretty_name。 我唯一关心的是,我不理解我必须坚持的课堂设计,它可以正常工作,并尊重我需要输出的方式。

先谢谢您

Stefan

         点击此处--->   EasySAP.com群内免费提供SAP练习系统(在群公告中)

加入QQ群:457200227(SAP S4 HANA技术交流) 群内免费提供SAP练习系统(在群公告中)


你好

我创建了一个类(让它称为class1),它带有一些用于私有属性的getter和setter方法。

另一个类(我们称其为class2)具有一个公共属性,该属性在内部表中保存class1的对象引用。

数据:lt_class1_objects引用ZCL_CLASS1的类型标准表。

当我使用以下命令序列化时:

DATA(lv_json)=/ui2/cl_json =>序列化(data = lr_task pretty_name =/ui2/cl_json => pretty_mode-low_case name_mappings = lt_mapping),class2对象的内容未序列化。

是否可以通过某种方式告诉序列化程序要序列化的属性? 当我使用CALL TRANSFORMATION时,私有属性会被序列化,但是在生成的json上还有其他格式问题。

我需要的格式应如下所示:

{

//信息:类2的公共属性(内部表),该属性保存对class1实例的引用

" lt_class2_attr":[

{

" lv_example_attr":"一些示例字符串",

" lv_example_attr2":"另一个字符串"

},

{

" lv_example_attr":"一些示例字符串",

" lv_example_attr2":"另一个字符串"

}

]

}

但是序列化后我得到的是这样的:

{

" lt_class2_attr":[

{

},

{

}

]

}

当我将属性复制/粘贴到公共部分时,它会按预期工作。

我可以公开属性,但是对我来说,二传手和getter的概念还不清楚。

我想念什么吗?

边注:

-"调用转换"存在的问题是,我无法摆脱它作为JSON输出生成的堆引用语法。 因此,创建的JSON格式与上面的示例不同。 与/ui2/cl_json一起使用时,它就像一个符咒,在我需要的low_case中也可以用作pretty_name。 我唯一关心的是,我不理解我必须坚持的课堂设计,它可以正常工作,并尊重我需要输出的方式。

先谢谢您

Stefan

付费偷看设置
发送
6条回答
DafaDDDa
1楼 · 2020-08-24 01:30.采纳回答

你好,斯特凡,

如果你是在班级外部进行序列化的,就像迈克尔提到的那样,你只能访问该班级的公共属性。

如果您希望/ui2/cl_json可以序列化所有类型的属性(私有+保护),则需要允许它访问它们。 您可以通过将/ui2/cl_json定义为您的班级朋友来做到这一点。 这样,您就不会破坏对其他类的封装,而是启用/ui2/cl_json访问类的所有数据。

如果您不拥有要序列化的类,则可以继承 并按班级添加好友。 在这种情况下,您至少可以访问受保护的属性。

 CLASS lcl_test定义最终朋友/ui2/cl_json。

   公共部分。
     数据:ID TYPE i。
     数据:儿童lcl_test的标准类型表。

   方法:构造函数。

   受保护的部分。
     数据:prot TYPE i。

   专用部分。
     数据:priv TYPE i。

 ENDCLASS。  

最诚挚的问候,

Alexey。

哎,真难
2楼-- · 2020-08-24 01:22

你好,Alexey,

谢谢! 我已经尝试定义朋友了,但是我想我在错误的地方做了。 现在可以了。 我在类定义中将/ui2/cl_json定义为朋友,其中包含我不想序列化的私有成员。

对此还有一个问题。 是否还有其他可能性可以逐个序列化排除属性? 以防万一我有一个私有的属性,但是我不想序列化。 目前我没有这个要求,但是过去我在C#世界中使用序列化做了类似的事情。

最诚挚的问候,

Stefan

黑丝骑士
3楼-- · 2020-08-24 01:32

您需要从"内部"序列化对象。 如果您尝试从"外部"进行操作,则不能访问受保护的私有属性也就不足为奇了。 因此,您最有可能必须实现在您的类/实例内部为您解决问题的方法serialize_json。

这是我通过在类中包含接口IF_SERIALIZABLE_OBJECT并将其作为XML序列化的方式。 然后使用序列化的方法来传递xml。

方法序列化。
 
数据:对if_serializable_object的类型引用为sref。
sref吗?=我。
致电转换ID 源对象= sref 结果XML输出。
ENDMETHOD。
Violet凡
4楼-- · 2020-08-24 01:18

你好迈克尔,

使用CALL TRANSFORMATION时,私有属性没有问题。 它与我使用的/ui2/cl_json序列化程序有关。 为了更清楚一点,我做了以下超级例子:

示例class1的代码。 该类的结构很小,保留了class2的对象引用。 这两种方法将此结构序列化为JSON字符串。 一种方法是使用ui2序列化程序,另一种方法是使用调用转换。 在第二课中,我添加了两个带有默认值的字符串属性,以查看每种情况下会发生什么(请参见下面的第二课代码)。

 CLASS zcl_class1定义
   上市
   最后
   创建公众。

   公共部分。
     类型:
         开始于l_mytype_class1_t,
             lr_obj_class2 TYPE REF TO ZCL_CLASS2,
             anystring TYPE字符串,
         l_mytype_class1_t的结尾。

     数据:
         ls_2_serialize TYPE l_mytype_class1_t。

     方法:
         serialize_me_ui2 EXPORTING ex_serialized_str TYPE字符串,
         serialize_me_call_trans EXPORTING ex_serialized_str TYPE字符串。

   受保护的部分。
   专用部分。
 ENDCLASS。

 类zcl_class1的实现。
   方法serialize_me_ui2。

     ex_serialized_str =/ui2/cl_json =>序列化(data = me-> ls_2_serialize compress = abap_true pretty_name =/ui2/cl_json => pretty_mode-user_low_case)。

   终结法。

   方法serialize_me_call_trans。

     DATA(json_writer)= cl_sxml_string_writer => create(type = if_sxml => co_xt_json)。
     呼叫转换ID来源root = me-> ls_2_serialize结果XML json_writer选项DATA_REFS ='堆或创建'。
     DATA(json_xstr)= json_writer-> get_output()。

     cl_abap_codepage => convert_from(
       出口
         源= json_xstr"源xstring
       接收
         结果= ex_serialized_str
     )。

   终结法。
 ENDCLASS。
 

第2类代码:

 CLASS zcl_class2定义
   上市
   最后
   创建公众。

   公共部分。

     接口if_serializable_object。

     数据:
         mypublicattr_class2 TYPE字符串VALUE'mypublicattr_class2的值'。

   受保护的部分。
     数据:
         myprotectedattr_class2 TYPE字符串VALUE'myprotectedattr_class2的值'。
   专用部分。
 ENDCLASS。

 CLASS zcl_class2实现。
 ENDCLASS。

我的小型Testclass的编码:

 class ltcl_class1定义最终用于测试
   持续时间短
   风险等级无害。

   私人部分。
     方法:
       tm_serialize_ui2用于测试提高cx_static_check,
       tm_serialize_call_trans用于测试提高cx_static_check。
 结束类。

 类ltcl_class1实现。
   方法tm_serialize_ui2。
     DATA(lr_c1)=新的ZCL_CLASS1()。
     DATA(lr_c2)=新的ZCL_CLASS2()。

     lr_c1-> ls_2_serialize-lr_obj_class2 = lr_c2。
     lr_c1-> ls_2_serialize-anystring ='任何字符串内容..'。

     DATA lv_ser_str TYPE字符串。

     lr_c1-> serialize_me_ui2(
       输入
         ex_serialized_str = lv_ser_str
     )。

     cl_abap_unit_assert =>失败("在这里执行您的第一个测试")。
   方法。

   方法tm_serialize_call_trans。
     DATA(lr_c1)=新的ZCL_CLASS1()。
     DATA(lr_c2)=新的ZCL_CLASS2()。

     lr_c1-> ls_2_serialize-lr_obj_class2 = lr_c2。
     lr_c1-> ls_2_serialize-anystring ='任何字符串内容..'。

     DATA lv_ser_str TYPE字符串。

     lr_c1-> serialize_me_call_trans(
       输入
         ex_serialized_str = lv_ser_str
     )。
   方法。
 结束类。

tm_serialize_ui2的输出:

仅引用对象的公共属性被序列化。

 {
 " lr_obj_class2":{
 " mypublicattr_class2":" mypublicattr_class2的值"
 },
 " anystring":"任何字符串内容.."
 } 

tm_serialize_call_trans的输出:

这两个属性都已序列化。 但我的问题是,我不能使用呼叫转换,因为此"%heap"部分生成的格式不符合我的需求。/ui2/序列化器产生的格式正是我所需要的。 但是这里我有私有或受保护的属性的问题。 此刻,我将它们公开。 但是我想要的是使它们受到保护,并使用适当的setter和getter方法来处理它们。 我只想对序列化的内容和非序列化的内容进行更多控制。 也许像属性注释这样的东西将被序列化? 对于某些序列化程序,这就是在C#世界中可以做到的方式。

 {
 "根": {
 " LR_OBJ_CLASS2":{
 "%ref":"#o32"
 },
 " ANYSTRING":"任何字符串内容。"
 },
 "%heap":{
 " o32":{
 "%type":" cls:ZCL_CLASS2",
 "%val":{
 " ZCL_CLASS2":{
 " MYPUBLICATTR_CLASS2":" mypublicattr_class2的值",
 " MYPROTECTEDATTR_CLASS2":" myprotectedattr_class2的值"
 }
 }
 }
 }
 } 
谢谢,Stefan
悠然的二货
5楼-- · 2020-08-24 01:07

您好,Stefan,

不,没有用于选择性序列化的逻辑。 我尚未计划。

您可能要做的是,如果需要的话,您可以通过类继承/ui2/cl_json并重新定义GET_SYMBOLS方法,在此仅返回所需的字段 进行序列化。

有关如何扩展该类的更多详细信息,您可以在博客

最好的

小c菟菟
6楼-- · 2020-08-24 01:25

您可以对/ui/cl_json的方法进行增强以导出私有 数据存入内存。 然后,您可以将它们导入自己的程序中。

一周热门 更多>