JSON has gradually become a mainstream data exchange format on the Internet due to its simple and convenient data structure.
Before discussing the JSON Conversion Method for Nested objects, let's look at the simple ruby JSON conversion.
First, the ruby object is converted to a JSON string:
Copy codeThe Code is as follows:
Class Obj1
Def initialize (var1)
@ Var1 = var1
End
Def to_json (*)
{
"Json_class" => self. class,
"Data" => {"var1" => @ var1}
}. To_json (*)
End
Def self. json_create (json_str)
New (json_str ["data"] ["var1"])
End
End
Obj1 = Obj1.new ("I am obj1 ")
# Obj1 to JSON string
Json_str = obj1.to _ json
Puts "JSON string of obj1 =#{ json_str }"
# JSON string to obj1
Obj11 = JSON. parse (json_str)
Puts "ob1 from json string =#{ obj11.var1 }"
The code above shows that there are three key points for the conversion between ruby and JSON string:
# The following two methods are available only when the json library is introduced. json adds the to_json (* a) method to the Hash object through the open class method, for open class in ruby, see Open-Closed Principle in programming languages that support the Open Class feature)
1) require 'json'
# Define the to_json (* a) method for converting an object to a JSON string. The implementation is to use the to_json (* a) method of the Hash object.
2) def to_json (*)
# Define the json_create method for constructing an object from JSON string. This method is a class method.
3) def self. json_create (json_str)
The preceding three points are the basic requirements for JSON string Conversion in Ruby.
The code execution result is:
Copy codeThe Code is as follows:
JSON string of obj1 = {"json_class": "Obj1", "data": {"var1": "I am obj1 "}}
Ob1 from json string = I am obj1
Now let's look at the JSON string Conversion of nested objects:
Copy codeThe Code is as follows:
#! /Usr/local/ruby/bin/ruby
Require 'json'
Class Obj1
Def initialize (var1)
@ Var1 = var1
End
Def to_json (*)
{
"Json_class" => self. class,
"Data" => {"var1" => @ var1}
}. To_json (*)
End
Def self. json_create (json_str)
New (json_str ["data"] ["var1"])
End
Attr_reader: var1
End
Class Obj2
Def initialize (var2)
@ Var2 = var2
End
Def to_json (*)
{
"Json_class" => self. class,
"Data" => {"var2" => @ var2}
}. To_json (*)
End
Def self. json_create (json_str)
New (json_str ["data"] ["var2"])
End
Attr_reader: var2
End
Class Obj
Def initialize (obj1, obj2)
@ Obj1 = obj1
@ Obj2 = obj2
End
Def to_json (*)
{
"Json_class" => self. class,
"Data" => {"obj1" => @ obj1.to _ json, "obj2" => @ obj2.to _ json}
}. To_json (*)
End
Def self. json_create (json_str)
New (json_str ["data"] ["obj1"], json_str ["data"] ["obj2"])
End
Def to_s
"Hi, I am obj"
End
Attr_reader: obj1,: obj2
End
Obj1 = Obj1.new ("I am obj1 ")
Obj2 = Obj2.new ("I am obj2 ")
Obj = Obj. new (obj1, obj2)
Obj_json_str = obj. to_json
Puts "JSON string of obj =#{ obj_json_str }"
Obj_1 = JSON. parse (obj_json_str)
Puts "obj_1 from json string, obj1.class =#{ obj_1.obj1.class}, obj2.class =#{ obj_1.obj2.class }"
In the code above, the nested object is our inertial thinking, which first converts the object itself into a JSON string:
Copy codeThe Code is as follows:
"Data" => {"obj1" => @ obj1.to _ json, "obj2" => @ obj2.to _ json}
The above code output:
Copy codeThe Code is as follows:
JSON string of obj = {"json_class": "Obj", "data": {"obj1": "{\" json_class \ ": \" Obj1 \", \ "data \": {\ "var1 \": \ "I am obj1 \" }}", "obj2": "{\" json_class \": \ "Obj2 \", \ "data \": {\ "var2 \": \ "I am obj2 \"}}"}}
Obj_1 from json string, obj1.class = String, obj2.class = String
We noticed that after the nested object is converted to a JSON string, there is an additional backslash \:
Copy codeThe Code is as follows:
JSON string of obj = {"json_class": "Obj", "data": {"obj1": "{\" json_class \ ": \" Obj1 \", \ "data \": {\ "var1 \": \ "I am obj1 \" }}", "obj2": "{\" json_class \": \ "Obj2 \", \ "data \": {\ "var2 \": \ "I am obj2 \"}}"}}
After JSON string Conversion, the nested objects obj1 and obj2 in obj are of the String type, rather than the expected Obj1 and Obj2 types.
Copy codeThe Code is as follows:
Obj_1 from json string, obj1.class = String, obj2.class = String
In fact, this is an inertial thinking victim. nested objects do not need to call its to_json method.
Therefore, the to_json code of the Obj class is as follows:
Copy codeThe Code is as follows:
Def to_json (*)
{
"Json_class" => self. class,
"Data" => {"obj1" => @ obj1.to _ json, "obj2" => @ obj2.to _ json}
}. To_json (*)
End
Corrected:
Copy codeThe Code is as follows:
Def to_json (*)
{
"Json_class" => self. class,
"Data" => {"obj1" => @ obj1, "obj2" => @ obj2}
}. To_json (*)
End
Then, run the code to see the expected output:
Copy codeThe Code is as follows:
JSON string of obj = {"json_class": "Obj", "data": {"obj1": {"json_class": "Obj1", "data ": {"var1": "I am obj1" }}, "obj2": {"json_class": "Obj2", "data": {"var2 ": "I am obj2 "}}}}
Obj_1 from json string = {"json_class" => "Obj", "data" => {"obj1" = >#, "obj2" => #}}