"Szia haver!"
– Szia, Diego.
"Látom, itt megtanulta a JSON szerializálás alapjait?"
"Mit értesz azon, hogy "alapok"? Sokat tudok!
– Annyira naiv. A felét nem tudod. Legfeljebb tíz százalék.
– Viccelsz. Mi van még?
"Objektumhierarchia deszerializálása (polimorf deserializáció), gyűjtemények deszerializálása és még sok minden más! A Jackson-keret nagy és erőteljes. Őszintén szólva, még csak most kezdte meg karcolni a felszínt."
"Rendben, akkor mesélj róla, én csak füles vagyok."
"Nagyon élvezem, hogy minden leckével okosabb leszek!"
– Nos, örömömre szolgál, hogy segíthetek, robotbarátom!
"Készen állsz? Akkor figyelj."
"Amint azt már megtanulta, a megjegyzéseket mind a szerializáláshoz, mind a szerializáláshoz használják. A gyakorlatban a szerializálás sokkal kevesebb információt igényel, mint a szerializálás. Például:"
Java osztály | JSON |
---|---|
|
|
|
|
|
|
"Az Array, ArrayList, LinkedList és más osztályok példányai JSON-tömbökké alakulnak."
"De amikor deszerializál egy JSON-tömböt, milyen objektumot kell létrehoznia: ArrayList vagy LinkedList?"
"Helyes. Ha egy osztálytag egy interfész (pl. nyilvános List<Cat> cats ), milyen objektumot kell hozzá rendelni?"
"Hozzáadhatunk további megjegyzéseket a mezőhöz, vagy kifejezetten jelezhetjük a célosztályokat a deszerializálás során. Nézze meg ezt a példát:"
public static void main(String[] args) throws IOException
{
String jsonString = ""{\"name\":\"Missy\",\"cats\":[{\"name\":\"Timmy\"},{\"name\":\"Killer\"}]}"";
StringReader reader = new StringReader(jsonString);
ObjectMapper mapper = new ObjectMapper();
Cat cat = mapper.readValue(reader, TypeFactory.collectionType(ArrayList.class, Cat.class));
}
@JsonAutoDetect
class Cat {
public String name;
public List<Cat> cats = new ArrayList<>();
Cat() {
}
}
"Más szóval, a leképező . readValue metódus második paraméterével átadhatjuk a deszerializálás során használandó osztályok listáját."
"Szeretem. Ez kényelmes. Így egy JSON-tömböt deszerializálhat, amire szüksége van, legyen az ArrayList vagy egy LinkedList.
– Említetted a kommentárok használatát is. Hogyan csinálod?
"Könnyű. Például:"
public static void main(String[] args) throws IOException
{
String jsonString = ""{\"name\":\"Missy\",\"cats\":[{\"name\":\"Timmy\"},{\"name\":\"Killer\"}]}"";
StringReader reader = new StringReader(jsonString);
ObjectMapper mapper = new ObjectMapper();
Cat cat = mapper.readValue(reader, Cat.class);
}
@JsonAutoDetect
class Cat
{
public String name;
@JsonDeserialize(as = ArrayList.class, contentAs = Cat.class)
public List<Cat> cats = new ArrayList<>();
Cat() {
}
}
"Egyszerűen hozzáadjuk a @JsonDeserialize(as = ArrayList.class, contentAs = Cat.class) megjegyzést az 5. sorhoz, jelezve, hogy a Lista felület melyik implementációját kell használni."
"Ah. értem. Ez tényleg nagyon egyszerű."
"De van még több. Tegyük fel, hogy a Listában szereplő adattípus egyben interfész is! Mit tennél?"
– Itt is használunk annotációt?
"Igen, ugyanaz. A paraméter típusának jelzésére is használható. Így:"
Gyűjtemény típusa | Hogyan állítsuk be az adattípust |
---|---|
Lista | @JsonDeserialize(contentAs = ValueTypeImpl.class) |
Térkép | @JsonDeserialize(keyAs = KeyTypeImpl.class) |
"Csodálatos! Nagyon sok megjegyzésre van szükség különféle helyzetekben, amelyeket nem tudunk előre látni."
"Ez még nem minden. És ezzel el is érkeztünk a fő fogáshoz: a valós projektekben az osztályok gyakran ugyanazt az alaposztályt vagy felületet öröklik, amelyet gyakorlatilag mindenhol használnak. És most képzeljük el, hogy egy ilyen osztályokat tartalmazó adatstruktúrát deszerializálni kell. Például:"
public static void main(String[] args) throws IOException
{
Cat cat = new Cat();
cat.name = "Missy";
cat.age = 5;
Dog dog = new Dog();
dog.name = "Killer";
dog.age = 8;
dog.owner = "Bill Jefferson";
ArrayList<Pet> pets = new ArrayList<Pet>();
pets.add(cat);
pets.add(dog);
StringWriter writer = new StringWriter();
ObjectMapper mapper = new ObjectMapper();
mapper.writeValue(writer, pets);
System.out.println(writer.toString());
}
@JsonAutoDetect
class Pet
{
public String name;
}
@JsonAutoDetect
class Cat extends Pet
{
public int age;
}
@JsonAutoDetect
class Dog extends Pet
{
public int age;
public String owner;
}
[
{ "name" : "Missy", "age" : 5},
{ "name" : "Killer", "age" : 8 , "owner" : "Bill Jeferson"}
]
"Figyeljen a sorozatosítás eredményére."
"Nem tudjuk ezeket az adatokat Java objektummá deszerializálni, mivel lényegében megkülönböztethetetlenek a többi osztály adataitól."
"Van néhány megkülönböztető jellemző: a kutyának van gazdája."
"Igen, de lehet, hogy ez a mező nulla, vagy teljesen kihagyható a szerializálás során."
"Nos, nem tudnánk megadni az adattípust olyan megjegyzésekkel, amelyeket ismerünk?"
"Nem. A deszerializálás után egyetlen gyűjteménynek különféle macska és kutya objektumokat kell tartalmaznia, valamint egy tucat másik osztályt, amelyek örökölhetnek Pettől."
– Mi a fenét tudsz itt csinálni?
– Itt két dolgot használnak.
"Először egy bizonyos mezőt választanak ki, hogy megkülönböztessék az egyik típust a másiktól. Ha nincs ilyen, akkor létrejön."
"Másodszor vannak speciális megjegyzések, amelyek lehetővé teszik a «polimorf deserializáció» folyamatának vezérlését. A következőket teheti:
public static void main(String[] args) throws IOException
{
Cat cat = new Cat();
cat.name = "Missy";
cat.age = 5;
Dog dog = new Dog();
dog.name = "Killer";
dog.age = 8;
dog.owner = "Bill Jeferson";
House house = new House();
house.pets.add(dog);
house.pets.add(cat);
StringWriter writer = new StringWriter();
ObjectMapper mapper = new ObjectMapper();
mapper.writeValue(writer, house);
System.out.println(writer.toString());
}
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type")
@JsonSubTypes({
@JsonSubTypes.Type(value = Cat.class, name = "cat"),
@JsonSubTypes.Type(value = Dog.class, name = "dog")
})
class Pet
{
public String name;
}
class Cat extends Pet
{
public int age;
}
class Dog extends Pet
{
public int age;
public String owner;
}
class House
{
public List<Pet> pets = new ArrayList<>();
}
{
"pets" : [
{"type" : "dog", "name" : "Killer", "age" : 8, "owner" : "Bill Jeferson"},
{"type" : "cat", "name" : "Missy", "age" : 5}
]
}
Annotációk használatával jelezzük, hogy a JSON-reprezentáció tartalmazni fog egy típus nevű speciális mezőt, amely a Cat (Macska ) osztályhoz tartozó cat értéket , a Dog osztály esetében pedig a dog értéket fogja tartalmazni . Ez az információ elegendő egy objektum megfelelő deszerializálásához: a deserializálás során a létrehozandó objektum típusát a típus mező értéke határozza meg.
"Néha az osztálynevet használják a típusmező értékeként (pl. «com.example.entity.Cat.class»), de ez nem jó gyakorlat. Honnan ismerné a JSON-unkat fogadó külső alkalmazás a Ami még rosszabb, az osztályokat néha átnevezzük. Jobb, ha egyedi nevet használunk egy adott osztály azonosítására."
"Csodálatos! Sóhajt. Nem tudtam, hogy a deserializáció ennyire bonyolult. És hogy annyi mindent lehet finomítani."
"Igen. Ezek új fogalmak számodra, de ez az a fajta gyakorlati tudás, amitől zseniális programozó leszel."
"Amigo klassz programozó. Menő!"
"Rendben. Menj és tarts egy kis szünetet."
GO TO FULL VERSION