Java 11497 (#12399)
* Added/created parent module (json-modules) * moved json(submodule) to json-modules(parent) * moved json-2(submodule) to json-modules(parent) * moved json-path(submodule) to json-modules(parent) * moved gson(submodule) to json-modules(parent) * deleted sub-modules that we moved to json-modules Co-authored-by: panagiotiskakos <panagiotis.kakos@libra-is.com>
This commit is contained in:
3
json-modules/README.md
Normal file
3
json-modules/README.md
Normal file
@@ -0,0 +1,3 @@
|
||||
## JSON
|
||||
|
||||
This module contains modules about JSON.
|
||||
13
json-modules/gson/.gitignore
vendored
Normal file
13
json-modules/gson/.gitignore
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
*.class
|
||||
|
||||
#folders#
|
||||
/target
|
||||
/neoDb*
|
||||
/data
|
||||
/src/main/webapp/WEB-INF/classes
|
||||
*/META-INF/*
|
||||
|
||||
# Packaged files #
|
||||
*.jar
|
||||
*.war
|
||||
*.ear
|
||||
16
json-modules/gson/README.md
Normal file
16
json-modules/gson/README.md
Normal file
@@ -0,0 +1,16 @@
|
||||
## GSON
|
||||
|
||||
This module contains articles about Gson
|
||||
|
||||
### Relevant Articles:
|
||||
|
||||
- [Gson Deserialization Cookbook](https://www.baeldung.com/gson-deserialization-guide)
|
||||
- [Jackson vs Gson](https://www.baeldung.com/jackson-vs-gson)
|
||||
- [Exclude Fields from Serialization in Gson](https://www.baeldung.com/gson-exclude-fields-serialization)
|
||||
- [Save Data to a JSON File with Gson](https://www.baeldung.com/gson-save-file)
|
||||
- [Convert JSON to a Map Using Gson](https://www.baeldung.com/gson-json-to-map)
|
||||
- [Working with Primitive Values in Gson](https://www.baeldung.com/java-gson-primitives)
|
||||
- [Convert String to JsonObject with Gson](https://www.baeldung.com/gson-string-to-jsonobject)
|
||||
- [Mapping Multiple JSON Fields to a Single Java Field](https://www.baeldung.com/json-multiple-fields-single-java-field)
|
||||
- [Serializing and Deserializing a List with Gson](https://www.baeldung.com/gson-list)
|
||||
- [Compare Two JSON Objects with Gson](https://www.baeldung.com/gson-compare-json-objects)
|
||||
74
json-modules/gson/pom.xml
Normal file
74
json-modules/gson/pom.xml
Normal file
@@ -0,0 +1,74 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>gson</artifactId>
|
||||
<version>0.1-SNAPSHOT</version>
|
||||
<name>gson</name>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>json-modules</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<!-- utils -->
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>${lombok.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>joda-time</groupId>
|
||||
<artifactId>joda-time</artifactId>
|
||||
<version>${joda-time.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>${commons-io.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-collections4</artifactId>
|
||||
<version>${commons-collections4.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>${commons-lang3.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>${guava.version}</version>
|
||||
</dependency>
|
||||
<!-- marshalling -->
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
<version>${gson.version}</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<finalName>gson</finalName>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<gson.version>2.8.0</gson.version>
|
||||
<joda-time.version>2.9.6</joda-time.version>
|
||||
<guava.version>11.0.2</guava.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,57 @@
|
||||
package com.baeldung.gson.entities;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.TimeZone;
|
||||
|
||||
public class ActorGson {
|
||||
|
||||
private String imdbId;
|
||||
private Date dateOfBirth;
|
||||
private List<String> filmography;
|
||||
|
||||
public ActorGson(String imdbId, Date dateOfBirth, List<String> filmography) {
|
||||
super();
|
||||
this.imdbId = imdbId;
|
||||
this.dateOfBirth = dateOfBirth;
|
||||
this.filmography = filmography;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ActorGson [imdbId=" + imdbId + ", dateOfBirth=" + formatDateOfBirth() + ", filmography=" + filmography + "]";
|
||||
}
|
||||
|
||||
public String getImdbId() {
|
||||
return imdbId;
|
||||
}
|
||||
|
||||
public void setImdbId(String imdbId) {
|
||||
this.imdbId = imdbId;
|
||||
}
|
||||
|
||||
public Date getDateOfBirth() {
|
||||
return dateOfBirth;
|
||||
}
|
||||
|
||||
public void setDateOfBirth(Date dateOfBirth) {
|
||||
this.dateOfBirth = dateOfBirth;
|
||||
}
|
||||
|
||||
public List<String> getFilmography() {
|
||||
return filmography;
|
||||
}
|
||||
|
||||
public void setFilmography(List<String> filmography) {
|
||||
this.filmography = filmography;
|
||||
}
|
||||
|
||||
private String formatDateOfBirth() {
|
||||
final DateFormat formatter = new SimpleDateFormat("EEE MMM dd hh:mm:ss zzz yyyy");
|
||||
formatter.setTimeZone(TimeZone.getTimeZone("GMT"));
|
||||
return formatter.format(dateOfBirth);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.baeldung.gson.entities;
|
||||
|
||||
public abstract class Animal {
|
||||
public String type = "Animal";
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.baeldung.gson.entities;
|
||||
|
||||
public class Cow extends Animal {
|
||||
private String breed;
|
||||
|
||||
public Cow() {
|
||||
breed = "Jersey";
|
||||
type = "Cow";
|
||||
}
|
||||
|
||||
public String getBreed() {
|
||||
return breed;
|
||||
}
|
||||
|
||||
public void setBreed(String breed) {
|
||||
this.breed = breed;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.baeldung.gson.entities;
|
||||
|
||||
public class Dog extends Animal {
|
||||
private String petName;
|
||||
|
||||
public Dog() {
|
||||
petName = "Milo";
|
||||
type = "Dog";
|
||||
}
|
||||
|
||||
public String getPetName() {
|
||||
return petName;
|
||||
}
|
||||
|
||||
public void setPetName(String petName) {
|
||||
this.petName = petName;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.baeldung.gson.entities;
|
||||
|
||||
public class Employee {
|
||||
private int id;
|
||||
private String name;
|
||||
private String address;
|
||||
|
||||
public Employee(int id, String name) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
public void setAddress(String address) {
|
||||
this.address = address;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package com.baeldung.gson.entities;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class Movie {
|
||||
|
||||
private String imdbId;
|
||||
private String director;
|
||||
private List<ActorGson> actors;
|
||||
|
||||
public Movie(String imdbID, String director, List<ActorGson> actors) {
|
||||
super();
|
||||
this.imdbId = imdbID;
|
||||
this.director = director;
|
||||
this.actors = actors;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Movie [imdbId=" + imdbId + ", director=" + director + ", actors=" + actors + "]";
|
||||
}
|
||||
|
||||
public String getImdbID() {
|
||||
return imdbId;
|
||||
}
|
||||
|
||||
public void setImdbID(String imdbID) {
|
||||
this.imdbId = imdbID;
|
||||
}
|
||||
|
||||
public String getDirector() {
|
||||
return director;
|
||||
}
|
||||
|
||||
public void setDirector(String director) {
|
||||
this.director = director;
|
||||
}
|
||||
|
||||
public List<ActorGson> getActors() {
|
||||
return actors;
|
||||
}
|
||||
|
||||
public void setActors(List<ActorGson> actors) {
|
||||
this.actors = actors;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.baeldung.gson.entities;
|
||||
|
||||
import com.google.gson.annotations.Expose;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class MovieWithNullValue {
|
||||
|
||||
@Expose
|
||||
private String imdbId;
|
||||
private String director;
|
||||
|
||||
@Expose
|
||||
private List<ActorGson> actors;
|
||||
|
||||
public MovieWithNullValue(String imdbID, String director, List<ActorGson> actors) {
|
||||
super();
|
||||
this.imdbId = imdbID;
|
||||
this.director = director;
|
||||
this.actors = actors;
|
||||
}
|
||||
|
||||
public String getImdbID() {
|
||||
return imdbId;
|
||||
}
|
||||
|
||||
public void setImdbID(String imdbID) {
|
||||
this.imdbId = imdbID;
|
||||
}
|
||||
|
||||
public String getDirector() {
|
||||
return director;
|
||||
}
|
||||
|
||||
public void setDirector(String director) {
|
||||
this.director = director;
|
||||
}
|
||||
|
||||
public List<ActorGson> getActors() {
|
||||
return actors;
|
||||
}
|
||||
|
||||
public void setActors(List<ActorGson> actors) {
|
||||
this.actors = actors;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package com.baeldung.gson.entities;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class MyClass {
|
||||
private int id;
|
||||
private String name;
|
||||
|
||||
public MyClass(int id, String name) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public MyClass() { }
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
MyClass myClass = (MyClass) o;
|
||||
return id == myClass.id && Objects.equals(name, myClass.name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
|
||||
return Objects.hash(id, name);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.baeldung.gson.entities;
|
||||
|
||||
public class User {
|
||||
|
||||
private int id;
|
||||
private String name;
|
||||
private transient String nationality;
|
||||
|
||||
public User(int id, String name, String nationality) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.nationality = nationality;
|
||||
}
|
||||
|
||||
public User(int id, String name) {
|
||||
this(id, name, null);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.baeldung.gson.entities;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public class Weather {
|
||||
|
||||
@SerializedName(value = "location", alternate = "place")
|
||||
private String location;
|
||||
|
||||
@SerializedName(value = "temp", alternate = "temperature")
|
||||
private int temp;
|
||||
|
||||
@SerializedName(value = "outlook", alternate = "weather")
|
||||
private String outlook;
|
||||
|
||||
public String getLocation() {
|
||||
return location;
|
||||
}
|
||||
|
||||
public void setLocation(String location) {
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
public int getTemp() {
|
||||
return temp;
|
||||
}
|
||||
|
||||
public void setTemp(int temp) {
|
||||
this.temp = temp;
|
||||
}
|
||||
|
||||
public String getOutlook() {
|
||||
return outlook;
|
||||
}
|
||||
|
||||
public void setOutlook(String outlook) {
|
||||
this.outlook = outlook;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.baeldung.gson.primitives.models;
|
||||
|
||||
public class BooleanExample {
|
||||
public boolean value;
|
||||
|
||||
public String toString() {
|
||||
return "{boolean: " + value + "}";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.baeldung.gson.primitives.models;
|
||||
|
||||
public class ByteExample {
|
||||
public byte value = (byte) 1;
|
||||
|
||||
public String toString() {
|
||||
return "{byte: " + value + "}";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.baeldung.gson.primitives.models;
|
||||
|
||||
public class CharExample {
|
||||
public char value;
|
||||
|
||||
public String toString() {
|
||||
return "{char: " + value + "}";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.baeldung.gson.primitives.models;
|
||||
|
||||
public class DoubleExample {
|
||||
public double value;
|
||||
|
||||
public String toString() {
|
||||
return "{float: " + value + "}";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.baeldung.gson.primitives.models;
|
||||
|
||||
public class FloatExample {
|
||||
public float value;
|
||||
|
||||
public String toString() {
|
||||
return "{float: " + value + "}";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package com.baeldung.gson.primitives.models;
|
||||
|
||||
public class InfinityValuesExample {
|
||||
public float negativeInfinity;
|
||||
public float positiveInfinity;
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.baeldung.gson.primitives.models;
|
||||
|
||||
public class LongExample {
|
||||
public long value = 1;
|
||||
|
||||
public String toString() {
|
||||
return "{byte: " + value + "}";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.baeldung.gson.primitives.models;
|
||||
|
||||
public class PrimitiveBundle {
|
||||
public byte byteValue;
|
||||
public short shortValue;
|
||||
public int intValue;
|
||||
public long longValue;
|
||||
public float floatValue;
|
||||
public double doubleValue;
|
||||
public boolean booleanValue;
|
||||
public char charValue;
|
||||
|
||||
public String toString() {
|
||||
return "{" + "byte: " + byteValue + ", " + "short: " + shortValue + ", "
|
||||
+ "int: " + intValue + ", " + "long: " + longValue + ", "
|
||||
+ "float: " + floatValue + ", " + "double: " + doubleValue + ", "
|
||||
+ "boolean: " + booleanValue + ", " + "char: " + charValue + "}";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.baeldung.gson.primitives.models;
|
||||
|
||||
public class PrimitiveBundleInitialized {
|
||||
// @formatter:off
|
||||
public byte byteValue = (byte) 1;
|
||||
public short shortValue = (short) 1;
|
||||
public int intValue = 1;
|
||||
public long longValue = 1L;
|
||||
public float floatValue = 1.0f;
|
||||
public double doubleValue = 1;
|
||||
// @formatter:on
|
||||
|
||||
public String toString() {
|
||||
return "{" + "byte: " + byteValue + ", " + "short: " + shortValue + ", "
|
||||
+ "int: " + intValue + ", " + "long: " + longValue + ", "
|
||||
+ "float: " + floatValue + ", " + "double: " + doubleValue + "}";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.baeldung.gson.serialization;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import com.baeldung.gson.entities.ActorGson;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonDeserializationContext;
|
||||
import com.google.gson.JsonDeserializer;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParseException;
|
||||
|
||||
public class ActorGsonDeserializer implements JsonDeserializer<ActorGson> {
|
||||
|
||||
private final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX");
|
||||
|
||||
@Override
|
||||
public ActorGson deserialize(JsonElement json, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException {
|
||||
|
||||
final JsonObject jsonObject = json.getAsJsonObject();
|
||||
|
||||
final JsonElement jsonImdbId = jsonObject.get("imdbId");
|
||||
final JsonElement jsonDateOfBirth = jsonObject.get("dateOfBirth");
|
||||
final JsonArray jsonFilmography = jsonObject.getAsJsonArray("filmography");
|
||||
|
||||
final ArrayList<String> filmList = new ArrayList<String>();
|
||||
if (jsonFilmography != null) {
|
||||
for (int i = 0; i < jsonFilmography.size(); i++) {
|
||||
filmList.add(jsonFilmography.get(i).getAsString());
|
||||
}
|
||||
}
|
||||
|
||||
ActorGson actorGson = null;
|
||||
try {
|
||||
actorGson = new ActorGson(jsonImdbId.getAsString(), sdf.parse(jsonDateOfBirth.getAsString()), filmList);
|
||||
} catch (final ParseException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
return actorGson;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.baeldung.gson.serialization;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonSerializationContext;
|
||||
import com.google.gson.JsonSerializer;
|
||||
import com.baeldung.gson.entities.ActorGson;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class ActorGsonSerializer implements JsonSerializer<ActorGson> {
|
||||
|
||||
private SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
|
||||
|
||||
@Override
|
||||
public JsonElement serialize(ActorGson actor, Type type, JsonSerializationContext jsonSerializationContext) {
|
||||
|
||||
JsonObject actorJsonObj = new JsonObject();
|
||||
actorJsonObj.addProperty("<strong>IMDB Code</strong>", actor.getImdbId());
|
||||
actorJsonObj.addProperty("<strong>Date Of Birth</strong>", actor.getDateOfBirth() != null ? sdf.format(actor.getDateOfBirth()) : null);
|
||||
actorJsonObj.addProperty("<strong>N° Film:</strong> ", actor.getFilmography() != null ? actor.getFilmography().size() : null);
|
||||
actorJsonObj.addProperty("filmography", actor.getFilmography() != null ? convertFilmography(actor.getFilmography()) : null);
|
||||
|
||||
return actorJsonObj;
|
||||
}
|
||||
|
||||
private String convertFilmography(List<String> filmography) {
|
||||
return filmography.stream().collect(Collectors.joining("-"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.baeldung.gson.serialization;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonDeserializationContext;
|
||||
import com.google.gson.JsonDeserializer;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import com.baeldung.gson.entities.Animal;
|
||||
|
||||
public class AnimalDeserializer implements JsonDeserializer<Animal> {
|
||||
private String animalTypeElementName;
|
||||
private Gson gson;
|
||||
private Map<String, Class<? extends Animal>> animalTypeRegistry;
|
||||
|
||||
public AnimalDeserializer(String animalTypeElementName) {
|
||||
this.animalTypeElementName = animalTypeElementName;
|
||||
this.gson = new Gson();
|
||||
this.animalTypeRegistry = new HashMap<>();
|
||||
}
|
||||
|
||||
public void registerBarnType(String animalTypeName, Class<? extends Animal> animalType) {
|
||||
animalTypeRegistry.put(animalTypeName, animalType);
|
||||
}
|
||||
|
||||
public Animal deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) {
|
||||
JsonObject animalObject = json.getAsJsonObject();
|
||||
JsonElement animalTypeElement = animalObject.get(animalTypeElementName);
|
||||
|
||||
Class<? extends Animal> animalType = animalTypeRegistry.get(animalTypeElement.getAsString());
|
||||
return gson.fromJson(animalObject, animalType);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
package com.baeldung.gson.serialization;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.baeldung.gson.entities.Employee;
|
||||
|
||||
import com.google.gson.*;
|
||||
|
||||
public class MapDeserializer implements JsonDeserializer<Map<String, Object>> {
|
||||
|
||||
@Override
|
||||
public Map<String, Object> deserialize(JsonElement elem, Type type, JsonDeserializationContext context) throws JsonParseException {
|
||||
|
||||
return elem.getAsJsonObject()
|
||||
.entrySet()
|
||||
.stream()
|
||||
.collect(Collectors.toMap(
|
||||
Map.Entry::getKey,
|
||||
e -> e.getValue().isJsonPrimitive() ?
|
||||
toPrimitive(e.getValue().getAsJsonPrimitive(), context)
|
||||
: context.deserialize(e.getValue(), Employee.class)
|
||||
));
|
||||
}
|
||||
|
||||
private Object toPrimitive(JsonPrimitive jsonValue, JsonDeserializationContext context) {
|
||||
if (jsonValue.isBoolean())
|
||||
return jsonValue.getAsBoolean();
|
||||
else if (jsonValue.isString())
|
||||
return jsonValue.getAsString();
|
||||
else {
|
||||
BigDecimal bigDec = jsonValue.getAsBigDecimal();
|
||||
Long l;
|
||||
Integer i;
|
||||
if ((i = toInteger(bigDec)) != null) {
|
||||
return i;
|
||||
} else if ((l = toLong(bigDec)) != null) {
|
||||
return l;
|
||||
} else {
|
||||
return bigDec.doubleValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Long toLong(BigDecimal val) {
|
||||
try {
|
||||
return val.toBigIntegerExact().longValue();
|
||||
} catch (ArithmeticException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private Integer toInteger(BigDecimal val) {
|
||||
try {
|
||||
return val.intValueExact();
|
||||
} catch (ArithmeticException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.baeldung.gson.serialization;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.gson.JsonDeserializationContext;
|
||||
import com.google.gson.JsonDeserializer;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonParseException;
|
||||
|
||||
public class StringDateMapDeserializer implements JsonDeserializer<Map<String, Date>> {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(StringDateMapDeserializer.class);
|
||||
|
||||
private SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd");
|
||||
|
||||
@Override
|
||||
public Map<String, Date> deserialize(JsonElement elem, Type type, JsonDeserializationContext jsonDeserializationContext) {
|
||||
System.out.println("Deserializer called");
|
||||
logger.info("Deserializer called");
|
||||
return elem.getAsJsonObject()
|
||||
.entrySet()
|
||||
.stream()
|
||||
.filter(e -> e.getValue().isJsonPrimitive())
|
||||
.filter(e -> e.getValue().getAsJsonPrimitive().isString())
|
||||
.collect(Collectors.toMap(Map.Entry::getKey, e -> formatDate(e.getValue())));
|
||||
}
|
||||
|
||||
private Date formatDate(JsonElement value) {
|
||||
try {
|
||||
return format.parse(value.getAsString());
|
||||
} catch (ParseException ex) {
|
||||
throw new JsonParseException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.baeldung.gson.serializationwithexclusions;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.FIELD)
|
||||
public @interface Exclude {
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.baeldung.gson.serializationwithexclusions;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public class MyClass {
|
||||
private long id;
|
||||
private String name;
|
||||
private String other;
|
||||
private MySubClass subclass;
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.baeldung.gson.serializationwithexclusions;
|
||||
|
||||
import com.google.gson.annotations.Expose;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public class MyClassWithAnnotatedFields {
|
||||
|
||||
@Expose
|
||||
private long id;
|
||||
@Expose
|
||||
private String name;
|
||||
private String other;
|
||||
@Expose
|
||||
private MySubClassWithAnnotatedFields subclass;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.baeldung.gson.serializationwithexclusions;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public class MyClassWithCustomAnnotatedFields {
|
||||
|
||||
private long id;
|
||||
private String name;
|
||||
@Exclude
|
||||
private String other;
|
||||
private MySubClassWithCustomAnnotatedFields subclass;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.baeldung.gson.serializationwithexclusions;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public class MyClassWithTransientFields {
|
||||
|
||||
private long id;
|
||||
private String name;
|
||||
private transient String other;
|
||||
private MySubClassWithTransientFields subclass;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.baeldung.gson.serializationwithexclusions;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public class MySubClass {
|
||||
private long id;
|
||||
private String description;
|
||||
private String otherVerboseInfo;
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.baeldung.gson.serializationwithexclusions;
|
||||
|
||||
import com.google.gson.annotations.Expose;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public class MySubClassWithAnnotatedFields {
|
||||
|
||||
@Expose private long id;
|
||||
@Expose private String description;
|
||||
private String otherVerboseInfo;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.baeldung.gson.serializationwithexclusions;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public class MySubClassWithCustomAnnotatedFields {
|
||||
|
||||
private long id;
|
||||
private String description;
|
||||
@Exclude
|
||||
private String otherVerboseInfo;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.baeldung.gson.serializationwithexclusions;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public class MySubClassWithTransientFields {
|
||||
|
||||
private long id;
|
||||
private String description;
|
||||
private transient String otherVerboseInfo;
|
||||
}
|
||||
19
json-modules/gson/src/main/resources/logback.xml
Normal file
19
json-modules/gson/src/main/resources/logback.xml
Normal file
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
|
||||
</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<logger name="org.springframework" level="WARN"/>
|
||||
<logger name="org.springframework.transaction" level="WARN"/>
|
||||
|
||||
<!-- in order to debug some marshalling issues, this needs to be TRACE -->
|
||||
<logger name="org.springframework.web.servlet.mvc" level="WARN"/>
|
||||
|
||||
<root level="INFO">
|
||||
<appender-ref ref="STDOUT"/>
|
||||
</root>
|
||||
</configuration>
|
||||
@@ -0,0 +1,117 @@
|
||||
package com.baeldung.gson.advance;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import com.baeldung.gson.entities.Dog;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import com.baeldung.gson.entities.Animal;
|
||||
import com.baeldung.gson.entities.Cow;
|
||||
import com.baeldung.gson.entities.MyClass;
|
||||
import com.baeldung.gson.serialization.AnimalDeserializer;
|
||||
import org.junit.Test;
|
||||
|
||||
public class GsonAdvanceUnitTest {
|
||||
|
||||
@Test
|
||||
public void givenListOfMyClass_whenSerializing_thenCorrect() {
|
||||
List<MyClass> list = Arrays.asList(new MyClass(1, "name1"), new MyClass(2, "name2"));
|
||||
|
||||
Gson gson = new Gson();
|
||||
String jsonString = gson.toJson(list);
|
||||
String expectedString = "[{\"id\":1,\"name\":\"name1\"},{\"id\":2,\"name\":\"name2\"}]";
|
||||
|
||||
assertEquals(expectedString, jsonString);
|
||||
}
|
||||
|
||||
@Test(expected = ClassCastException.class)
|
||||
public void givenJsonString_whenIncorrectDeserializing_thenThrowClassCastException() {
|
||||
String inputString = "[{\"id\":1,\"name\":\"name1\"},{\"id\":2,\"name\":\"name2\"}]";
|
||||
|
||||
Gson gson = new Gson();
|
||||
List<MyClass> outputList = gson.fromJson(inputString, ArrayList.class);
|
||||
|
||||
assertEquals(1, outputList.get(0).getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenJsonString_whenDeserializing_thenReturnListOfMyClass() {
|
||||
String inputString = "[{\"id\":1,\"name\":\"name1\"},{\"id\":2,\"name\":\"name2\"}]";
|
||||
List<MyClass> inputList = Arrays.asList(new MyClass(1, "name1"), new MyClass(2, "name2"));
|
||||
|
||||
Type listOfMyClassObject = new TypeToken<ArrayList<MyClass>>() {}.getType();
|
||||
|
||||
Gson gson = new Gson();
|
||||
List<MyClass> outputList = gson.fromJson(inputString, listOfMyClassObject);
|
||||
|
||||
assertEquals(inputList, outputList);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenPolymorphicList_whenSerializeWithTypeAdapter_thenCorrect() {
|
||||
String expectedString = "[{\"petName\":\"Milo\",\"type\":\"Dog\"},{\"breed\":\"Jersey\",\"type\":\"Cow\"}]";
|
||||
|
||||
List<Animal> inList = new ArrayList<>();
|
||||
inList.add(new Dog());
|
||||
inList.add(new Cow());
|
||||
|
||||
String jsonString = new Gson().toJson(inList);
|
||||
|
||||
assertEquals(expectedString, jsonString);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenPolymorphicList_whenDeserializeWithTypeAdapter_thenCorrect() {
|
||||
String inputString = "[{\"petName\":\"Milo\",\"type\":\"Dog\"},{\"breed\":\"Jersey\",\"type\":\"Cow\"}]";
|
||||
|
||||
AnimalDeserializer deserializer = new AnimalDeserializer("type");
|
||||
deserializer.registerBarnType("Dog", Dog.class);
|
||||
deserializer.registerBarnType("Cow", Cow.class);
|
||||
Gson gson = new GsonBuilder()
|
||||
.registerTypeAdapter(Animal.class, deserializer)
|
||||
.create();
|
||||
|
||||
List<Animal> outList = gson.fromJson(inputString, new TypeToken<List<Animal>>(){}.getType());
|
||||
|
||||
assertEquals(2, outList.size());
|
||||
assertTrue(outList.get(0) instanceof Dog);
|
||||
assertTrue(outList.get(1) instanceof Cow);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenPolymorphicList_whenSerializeWithRuntimeTypeAdapter_thenCorrect() {
|
||||
String expectedString = "[{\"petName\":\"Milo\",\"type\":\"Dog\"},{\"breed\":\"Jersey\",\"type\":\"Cow\"}]";
|
||||
|
||||
List<Animal> inList = new ArrayList<>();
|
||||
inList.add(new Dog());
|
||||
inList.add(new Cow());
|
||||
String jsonString = new Gson().toJson(inList);
|
||||
|
||||
assertEquals(expectedString, jsonString);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenPolymorphicList_whenDeserializeWithRuntimeTypeAdapter_thenCorrect() {
|
||||
String inputString = "[{\"petName\":\"Milo\",\"type\":\"Dog\"},{\"breed\":\"Jersey\",\"type\":\"Cow\"}]";
|
||||
|
||||
Type listOfAnimals = new TypeToken<ArrayList<Animal>>() {}.getType();
|
||||
|
||||
RuntimeTypeAdapterFactory<Animal> adapter = RuntimeTypeAdapterFactory.of(Animal.class, "type")
|
||||
.registerSubtype(Dog.class)
|
||||
.registerSubtype(Cow.class);
|
||||
|
||||
Gson gson = new GsonBuilder().registerTypeAdapterFactory(adapter).create();
|
||||
|
||||
List<Animal> outList = gson.fromJson(inputString, listOfAnimals);
|
||||
|
||||
assertEquals(2, outList.size());
|
||||
assertTrue(outList.get(0) instanceof Dog);
|
||||
assertTrue(outList.get(1) instanceof Cow);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,265 @@
|
||||
package com.baeldung.gson.advance;
|
||||
|
||||
/*
|
||||
* Copyright (C) 2011 Google Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParseException;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import com.google.gson.TypeAdapter;
|
||||
import com.google.gson.TypeAdapterFactory;
|
||||
import com.google.gson.internal.Streams;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import com.google.gson.stream.JsonReader;
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
|
||||
/**
|
||||
* Adapts values whose runtime type may differ from their declaration type. This
|
||||
* is necessary when a field's type is not the same type that GSON should create
|
||||
* when deserializing that field. For example, consider these types:
|
||||
* <pre> {@code
|
||||
* abstract class Shape {
|
||||
* int x;
|
||||
* int y;
|
||||
* }
|
||||
* class Circle extends Shape {
|
||||
* int radius;
|
||||
* }
|
||||
* class Rectangle extends Shape {
|
||||
* int width;
|
||||
* int height;
|
||||
* }
|
||||
* class Diamond extends Shape {
|
||||
* int width;
|
||||
* int height;
|
||||
* }
|
||||
* class Drawing {
|
||||
* Shape bottomShape;
|
||||
* Shape topShape;
|
||||
* }
|
||||
* }</pre>
|
||||
* <p>Without additional type information, the serialized JSON is ambiguous. Is
|
||||
* the bottom shape in this drawing a rectangle or a diamond? <pre> {@code
|
||||
* {
|
||||
* "bottomShape": {
|
||||
* "width": 10,
|
||||
* "height": 5,
|
||||
* "x": 0,
|
||||
* "y": 0
|
||||
* },
|
||||
* "topShape": {
|
||||
* "radius": 2,
|
||||
* "x": 4,
|
||||
* "y": 1
|
||||
* }
|
||||
* }}</pre>
|
||||
* This class addresses this problem by adding type information to the
|
||||
* serialized JSON and honoring that type information when the JSON is
|
||||
* deserialized: <pre> {@code
|
||||
* {
|
||||
* "bottomShape": {
|
||||
* "type": "Diamond",
|
||||
* "width": 10,
|
||||
* "height": 5,
|
||||
* "x": 0,
|
||||
* "y": 0
|
||||
* },
|
||||
* "topShape": {
|
||||
* "type": "Circle",
|
||||
* "radius": 2,
|
||||
* "x": 4,
|
||||
* "y": 1
|
||||
* }
|
||||
* }}</pre>
|
||||
* Both the type field name ({@code "type"}) and the type labels ({@code
|
||||
* "Rectangle"}) are configurable.
|
||||
*
|
||||
* <h3>Registering Types</h3>
|
||||
* Create a {@code RuntimeTypeAdapterFactory} by passing the base type and type field
|
||||
* name to the {@link #of} factory method. If you don't supply an explicit type
|
||||
* field name, {@code "type"} will be used. <pre> {@code
|
||||
* RuntimeTypeAdapterFactory<Shape> shapeAdapterFactory
|
||||
* = RuntimeTypeAdapterFactory.of(Shape.class, "type");
|
||||
* }</pre>
|
||||
* Next register all of your subtypes. Every subtype must be explicitly
|
||||
* registered. This protects your application from injection attacks. If you
|
||||
* don't supply an explicit type label, the type's simple name will be used.
|
||||
* <pre> {@code
|
||||
* shapeAdapterFactory.registerSubtype(Rectangle.class, "Rectangle");
|
||||
* shapeAdapterFactory.registerSubtype(Circle.class, "Circle");
|
||||
* shapeAdapterFactory.registerSubtype(Diamond.class, "Diamond");
|
||||
* }</pre>
|
||||
* Finally, register the type adapter factory in your application's GSON builder:
|
||||
* <pre> {@code
|
||||
* Gson gson = new GsonBuilder()
|
||||
* .registerTypeAdapterFactory(shapeAdapterFactory)
|
||||
* .create();
|
||||
* }</pre>
|
||||
* Like {@code GsonBuilder}, this API supports chaining: <pre> {@code
|
||||
* RuntimeTypeAdapterFactory<Shape> shapeAdapterFactory = RuntimeTypeAdapterFactory.of(Shape.class)
|
||||
* .registerSubtype(Rectangle.class)
|
||||
* .registerSubtype(Circle.class)
|
||||
* .registerSubtype(Diamond.class);
|
||||
* }</pre>
|
||||
*/
|
||||
public final class RuntimeTypeAdapterFactory<T> implements TypeAdapterFactory {
|
||||
private final Class<?> baseType;
|
||||
private final String typeFieldName;
|
||||
private final Map<String, Class<?>> labelToSubtype = new LinkedHashMap<String, Class<?>>();
|
||||
private final Map<Class<?>, String> subtypeToLabel = new LinkedHashMap<Class<?>, String>();
|
||||
private final boolean maintainType;
|
||||
|
||||
private RuntimeTypeAdapterFactory(Class<?> baseType, String typeFieldName, boolean maintainType) {
|
||||
if (typeFieldName == null || baseType == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
this.baseType = baseType;
|
||||
this.typeFieldName = typeFieldName;
|
||||
this.maintainType = maintainType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new runtime type adapter using for {@code baseType} using {@code
|
||||
* typeFieldName} as the type field name. Type field names are case sensitive.
|
||||
* {@code maintainType} flag decide if the type will be stored in pojo or not.
|
||||
*/
|
||||
public static <T> RuntimeTypeAdapterFactory<T> of(Class<T> baseType, String typeFieldName, boolean maintainType) {
|
||||
return new RuntimeTypeAdapterFactory<T>(baseType, typeFieldName, maintainType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new runtime type adapter using for {@code baseType} using {@code
|
||||
* typeFieldName} as the type field name. Type field names are case sensitive.
|
||||
*/
|
||||
public static <T> RuntimeTypeAdapterFactory<T> of(Class<T> baseType, String typeFieldName) {
|
||||
return new RuntimeTypeAdapterFactory<T>(baseType, typeFieldName, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new runtime type adapter for {@code baseType} using {@code "type"} as
|
||||
* the type field name.
|
||||
*/
|
||||
public static <T> RuntimeTypeAdapterFactory<T> of(Class<T> baseType) {
|
||||
return new RuntimeTypeAdapterFactory<T>(baseType, "type", false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers {@code type} identified by {@code label}. Labels are case
|
||||
* sensitive.
|
||||
*
|
||||
* @throws IllegalArgumentException if either {@code type} or {@code label}
|
||||
* have already been registered on this type adapter.
|
||||
*/
|
||||
public RuntimeTypeAdapterFactory<T> registerSubtype(Class<? extends T> type, String label) {
|
||||
if (type == null || label == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
if (subtypeToLabel.containsKey(type) || labelToSubtype.containsKey(label)) {
|
||||
throw new IllegalArgumentException("types and labels must be unique");
|
||||
}
|
||||
labelToSubtype.put(label, type);
|
||||
subtypeToLabel.put(type, label);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers {@code type} identified by its {@link Class#getSimpleName simple
|
||||
* name}. Labels are case sensitive.
|
||||
*
|
||||
* @throws IllegalArgumentException if either {@code type} or its simple name
|
||||
* have already been registered on this type adapter.
|
||||
*/
|
||||
public RuntimeTypeAdapterFactory<T> registerSubtype(Class<? extends T> type) {
|
||||
return registerSubtype(type, type.getSimpleName());
|
||||
}
|
||||
|
||||
public <R> TypeAdapter<R> create(Gson gson, TypeToken<R> type) {
|
||||
if (type.getRawType() != baseType) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final Map<String, TypeAdapter<?>> labelToDelegate
|
||||
= new LinkedHashMap<String, TypeAdapter<?>>();
|
||||
final Map<Class<?>, TypeAdapter<?>> subtypeToDelegate
|
||||
= new LinkedHashMap<Class<?>, TypeAdapter<?>>();
|
||||
for (Map.Entry<String, Class<?>> entry : labelToSubtype.entrySet()) {
|
||||
TypeAdapter<?> delegate = gson.getDelegateAdapter(this, TypeToken.get(entry.getValue()));
|
||||
labelToDelegate.put(entry.getKey(), delegate);
|
||||
subtypeToDelegate.put(entry.getValue(), delegate);
|
||||
}
|
||||
|
||||
return new TypeAdapter<R>() {
|
||||
@Override public R read(JsonReader in) throws IOException {
|
||||
JsonElement jsonElement = Streams.parse(in);
|
||||
JsonElement labelJsonElement;
|
||||
if (maintainType) {
|
||||
labelJsonElement = jsonElement.getAsJsonObject().get(typeFieldName);
|
||||
} else {
|
||||
labelJsonElement = jsonElement.getAsJsonObject().remove(typeFieldName);
|
||||
}
|
||||
|
||||
if (labelJsonElement == null) {
|
||||
throw new JsonParseException("cannot deserialize " + baseType
|
||||
+ " because it does not define a field named " + typeFieldName);
|
||||
}
|
||||
String label = labelJsonElement.getAsString();
|
||||
@SuppressWarnings("unchecked") // registration requires that subtype extends T
|
||||
TypeAdapter<R> delegate = (TypeAdapter<R>) labelToDelegate.get(label);
|
||||
if (delegate == null) {
|
||||
throw new JsonParseException("cannot deserialize " + baseType + " subtype named "
|
||||
+ label + "; did you forget to register a subtype?");
|
||||
}
|
||||
return delegate.fromJsonTree(jsonElement);
|
||||
}
|
||||
|
||||
@Override public void write(JsonWriter out, R value) throws IOException {
|
||||
Class<?> srcType = value.getClass();
|
||||
String label = subtypeToLabel.get(srcType);
|
||||
@SuppressWarnings("unchecked") // registration requires that subtype extends T
|
||||
TypeAdapter<R> delegate = (TypeAdapter<R>) subtypeToDelegate.get(srcType);
|
||||
if (delegate == null) {
|
||||
throw new JsonParseException("cannot serialize " + srcType.getName()
|
||||
+ "; did you forget to register a subtype?");
|
||||
}
|
||||
JsonObject jsonObject = delegate.toJsonTree(value).getAsJsonObject();
|
||||
|
||||
if (maintainType) {
|
||||
Streams.write(jsonObject, out);
|
||||
return;
|
||||
}
|
||||
|
||||
JsonObject clone = new JsonObject();
|
||||
|
||||
if (jsonObject.has(typeFieldName)) {
|
||||
throw new JsonParseException("cannot serialize " + srcType.getName()
|
||||
+ " because it already defines a field named " + typeFieldName);
|
||||
}
|
||||
clone.add(typeFieldName, new JsonPrimitive(label));
|
||||
|
||||
for (Map.Entry<String, JsonElement> e : jsonObject.entrySet()) {
|
||||
clone.add(e.getKey(), e.getValue());
|
||||
}
|
||||
Streams.write(clone, out);
|
||||
}
|
||||
}.nullSafe();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.baeldung.gson.conversion;
|
||||
|
||||
import com.google.gson.*;
|
||||
import org.junit.Assert;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class JsonObjectConversionsUnitTest {
|
||||
|
||||
@Test
|
||||
void whenUsingJsonParser_thenConvertToJsonObject() throws Exception {
|
||||
// Example 1: Using JsonParser
|
||||
String json = "{ \"name\": \"Baeldung\", \"java\": true }";
|
||||
|
||||
JsonObject jsonObject = new JsonParser().parse(json).getAsJsonObject();
|
||||
|
||||
Assert.assertTrue(jsonObject.isJsonObject());
|
||||
Assert.assertTrue(jsonObject.get("name").getAsString().equals("Baeldung"));
|
||||
Assert.assertTrue(jsonObject.get("java").getAsBoolean() == true);
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenUsingGsonInstanceFromJson_thenConvertToJsonObject() throws Exception {
|
||||
// Example 2: Using fromJson
|
||||
String json = "{ \"name\": \"Baeldung\", \"java\": true }";
|
||||
|
||||
JsonObject convertedObject = new Gson().fromJson(json, JsonObject.class);
|
||||
|
||||
Assert.assertTrue(convertedObject.isJsonObject());
|
||||
Assert.assertTrue(convertedObject.get("name").getAsString().equals("Baeldung"));
|
||||
Assert.assertTrue(convertedObject.get("java").getAsBoolean() == true);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package com.baeldung.gson.deserialization;
|
||||
|
||||
public class Foo {
|
||||
public int intValue;
|
||||
public String stringValue;
|
||||
|
||||
public Foo(final int intValue, final String stringValue) {
|
||||
this.intValue = intValue;
|
||||
this.stringValue = stringValue;
|
||||
}
|
||||
|
||||
public Foo(final String stringValue) {
|
||||
this.stringValue = stringValue;
|
||||
}
|
||||
|
||||
public Foo() {
|
||||
super();
|
||||
}
|
||||
|
||||
// API
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = (prime * result) + intValue;
|
||||
result = (prime * result) + ((stringValue == null) ? 0 : stringValue.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass()) {
|
||||
return false;
|
||||
}
|
||||
final Foo other = (Foo) obj;
|
||||
if (intValue != other.intValue) {
|
||||
return false;
|
||||
}
|
||||
if (stringValue == null) {
|
||||
if (other.stringValue != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!stringValue.equals(other.stringValue)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "TargetClass{" + "intValue= " + intValue + ", stringValue= " + stringValue + '}';
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.baeldung.gson.deserialization;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonDeserializationContext;
|
||||
import com.google.gson.JsonDeserializer;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonParseException;
|
||||
|
||||
public class FooDeserializer implements JsonDeserializer<Foo[]> {
|
||||
|
||||
@Override
|
||||
public Foo[] deserialize(final JsonElement json, final Type typeOfT, final JsonDeserializationContext context) throws JsonParseException {
|
||||
final JsonArray jArray = json.getAsJsonArray();
|
||||
final Foo[] scArray = new Foo[jArray.size()];
|
||||
int index = 0;
|
||||
for (final JsonElement jElement : jArray) {
|
||||
final int i = jElement.getAsJsonObject().get("intValue").getAsInt();
|
||||
final String s = jElement.getAsJsonObject().get("stringValue").getAsString();
|
||||
scArray[index++] = new Foo(i, s);
|
||||
}
|
||||
return scArray;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.baeldung.gson.deserialization;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
import com.google.gson.JsonDeserializationContext;
|
||||
import com.google.gson.JsonDeserializer;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParseException;
|
||||
|
||||
public class FooDeserializerFromJsonWithDifferentFields implements JsonDeserializer<Foo> {
|
||||
|
||||
@Override
|
||||
public Foo deserialize(final JsonElement jElement, final Type typeOfT, final JsonDeserializationContext context) throws JsonParseException {
|
||||
final JsonObject jObject = jElement.getAsJsonObject();
|
||||
final int intValue = jObject.get("valueInt").getAsInt();
|
||||
final String stringValue = jObject.get("valueString").getAsString();
|
||||
return new Foo(intValue, stringValue);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.baeldung.gson.deserialization;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
import com.google.gson.InstanceCreator;
|
||||
|
||||
public class FooInstanceCreator implements InstanceCreator<Foo> {
|
||||
|
||||
@Override
|
||||
public Foo createInstance(Type type) {
|
||||
return new Foo("sample");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.baeldung.gson.deserialization;
|
||||
|
||||
public class FooWithInner {
|
||||
public int intValue;
|
||||
public String stringValue;
|
||||
public InnerFoo innerFoo;
|
||||
|
||||
public FooWithInner(int intValue, String stringValue, String name) {
|
||||
super();
|
||||
this.intValue = intValue;
|
||||
this.stringValue = stringValue;
|
||||
this.innerFoo = new InnerFoo(name);
|
||||
}
|
||||
|
||||
public class InnerFoo {
|
||||
public String name;
|
||||
|
||||
public InnerFoo(String name) {
|
||||
super();
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.baeldung.gson.deserialization;
|
||||
|
||||
public class GenericFoo<T> {
|
||||
|
||||
public T theValue;
|
||||
|
||||
public GenericFoo(final T value) {
|
||||
theValue = value;
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
@Override
|
||||
public final String toString() {
|
||||
return "GenericTargetClass{" + "intField=" + theValue + '}';
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.baeldung.gson.deserialization;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import com.baeldung.gson.entities.Weather;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
|
||||
public class GsonAlternateUnitTest {
|
||||
|
||||
@Test
|
||||
public void givenTwoJsonFormats_whenDeserialized_thenWeatherObjectsCreated() throws Exception {
|
||||
|
||||
Gson gson = new GsonBuilder().create();
|
||||
|
||||
Weather weather = gson.fromJson("{" +
|
||||
"\"location\": \"London\"," +
|
||||
"\"temp\": 15," +
|
||||
"\"weather\": \"Cloudy\"" +
|
||||
"}", Weather.class);
|
||||
|
||||
assertEquals("London", weather.getLocation());
|
||||
assertEquals("Cloudy", weather.getOutlook());
|
||||
assertEquals(15, weather.getTemp());
|
||||
|
||||
weather = gson.fromJson("{" +
|
||||
"\"place\": \"Lisbon\"," +
|
||||
"\"temperature\": 35," +
|
||||
"\"outlook\": \"Sunny\"" +
|
||||
"}", Weather.class);
|
||||
|
||||
assertEquals("Lisbon", weather.getLocation());
|
||||
assertEquals("Sunny", weather.getOutlook());
|
||||
assertEquals(35, weather.getTemp());
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.baeldung.gson.deserialization;
|
||||
|
||||
import java.text.ParseException;
|
||||
|
||||
import com.baeldung.gson.entities.Movie;
|
||||
import com.baeldung.gson.serialization.ActorGsonDeserializer;
|
||||
import com.baeldung.gson.entities.ActorGson;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
|
||||
public class GsonDeserializeUnitTest {
|
||||
@Test
|
||||
public void whenSimpleDeserialize_thenCorrect() throws ParseException {
|
||||
|
||||
final String jsonInput = "{\"imdbId\":\"tt0472043\",\"actors\":" + "[{\"imdbId\":\"nm2199632\",\"dateOfBirth\":\"Tue Sep 21 11:00:00 GMT 1982\",\"filmography\":" + "[\"Apocalypto\",\"Beatdown\",\"Wind Walkers\"]}]}";
|
||||
|
||||
final Gson gson = new GsonBuilder().setDateFormat("EEE MMM dd hh:mm:ss zzz yyyy").create();
|
||||
|
||||
final Movie outputMovie = gson.fromJson(jsonInput, Movie.class);
|
||||
|
||||
final String expectedOutput = "Movie [imdbId=tt0472043, director=null, actors=[ActorGson [imdbId=nm2199632, dateOfBirth=Tue Sep 21 11:00:00 GMT 1982, filmography=[Apocalypto, Beatdown, Wind Walkers]]]]";
|
||||
Assert.assertEquals(outputMovie.toString(), expectedOutput);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenCustomDeserialize_thenCorrect() throws ParseException {
|
||||
|
||||
final String jsonInput = "{\"imdbId\":\"tt0472043\",\"actors\":" + "[{\"imdbId\":\"nm2199632\",\"dateOfBirth\":\"1982-09-21T12:00:00+01:00\",\"filmography\":" + "[\"Apocalypto\",\"Beatdown\",\"Wind Walkers\"]}]}";
|
||||
|
||||
final Gson gson = new GsonBuilder().registerTypeAdapter(ActorGson.class, new ActorGsonDeserializer()).create();
|
||||
|
||||
final Movie outputMovie = gson.fromJson(jsonInput, Movie.class);
|
||||
|
||||
final String expectedOutput = "Movie [imdbId=tt0472043, director=null, actors=[ActorGson [imdbId=nm2199632, dateOfBirth=Tue Sep 21 11:00:00 GMT 1982, filmography=[Apocalypto, Beatdown, Wind Walkers]]]]";
|
||||
Assert.assertEquals(outputMovie.toString(), expectedOutput);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
package com.baeldung.gson.deserialization;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.text.ParseException;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.lang3.time.DateUtils;
|
||||
import com.baeldung.gson.entities.Employee;
|
||||
import com.baeldung.gson.serialization.MapDeserializer;
|
||||
import com.baeldung.gson.serialization.StringDateMapDeserializer;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import com.google.gson.internal.LinkedTreeMap;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
public class MapDeserializationUnitTest {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(MapDeserializationUnitTest.class);
|
||||
|
||||
@Test
|
||||
public void whenUsingMapClass_thenShouldReturnMapWithDefaultClasses() {
|
||||
|
||||
String jsonString = "{'employee.name':'Bob','employee.salary':10000, 'employee.active':true, "
|
||||
+ "'employee':{'id':10, 'name': 'Bob Willis', 'address':'London'}}";
|
||||
|
||||
Gson gson = new Gson();
|
||||
Map map = gson.fromJson(jsonString, Map.class);
|
||||
|
||||
logger.info("The converted map: {}", map);
|
||||
Assert.assertEquals(4, map.size());
|
||||
Assert.assertEquals(Double.class, map.get("employee.salary").getClass());
|
||||
Assert.assertEquals(LinkedTreeMap.class, map.get("employee").getClass());
|
||||
|
||||
}
|
||||
|
||||
@Test(expected = JsonSyntaxException.class)
|
||||
public void whenUsingJsonStringWithDuplicateKey_thenShouldThrowJsonSyntaxException() {
|
||||
|
||||
String jsonString = "{'employee.name':'Bob', 'employee.name':'Jenny','employee.salary':10000, "
|
||||
+ "'employee.active':true, " + "'employee':{'id':10, 'name': 'Bob Willis', 'address':'London'}}";
|
||||
|
||||
Gson gson = new Gson();
|
||||
Map map = gson.fromJson(jsonString, Map.class);
|
||||
|
||||
logger.info("The converted map: {}", map);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenUsingTypeToken_thenShouldReturnMapWithProperClass() {
|
||||
|
||||
String jsonString = "{'Bob':{'id':10, 'name': 'Bob Willis', 'address':'UK'},"
|
||||
+ "'Jenny':{'id':10, 'name': 'Jenny McCarthy', 'address':'USA'}, "
|
||||
+ "'Steve':{'id':10, 'name': 'Steven Waugh', 'address':'Australia'}}";
|
||||
|
||||
Gson gson = new Gson();
|
||||
Type empMapType = new TypeToken<Map<String, Employee>>(){}.getType();
|
||||
Map<String, Employee> nameEmployeeMap = gson.fromJson(jsonString, empMapType);
|
||||
|
||||
logger.info("The converted map: {}", nameEmployeeMap);
|
||||
Assert.assertEquals(3, nameEmployeeMap.size());
|
||||
Assert.assertEquals(Employee.class, nameEmployeeMap.get("Bob").getClass());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenUsingCustomDeserializer_thenShouldReturnMapWithProperClass() {
|
||||
|
||||
String jsonString = "{'employee.name':'Bob','employee.salary':10000, 'employee.active':true, "
|
||||
+ "'employee':{'id':10, 'name': 'Bob Willis', 'address':'London'}}";
|
||||
|
||||
Type type = new TypeToken<Map<String, Object>>(){}.getType();
|
||||
Gson gson = new GsonBuilder()
|
||||
.registerTypeAdapter(type, new MapDeserializer())
|
||||
.create();
|
||||
Map<String, Object> blendedMap = gson.fromJson(jsonString, type);
|
||||
|
||||
logger.info("The converted map: {}", blendedMap);
|
||||
Assert.assertEquals(4, blendedMap.size());
|
||||
Assert.assertEquals(Integer.class, blendedMap.get("employee.salary").getClass());
|
||||
Assert.assertEquals(Employee.class, blendedMap.get("employee").getClass());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenUsingCustomDateDeserializer_thenShouldReturnMapWithDate() {
|
||||
String jsonString = "{'Bob': '2017/06/01', 'Jennie':'2015/01/03'}";
|
||||
Type type = new TypeToken<Map<String, Date>>(){}.getType();
|
||||
Gson gson = new GsonBuilder()
|
||||
.registerTypeAdapter(type, new StringDateMapDeserializer())
|
||||
.create();
|
||||
Map<String, Date> empJoiningDateMap = gson.fromJson(jsonString, type);
|
||||
|
||||
logger.info("The converted map: {}", empJoiningDateMap);
|
||||
logger.info("The map class {}", empJoiningDateMap.getClass());
|
||||
Assert.assertEquals(2, empJoiningDateMap.size());
|
||||
Assert.assertEquals(Date.class, empJoiningDateMap.get("Bob").getClass());
|
||||
Date dt = null;
|
||||
try {
|
||||
dt = DateUtils.parseDate("2017-06-01", "yyyy-MM-dd");
|
||||
Assert.assertEquals(dt, empJoiningDateMap.get("Bob"));
|
||||
} catch (ParseException e) {
|
||||
logger.error("Could not parse date", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
package com.baeldung.gson.deserialization.test;
|
||||
|
||||
import static org.hamcrest.Matchers.hasItem;
|
||||
import static org.hamcrest.Matchers.instanceOf;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
|
||||
import com.baeldung.gson.deserialization.Foo;
|
||||
import com.baeldung.gson.deserialization.FooDeserializerFromJsonWithDifferentFields;
|
||||
import com.baeldung.gson.deserialization.FooInstanceCreator;
|
||||
import com.baeldung.gson.deserialization.FooWithInner;
|
||||
import com.baeldung.gson.deserialization.GenericFoo;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
public class GsonDeserializationUnitTest {
|
||||
|
||||
// tests - single element
|
||||
|
||||
@Test
|
||||
public final void whenDeserializingToSimpleObject_thenCorrect() {
|
||||
final String json = "{\"intValue\":1,\"stringValue\":\"one\"}";
|
||||
|
||||
final Foo targetObject = new Gson().fromJson(json, Foo.class);
|
||||
|
||||
assertEquals(targetObject.intValue, 1);
|
||||
assertEquals(targetObject.stringValue, "one");
|
||||
}
|
||||
|
||||
@Test
|
||||
public final void givenJsonHasExtraValues_whenDeserializing_thenCorrect() {
|
||||
final String json = "{\"intValue\":1,\"stringValue\":\"one\",\"extraString\":\"two\",\"extraFloat\":2.2}";
|
||||
final Foo targetObject = new Gson().fromJson(json, Foo.class);
|
||||
|
||||
assertEquals(targetObject.intValue, 1);
|
||||
assertEquals(targetObject.stringValue, "one");
|
||||
}
|
||||
|
||||
@Test
|
||||
public final void givenJsonHasNonMatchingFields_whenDeserializingWithCustomDeserializer_thenCorrect() {
|
||||
final String json = "{\"valueInt\":7,\"valueString\":\"seven\"}";
|
||||
|
||||
final GsonBuilder gsonBldr = new GsonBuilder();
|
||||
gsonBldr.registerTypeAdapter(Foo.class, new FooDeserializerFromJsonWithDifferentFields());
|
||||
final Foo targetObject = gsonBldr.create().fromJson(json, Foo.class);
|
||||
|
||||
assertEquals(targetObject.intValue, 7);
|
||||
assertEquals(targetObject.stringValue, "seven");
|
||||
}
|
||||
|
||||
@Test
|
||||
public final void whenDeserializingToGenericObject_thenCorrect() {
|
||||
final Type typeToken = new TypeToken<GenericFoo<Integer>>() {
|
||||
}.getType();
|
||||
final String json = "{\"theValue\":1}";
|
||||
|
||||
final GenericFoo<Integer> targetObject = new Gson().fromJson(json, typeToken);
|
||||
|
||||
assertEquals(targetObject.theValue, new Integer(1));
|
||||
}
|
||||
|
||||
// tests - multiple elements
|
||||
|
||||
@Test
|
||||
public final void givenJsonArrayOfFoos_whenDeserializingToArray_thenCorrect() {
|
||||
final String json = "[{\"intValue\":1,\"stringValue\":\"one\"}," + "{\"intValue\":2,\"stringValue\":\"two\"}]";
|
||||
final Foo[] targetArray = new GsonBuilder().create().fromJson(json, Foo[].class);
|
||||
|
||||
assertThat(Lists.newArrayList(targetArray), hasItem(new Foo(1, "one")));
|
||||
assertThat(Lists.newArrayList(targetArray), hasItem(new Foo(2, "two")));
|
||||
assertThat(Lists.newArrayList(targetArray), not(hasItem(new Foo(1, "two"))));
|
||||
}
|
||||
|
||||
@Test
|
||||
public final void givenJsonArrayOfFoos_whenDeserializingCollection_thenCorrect() {
|
||||
final String json = "[{\"intValue\":1,\"stringValue\":\"one\"},{\"intValue\":2,\"stringValue\":\"two\"}]";
|
||||
final Type targetClassType = new TypeToken<ArrayList<Foo>>() {
|
||||
}.getType();
|
||||
|
||||
final Collection<Foo> targetCollection = new Gson().fromJson(json, targetClassType);
|
||||
assertThat(targetCollection, instanceOf(ArrayList.class));
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
@Test
|
||||
public void whenDeserializingJsonIntoElements_thenCorrect() {
|
||||
final String jsonSourceObject = "{\"valueInt\":7,\"valueString\":\"seven\"}";
|
||||
final JsonParser jParser = new JsonParser();
|
||||
final JsonElement jElement = jParser.parse(jsonSourceObject);
|
||||
final JsonObject jObject = jElement.getAsJsonObject();
|
||||
final int intValue = jObject.get("valueInt").getAsInt();
|
||||
final String stringValue = jObject.get("valueString").getAsString();
|
||||
|
||||
final Foo targetObject = new Foo(intValue, stringValue);
|
||||
|
||||
assertEquals(targetObject.intValue, 7);
|
||||
assertEquals(targetObject.stringValue, "seven");
|
||||
}
|
||||
|
||||
// new examples
|
||||
|
||||
@Test
|
||||
public void whenDeserializingToNestedObjects_thenCorrect() {
|
||||
final String json = "{\"intValue\":1,\"stringValue\":\"one\",\"innerFoo\":{\"name\":\"inner\"}}";
|
||||
|
||||
final FooWithInner targetObject = new Gson().fromJson(json, FooWithInner.class);
|
||||
|
||||
assertEquals(targetObject.intValue, 1);
|
||||
assertEquals(targetObject.stringValue, "one");
|
||||
assertEquals(targetObject.innerFoo.name, "inner");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenDeserializingUsingInstanceCreator_thenCorrect() {
|
||||
final String json = "{\"intValue\":1}";
|
||||
|
||||
final GsonBuilder gsonBldr = new GsonBuilder();
|
||||
gsonBldr.registerTypeAdapter(Foo.class, new FooInstanceCreator());
|
||||
final Foo targetObject = gsonBldr.create().fromJson(json, Foo.class);
|
||||
|
||||
assertEquals(targetObject.intValue, 1);
|
||||
assertEquals(targetObject.stringValue, "sample");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
package com.baeldung.gson.jsoncompare;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonParser;
|
||||
import org.junit.Test;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class JsonCompareUnitTest {
|
||||
@Test
|
||||
public void givenJsonStrings_whenCompared_thenNotEqual() {
|
||||
String string1 = "{\"fullName\": \"Emily Jenkins\", \"age\": 27 }";
|
||||
String string2 = "{\"fullName\": \"Emily Jenkins\", \"age\": 27}";
|
||||
|
||||
assertNotEquals(string1, string2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenIdenticalSimpleObjects_whenCompared_thenEqual() {
|
||||
JsonParser parser = new JsonParser();
|
||||
String string1 = "{\"customer\": {\"id\": \"44521\",\"fullName\": \"Emily Jenkins\", \"age\": 27 }}";
|
||||
String string2 = "{\"customer\": {\"id\": \"44521\", \"fullName\": \"Emily Jenkins\",\"age\": 27}}";
|
||||
|
||||
assertTrue(parser.parse(string1)
|
||||
.isJsonObject());
|
||||
assertEquals(parser.parse(string1), parser.parse(string2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenSameObjectsInDifferentOrder_whenCompared_thenEqual() {
|
||||
JsonParser parser = new JsonParser();
|
||||
String string1 = "{\"customer\": {\"id\": \"44521\",\"fullName\": \"Emily Jenkins\", \"age\": 27 }}";
|
||||
String string2 = "{\"customer\": {\"id\": \"44521\",\"age\": 27, \"fullName\": \"Emily Jenkins\" }}";
|
||||
|
||||
JsonElement json1 = parser.parse(string1);
|
||||
JsonElement json2 = parser.parse(string2);
|
||||
|
||||
assertEquals(json1, json2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenIdenticalArrays_whenCompared_thenEqual() {
|
||||
JsonParser parser = new JsonParser();
|
||||
String string1 = "[10, 20, 30]";
|
||||
String string2 = "[10, 20, 30]";
|
||||
|
||||
assertTrue(parser.parse(string1)
|
||||
.isJsonArray());
|
||||
assertEquals(parser.parse(string1), parser.parse(string2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenArraysInDifferentOrder_whenCompared_thenNotEqual() {
|
||||
JsonParser parser = new JsonParser();
|
||||
String string1 = "[20, 10, 30]";
|
||||
String string2 = "[10, 20, 30]";
|
||||
|
||||
assertNotEquals(parser.parse(string1), parser.parse(string2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenIdenticalNestedObjects_whenCompared_thenEqual() {
|
||||
JsonParser parser = new JsonParser();
|
||||
String string1 = "{\"customer\": {\"id\": \"44521\",\"fullName\": \"Emily Jenkins\", \"age\": 27, \"consumption_info\" : {\"fav_product\": \"Coke\", \"last_buy\": \"2012-04-23\"}}}";
|
||||
String string2 = "{\"customer\": {\"id\": \"44521\",\"fullName\": \"Emily Jenkins\", \"age\": 27, \"consumption_info\" : {\"last_buy\": \"2012-04-23\", \"fav_product\": \"Coke\"}}}";
|
||||
|
||||
JsonElement json1 = parser.parse(string1);
|
||||
JsonElement json2 = parser.parse(string2);
|
||||
|
||||
assertEquals(json1, json2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenIdenticalNestedObjectsWithArray_whenCompared_thenEqual() {
|
||||
JsonParser parser = new JsonParser();
|
||||
String string1 = "{\"customer\": {\"id\": \"44521\",\"fullName\": \"Emily Jenkins\", \"age\": 27, \"consumption_info\" : {\"last_buy\": \"2012-04-23\", \"prouducts\": [\"banana\", \"eggs\"]}}}";
|
||||
String string2 = "{\"customer\": {\"id\": \"44521\",\"fullName\": \"Emily Jenkins\", \"age\": 27, \"consumption_info\" : {\"last_buy\": \"2012-04-23\", \"prouducts\": [\"banana\", \"eggs\"]}}}";
|
||||
|
||||
JsonElement json1 = parser.parse(string1);
|
||||
JsonElement json2 = parser.parse(string2);
|
||||
|
||||
assertEquals(json1, json2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenNestedObjectsDifferentArrayOrder_whenCompared_thenNotEqual() {
|
||||
JsonParser parser = new JsonParser();
|
||||
String string1 = "{\"customer\": {\"id\": \"44521\",\"fullName\": \"Emily Jenkins\", \"age\": 27, \"consumption_info\" : {\"last_buy\": \"2012-04-23\", \"prouducts\": [\"banana\", \"eggs\"]}}}";
|
||||
String string2 = "{\"customer\": {\"id\": \"44521\",\"fullName\": \"Emily Jenkins\", \"age\": 27, \"consumption_info\" : {\"last_buy\": \"2012-04-23\", \"prouducts\": [\"eggs\", \"banana\"]}}}";
|
||||
|
||||
JsonElement json1 = parser.parse(string1);
|
||||
JsonElement json2 = parser.parse(string2);
|
||||
|
||||
assertNotEquals(json1, json2);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,248 @@
|
||||
package com.baeldung.gson.primitives;
|
||||
|
||||
import com.baeldung.gson.primitives.models.*;
|
||||
import com.google.gson.*;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
import static junit.framework.TestCase.*;
|
||||
|
||||
public class PrimitiveValuesUnitTest {
|
||||
@Test public void whenSerializingToJSON_thenShouldCreateJSON() {
|
||||
PrimitiveBundle primitiveBundle = new PrimitiveBundle();
|
||||
|
||||
// @formatter:off
|
||||
primitiveBundle.byteValue = (byte) 0x00001111;
|
||||
primitiveBundle.shortValue = (short) 3;
|
||||
primitiveBundle.intValue = 3;
|
||||
primitiveBundle.longValue = 3;
|
||||
primitiveBundle.floatValue = 3.5f;
|
||||
primitiveBundle.doubleValue = 3.5;
|
||||
primitiveBundle.booleanValue = true;
|
||||
primitiveBundle.charValue = 'a';
|
||||
// @formatter:on
|
||||
|
||||
Gson gson = new Gson();
|
||||
|
||||
String expected = "{\"byteValue\":17,\"shortValue\":3,\"intValue\":3,"
|
||||
+ "\"longValue\":3,\"floatValue\":3.5" + ",\"doubleValue\":3.5"
|
||||
+ ",\"booleanValue\":true,\"charValue\":\"a\"}";
|
||||
|
||||
assertEquals(expected, gson.toJson(primitiveBundle));
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class) public void
|
||||
whenSerializingInfinity_thenShouldRaiseAnException() {
|
||||
InfinityValuesExample model = new InfinityValuesExample();
|
||||
model.negativeInfinity = Float.NEGATIVE_INFINITY;
|
||||
model.positiveInfinity = Float.POSITIVE_INFINITY;
|
||||
|
||||
Gson gson = new Gson();
|
||||
|
||||
gson.toJson(model);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class) public void
|
||||
whenSerializingNaN_thenShouldRaiseAnException() {
|
||||
FloatExample model = new FloatExample();
|
||||
model.value = Float.NaN;
|
||||
|
||||
Gson gson = new Gson();
|
||||
gson.toJson(model);
|
||||
}
|
||||
|
||||
@Test public void whenDeserializingFromJSON_thenShouldParseTheValueInTheString() {
|
||||
String json = "{\"byteValue\": 17, \"shortValue\": 3, \"intValue\": 3, "
|
||||
+ "\"longValue\": 3, \"floatValue\": 3.5" + ", \"doubleValue\": 3.5"
|
||||
+ ", \"booleanValue\": true, \"charValue\": \"a\"}";
|
||||
|
||||
Gson gson = new Gson();
|
||||
PrimitiveBundle model = gson.fromJson(json, PrimitiveBundle.class);
|
||||
|
||||
// @formatter:off
|
||||
assertEquals(17, model.byteValue);
|
||||
assertEquals(3, model.shortValue);
|
||||
assertEquals(3, model.intValue);
|
||||
assertEquals(3, model.longValue);
|
||||
assertEquals(3.5, model.floatValue, 0.0001);
|
||||
assertEquals(3.5, model.doubleValue, 0.0001);
|
||||
assertTrue( model.booleanValue);
|
||||
assertEquals('a', model.charValue);
|
||||
// @formatter:on
|
||||
}
|
||||
|
||||
@Test public void whenDeserializingHighPrecissionNumberIntoFloat_thenShouldPerformRounding() {
|
||||
String json = "{\"value\": 12.123425589123456}";
|
||||
Gson gson = new Gson();
|
||||
FloatExample model = gson.fromJson(json, FloatExample.class);
|
||||
assertEquals(12.123426f, model.value, 0.000001);
|
||||
}
|
||||
|
||||
@Test public void whenDeserializingHighPrecissiongNumberIntoDouble_thenShouldPerformRounding() {
|
||||
String json = "{\"value\": 12.123425589123556}";
|
||||
Gson gson = new Gson();
|
||||
DoubleExample model = gson.fromJson(json, DoubleExample.class);
|
||||
assertEquals(12.123425589124f, model.value, 0.000001);
|
||||
}
|
||||
|
||||
|
||||
@Test public void whenDeserializingValueThatOverflows_thenShouldOverflowSilently() {
|
||||
Gson gson = new Gson();
|
||||
String json = "{\"value\": \"300\"}";
|
||||
ByteExample model = gson.fromJson(json, ByteExample.class);
|
||||
|
||||
assertEquals(44, model.value);
|
||||
}
|
||||
|
||||
@Test public void whenDeserializingRealIntoByte_thenShouldRaiseAnException() {
|
||||
Gson gson = new Gson();
|
||||
String json = "{\"value\": 2.3}";
|
||||
try {
|
||||
gson.fromJson(json, ByteExample.class);
|
||||
} catch (Exception ex) {
|
||||
assertTrue(ex instanceof JsonSyntaxException);
|
||||
assertTrue(ex.getCause() instanceof NumberFormatException);
|
||||
return;
|
||||
}
|
||||
|
||||
fail();
|
||||
}
|
||||
|
||||
@Test public void whenDeserializingRealIntoLong_thenShouldRaiseAnException() {
|
||||
Gson gson = new Gson();
|
||||
String json = "{\"value\": 2.3}";
|
||||
try {
|
||||
gson.fromJson(json, LongExample.class);
|
||||
} catch (Exception ex) {
|
||||
assertTrue(ex instanceof JsonSyntaxException);
|
||||
assertTrue(ex.getCause() instanceof NumberFormatException);
|
||||
return;
|
||||
}
|
||||
|
||||
fail();
|
||||
}
|
||||
|
||||
@Test public void whenDeserializingRealWhoseDecimalPartIs0_thenShouldParseItCorrectly() {
|
||||
Gson gson = new Gson();
|
||||
String json = "{\"value\": 2.0}";
|
||||
LongExample model = gson.fromJson(json, LongExample.class);
|
||||
assertEquals(2, model.value);
|
||||
}
|
||||
|
||||
@Test public void whenDeserializingUnicodeChar_thenShouldParseItCorrectly() {
|
||||
Gson gson = new Gson();
|
||||
String json = "{\"value\": \"\\u00AE\"}";
|
||||
CharExample model = gson.fromJson(json, CharExample.class);
|
||||
|
||||
assertEquals('\u00AE', model.value);
|
||||
}
|
||||
|
||||
@Test public void whenDeserializingNullValues_thenShouldIgnoreThoseFields() {
|
||||
Gson gson = new Gson();
|
||||
// @formatter:off
|
||||
String json = "{\"byteValue\": null, \"shortValue\": null, "
|
||||
+ "\"intValue\": null, " + "\"longValue\": null, \"floatValue\": null"
|
||||
+ ", \"doubleValue\": null}";
|
||||
// @formatter:on
|
||||
PrimitiveBundleInitialized model = gson.fromJson(json,
|
||||
PrimitiveBundleInitialized.class);
|
||||
|
||||
assertEquals(1, model.byteValue);
|
||||
assertEquals(1, model.shortValue);
|
||||
assertEquals(1, model.intValue);
|
||||
assertEquals(1, model.longValue);
|
||||
assertEquals(1, model.floatValue, 0.0001);
|
||||
assertEquals(1, model.doubleValue, 0.0001);
|
||||
}
|
||||
|
||||
@Test(expected = JsonSyntaxException.class) public void
|
||||
whenDeserializingTheEmptyString_thenShouldRaiseAnException() {
|
||||
Gson gson = new Gson();
|
||||
// @formatter:off
|
||||
String json = "{\"byteValue\": \"\", \"shortValue\": \"\", "
|
||||
+ "\"intValue\": \"\", " + "\"longValue\": \"\", \"floatValue\": \"\""
|
||||
+ ", \"doubleValue\": \"\"" + ", \"booleanValue\": \"\"}";
|
||||
// @formatter:on
|
||||
gson.fromJson(json, PrimitiveBundleInitialized.class);
|
||||
}
|
||||
|
||||
@Test public void whenDeserializingTheEmptyStringIntoChar_thenShouldHaveTheEmtpyChar() {
|
||||
Gson gson = new Gson();
|
||||
// @formatter:off
|
||||
String json = "{\"charValue\": \"\"}";
|
||||
// @formatter:on
|
||||
CharExample model = gson.fromJson(json, CharExample.class);
|
||||
|
||||
assertEquals(Character.MIN_VALUE, model.value);
|
||||
}
|
||||
|
||||
@Test public void whenDeserializingValidValueAppearingInAString_thenShouldParseTheValue() {
|
||||
Gson gson = new Gson();
|
||||
// @formatter:off
|
||||
String json = "{\"byteValue\": \"15\", \"shortValue\": \"15\", "
|
||||
+ "\"intValue\": \"15\", " + "\"longValue\": \"15\", \"floatValue\": \"15.0\""
|
||||
+ ", \"doubleValue\": \"15.0\"}";
|
||||
// @formatter:on
|
||||
PrimitiveBundleInitialized model = gson.fromJson(json,
|
||||
PrimitiveBundleInitialized.class);
|
||||
|
||||
assertEquals(15, model.byteValue);
|
||||
assertEquals(15, model.shortValue);
|
||||
assertEquals(15, model.intValue);
|
||||
assertEquals(15, model.longValue);
|
||||
assertEquals(15, model.floatValue, 0.0001);
|
||||
assertEquals(15, model.doubleValue, 0.0001);
|
||||
}
|
||||
|
||||
@Test public void whenDeserializingABooleanFrom0Or1Integer_thenShouldRaiseAnException() {
|
||||
String json = "{\"value\": 1}";
|
||||
Gson gson = new Gson();
|
||||
|
||||
try {
|
||||
gson.fromJson(json, BooleanExample.class);
|
||||
} catch (Exception ex) {
|
||||
assertTrue(ex instanceof JsonSyntaxException);
|
||||
assertTrue(ex.getCause() instanceof IllegalStateException);
|
||||
return;
|
||||
}
|
||||
|
||||
fail();
|
||||
}
|
||||
|
||||
@Test public void whenDeserializingWithCustomDeserializerABooleanFrom0Or1Integer_thenShouldWork() {
|
||||
String json = "{\"value\": 1}";
|
||||
GsonBuilder builder = new GsonBuilder();
|
||||
builder.registerTypeAdapter(BooleanExample.class,
|
||||
new BooleanAs2ValueIntegerDeserializer());
|
||||
|
||||
Gson gson = builder.create();
|
||||
|
||||
BooleanExample model = gson.fromJson(json, BooleanExample.class);
|
||||
|
||||
assertTrue(model.value);
|
||||
}
|
||||
|
||||
// @formatter:off
|
||||
static class BooleanAs2ValueIntegerDeserializer implements JsonDeserializer<BooleanExample> {
|
||||
@Override public BooleanExample deserialize(
|
||||
JsonElement jsonElement,
|
||||
Type type,
|
||||
JsonDeserializationContext jsonDeserializationContext) throws JsonParseException {
|
||||
|
||||
BooleanExample model = new BooleanExample();
|
||||
int value = jsonElement.getAsJsonObject().getAsJsonPrimitive("value").getAsInt();
|
||||
if (value == 0) {
|
||||
model.value = false;
|
||||
} else if (value == 1) {
|
||||
model.value = true;
|
||||
} else {
|
||||
throw new JsonParseException("Unexpected value. Trying to deserialize "
|
||||
+ "a boolean from an integer different than 0 and 1.");
|
||||
}
|
||||
|
||||
return model;
|
||||
}
|
||||
}
|
||||
// @formatter:on
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.baeldung.gson.serialization;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonSerializationContext;
|
||||
import com.google.gson.JsonSerializer;
|
||||
|
||||
public class DifferentNameSerializer implements JsonSerializer<SourceClass> {
|
||||
|
||||
@Override
|
||||
public JsonElement serialize(final SourceClass src, final Type typeOfSrc, final JsonSerializationContext context) {
|
||||
final String otherIntValueName = "otherIntValue";
|
||||
final String otherStringValueName = "otherStringValue";
|
||||
|
||||
final JsonObject jObject = new JsonObject();
|
||||
jObject.addProperty(otherIntValueName, src.getIntValue());
|
||||
jObject.addProperty(otherStringValueName, src.getStringValue());
|
||||
|
||||
return jObject;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package com.baeldung.gson.serialization;
|
||||
|
||||
import com.baeldung.gson.entities.Movie;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.baeldung.gson.entities.ActorGson;
|
||||
import com.baeldung.gson.entities.MovieWithNullValue;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class GsonSerializeUnitTest {
|
||||
|
||||
@Test
|
||||
public void whenSimpleSerialize_thenCorrect() throws ParseException {
|
||||
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
|
||||
|
||||
ActorGson rudyYoungblood = new ActorGson("nm2199632", sdf.parse("21-09-1982"), Arrays.asList("Apocalypto", "Beatdown", "Wind Walkers"));
|
||||
Movie movie = new Movie("tt0472043", "Mel Gibson", Arrays.asList(rudyYoungblood));
|
||||
|
||||
String expectedOutput = "{\"imdbId\":\"tt0472043\",\"director\":\"Mel Gibson\",\"actors\":[{\"imdbId\":\"nm2199632\",\"dateOfBirth\":\"Sep 21, 1982 12:00:00 AM\",\"filmography\":[\"Apocalypto\",\"Beatdown\",\"Wind Walkers\"]}]}";
|
||||
Assert.assertEquals(new Gson().toJson(movie), expectedOutput);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenCustomSerialize_thenCorrect() throws ParseException {
|
||||
Gson gson = new GsonBuilder().setPrettyPrinting().excludeFieldsWithoutExposeAnnotation().serializeNulls().disableHtmlEscaping().registerTypeAdapter(ActorGson.class, new ActorGsonSerializer()).create();
|
||||
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
|
||||
|
||||
ActorGson rudyYoungblood = new ActorGson("nm2199632", sdf.parse("21-09-1982"), Arrays.asList("Apocalypto", "Beatdown", "Wind Walkers"));
|
||||
MovieWithNullValue movieWithNullValue = new MovieWithNullValue(null, "Mel Gibson", Arrays.asList(rudyYoungblood));
|
||||
|
||||
String expectedOutput = new GsonBuilder()
|
||||
.setPrettyPrinting()
|
||||
.serializeNulls()
|
||||
.disableHtmlEscaping()
|
||||
.create()
|
||||
.toJson(new JsonParser()
|
||||
.parse("{\"imdbId\":null,\"actors\":[{\"<strong>IMDB Code</strong>\":\"nm2199632\",\"<strong>Date Of Birth</strong>\":\"21-09-1982\",\"<strong>N° Film:</strong> \":3,\"filmography\":\"Apocalypto-Beatdown-Wind Walkers\"}]}"));
|
||||
Assert.assertEquals(gson.toJson(movieWithNullValue), expectedOutput);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.baeldung.gson.serialization;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonSerializationContext;
|
||||
import com.google.gson.JsonSerializer;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
public class IgnoringFieldsNotMatchingCriteriaSerializer implements JsonSerializer<SourceClass> {
|
||||
@Override
|
||||
public JsonElement serialize(SourceClass src, Type typeOfSrc, JsonSerializationContext context) {
|
||||
JsonObject jObject = new JsonObject();
|
||||
|
||||
// Criteria: intValue >= 0
|
||||
if (src.getIntValue() >= 0) {
|
||||
String intValue = "intValue";
|
||||
jObject.addProperty(intValue, src.getIntValue());
|
||||
}
|
||||
|
||||
String stringValue = "stringValue";
|
||||
jObject.addProperty(stringValue, src.getStringValue());
|
||||
|
||||
return jObject;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.baeldung.gson.serialization;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonSerializationContext;
|
||||
import com.google.gson.JsonSerializer;
|
||||
|
||||
public class IgnoringFieldsSerializer implements JsonSerializer<SourceClass> {
|
||||
@Override
|
||||
public JsonElement serialize(final SourceClass src, final Type typeOfSrc, final JsonSerializationContext context) {
|
||||
final String intValue = "intValue";
|
||||
final JsonObject jObject = new JsonObject();
|
||||
jObject.addProperty(intValue, src.getIntValue());
|
||||
|
||||
return jObject;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package com.baeldung.gson.serialization;
|
||||
|
||||
public class SourceClass {
|
||||
private int intValue;
|
||||
private String stringValue;
|
||||
|
||||
public SourceClass(final int intValue, final String stringValue) {
|
||||
this.intValue = intValue;
|
||||
this.stringValue = stringValue;
|
||||
}
|
||||
|
||||
// API
|
||||
|
||||
public int getIntValue() {
|
||||
return intValue;
|
||||
}
|
||||
|
||||
public String getStringValue() {
|
||||
return stringValue;
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SourceClass{" + "intValue=" + intValue + ", stringValue='" + stringValue + '\'' + '}';
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
if (this == o)
|
||||
return true;
|
||||
if (!(o instanceof SourceClass))
|
||||
return false;
|
||||
|
||||
final SourceClass that = (SourceClass) o;
|
||||
|
||||
if (intValue != that.intValue)
|
||||
return false;
|
||||
if (!stringValue.equals(that.stringValue))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = intValue;
|
||||
result = 31 * result + stringValue.hashCode();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
package com.baeldung.gson.serialization.test;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
|
||||
import com.baeldung.gson.serialization.DifferentNameSerializer;
|
||||
import com.baeldung.gson.serialization.IgnoringFieldsNotMatchingCriteriaSerializer;
|
||||
import com.baeldung.gson.serialization.IgnoringFieldsSerializer;
|
||||
import com.baeldung.gson.serialization.SourceClass;
|
||||
|
||||
import org.assertj.core.util.Lists;
|
||||
import org.joda.time.DateTime;
|
||||
import org.junit.Test;
|
||||
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
public class GsonSerializationUnitTest {
|
||||
|
||||
@Test
|
||||
public void givenArrayOfObjects_whenSerializing_thenCorrect() {
|
||||
final SourceClass[] sourceArray = { new SourceClass(1, "one"), new SourceClass(2, "two") };
|
||||
final String jsonString = new Gson().toJson(sourceArray);
|
||||
|
||||
// test
|
||||
final String expectedResult = "[{\"intValue\":1,\"stringValue\":\"one\"},{\"intValue\":2,\"stringValue\":\"two\"}]";
|
||||
assertEquals(expectedResult, jsonString);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenCollection_whenSerializing_thenCorrect() {
|
||||
final Collection<SourceClass> sourceCollection = Lists.newArrayList(new SourceClass(1, "one"), new SourceClass(2, "two"));
|
||||
final String jsonCollection = new Gson().toJson(sourceCollection);
|
||||
|
||||
final String expectedResult = "[{\"intValue\":1,\"stringValue\":\"one\"},{\"intValue\":2,\"stringValue\":\"two\"}]";
|
||||
assertEquals(expectedResult, jsonCollection);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenUsingCustomSerializer_whenChangingNameOfFieldOnSerializing_thenCorrect() {
|
||||
final SourceClass sourceObject = new SourceClass(7, "seven");
|
||||
final GsonBuilder gsonBuildr = new GsonBuilder();
|
||||
gsonBuildr.registerTypeAdapter(SourceClass.class, new DifferentNameSerializer());
|
||||
final String jsonString = gsonBuildr.create().toJson(sourceObject);
|
||||
|
||||
final String expectedResult = "{\"otherIntValue\":7,\"otherStringValue\":\"seven\"}";
|
||||
assertEquals(expectedResult, jsonString);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenIgnoringAField_whenSerializingWithCustomSerializer_thenFieldIgnored() {
|
||||
final SourceClass sourceObject = new SourceClass(7, "seven");
|
||||
final GsonBuilder gsonBuildr = new GsonBuilder();
|
||||
gsonBuildr.registerTypeAdapter(SourceClass.class, new IgnoringFieldsSerializer());
|
||||
final String jsonString = gsonBuildr.create().toJson(sourceObject);
|
||||
|
||||
final String expectedResult = "{\"intValue\":7}";
|
||||
assertEquals(expectedResult, jsonString);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenUsingCustomDeserializer_whenFieldNotMatchesCriteria_thenIgnored() {
|
||||
final SourceClass sourceObject = new SourceClass(-1, "minus 1");
|
||||
final GsonBuilder gsonBuildr = new GsonBuilder();
|
||||
gsonBuildr.registerTypeAdapter(SourceClass.class, new IgnoringFieldsNotMatchingCriteriaSerializer());
|
||||
final Gson gson = gsonBuildr.create();
|
||||
final Type sourceObjectType = new TypeToken<SourceClass>() {
|
||||
}.getType();
|
||||
final String jsonString = gson.toJson(sourceObject, sourceObjectType);
|
||||
|
||||
final String expectedResult = "{\"stringValue\":\"minus 1\"}";
|
||||
assertEquals(expectedResult, jsonString);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenDate_whenSerializing_thenCorrect() {
|
||||
Date sourceDate = new DateTime().withYear(2000).withMonthOfYear(1).withDayOfMonth(1).withHourOfDay(0).withMinuteOfHour(0).withSecondOfMinute(0).toDate();
|
||||
|
||||
final Gson gson = new Gson();
|
||||
Type sourceDateType = new TypeToken<Date>() {
|
||||
}.getType();
|
||||
String jsonDate = gson.toJson(sourceDate, sourceDateType);
|
||||
|
||||
System.out.println("jsonDate:\n" + jsonDate);
|
||||
String expectedResult = "\"Jan 1, 2000 12:00:00 AM\"";
|
||||
assertEquals(expectedResult, jsonDate);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package com.baeldung.gson.serialization.test;
|
||||
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import com.baeldung.gson.entities.User;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
import org.junit.runners.Parameterized.Parameter;
|
||||
import org.junit.runners.Parameterized.Parameters;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
|
||||
@RunWith(Parameterized.class)
|
||||
public class JsonFileUnitTest {
|
||||
|
||||
@Parameter
|
||||
public Object object;
|
||||
|
||||
@Parameters
|
||||
public static Object[] data() {
|
||||
return new Object[] { 123.45, new User(1, "Tom", "American") };
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenProperData_whenStoredInFile_shouldSaveJsonSuccessfully() {
|
||||
String filePath = "target/output.json";
|
||||
try (Writer writer = new FileWriter(filePath)) {
|
||||
Gson gson = new GsonBuilder().setPrettyPrinting().create();
|
||||
gson.toJson(object, writer);
|
||||
Assert.assertTrue(Files.exists(Paths.get(filePath)));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
package com.baeldung.gson.serializationwithexclusions;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import com.google.gson.ExclusionStrategy;
|
||||
import com.google.gson.FieldAttributes;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
|
||||
class SerializationWithExclusionsUnitTest {
|
||||
|
||||
final String expectedResult = "{\"id\":1,\"name\":\"foo\",\"subclass\":{\"id\":42,\"description\":\"the answer\"}}";
|
||||
|
||||
@Test
|
||||
public void givenClassWithTransientFields_whenSerializing_thenCorrectWithoutTransientFields() {
|
||||
MyClassWithTransientFields source = new MyClassWithTransientFields(1L, "foo", "bar", new MySubClassWithTransientFields(42L, "the answer", "Verbose field which we don't want to be serialized"));
|
||||
String jsonString = new Gson().toJson(source);
|
||||
assertEquals(expectedResult, jsonString);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenClassAnnotated_whenSerializing_thenCorrectWithoutNotAnnotatedFields() {
|
||||
MyClassWithAnnotatedFields source = new MyClassWithAnnotatedFields(1L, "foo", "bar", new MySubClassWithAnnotatedFields(42L, "the answer", "Verbose field which we don't want to be serialized"));
|
||||
Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation()
|
||||
.create();
|
||||
String jsonString = gson.toJson(source);
|
||||
|
||||
assertEquals(expectedResult, jsonString);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenExclusionStrategyByClassesAndFields_whenSerializing_thenFollowStrategy() {
|
||||
MyClass source = new MyClass(1L, "foo", "bar", new MySubClass(42L, "the answer", "Verbose field which we don't want to be serialized"));
|
||||
ExclusionStrategy strategy = new ExclusionStrategy() {
|
||||
@Override
|
||||
public boolean shouldSkipField(FieldAttributes field) {
|
||||
if (field.getDeclaringClass() == MyClass.class && field.getName()
|
||||
.equals("other"))
|
||||
return true;
|
||||
if (field.getDeclaringClass() == MySubClass.class && field.getName()
|
||||
.equals("otherVerboseInfo"))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldSkipClass(Class<?> clazz) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
Gson gson = new GsonBuilder().addSerializationExclusionStrategy(strategy)
|
||||
.create();
|
||||
String jsonString = gson.toJson(source);
|
||||
|
||||
assertEquals(expectedResult, jsonString);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenExclusionStrategyByStartsWith_whenSerializing_thenFollowStrategy() {
|
||||
MyClass source = new MyClass(1L, "foo", "bar", new MySubClass(42L, "the answer", "Verbose field which we don't want to be serialized"));
|
||||
ExclusionStrategy strategy = new ExclusionStrategy() {
|
||||
@Override
|
||||
public boolean shouldSkipClass(Class<?> clazz) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldSkipField(FieldAttributes field) {
|
||||
return field.getName().startsWith("other");
|
||||
}
|
||||
};
|
||||
Gson gson = new GsonBuilder().setExclusionStrategies(strategy)
|
||||
.create();
|
||||
String jsonString = gson.toJson(source);
|
||||
|
||||
assertEquals(expectedResult, jsonString);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenExclusionStrategyByCustomAnnotation_whenSerializing_thenFollowStrategy() {
|
||||
MyClassWithCustomAnnotatedFields source = new MyClassWithCustomAnnotatedFields(1L, "foo", "bar", new MySubClassWithCustomAnnotatedFields(42L, "the answer", "Verbose field which we don't want to be serialized"));
|
||||
ExclusionStrategy strategy = new ExclusionStrategy() {
|
||||
@Override
|
||||
public boolean shouldSkipClass(Class<?> clazz) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldSkipField(FieldAttributes field) {
|
||||
return field.getAnnotation(Exclude.class) != null;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
Gson gson = new GsonBuilder().setExclusionStrategies(strategy)
|
||||
.create();
|
||||
String jsonString = gson.toJson(source);
|
||||
assertEquals(expectedResult, jsonString);
|
||||
}
|
||||
|
||||
}
|
||||
13
json-modules/gson/src/test/resources/.gitignore
vendored
Normal file
13
json-modules/gson/src/test/resources/.gitignore
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
*.class
|
||||
|
||||
#folders#
|
||||
/target
|
||||
/neoDb*
|
||||
/data
|
||||
/src/main/webapp/WEB-INF/classes
|
||||
*/META-INF/*
|
||||
|
||||
# Packaged files #
|
||||
*.jar
|
||||
*.war
|
||||
*.ear
|
||||
19
json-modules/gson/src/test/resources/logback-test.xml
Normal file
19
json-modules/gson/src/test/resources/logback-test.xml
Normal file
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
|
||||
</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<logger name="org.springframework" level="WARN"/>
|
||||
<logger name="org.springframework.transaction" level="WARN"/>
|
||||
|
||||
<!-- in order to debug some marshalling issues, this needs to be TRACE -->
|
||||
<logger name="org.springframework.web.servlet.mvc" level="WARN"/>
|
||||
|
||||
<root level="INFO">
|
||||
<appender-ref ref="STDOUT"/>
|
||||
</root>
|
||||
</configuration>
|
||||
13
json-modules/json-2/README.md
Normal file
13
json-modules/json-2/README.md
Normal file
@@ -0,0 +1,13 @@
|
||||
## JSON
|
||||
|
||||
This module contains articles about JSON.
|
||||
|
||||
### Relevant Articles:
|
||||
|
||||
- [Introduction to Jsoniter](https://www.baeldung.com/java-jsoniter)
|
||||
- [Introduction to Moshi Json](https://www.baeldung.com/java-json-moshi)
|
||||
- [Hypermedia Serialization With JSON-LD](https://www.baeldung.com/json-linked-data)
|
||||
- [Generate a Java Class From JSON](https://www.baeldung.com/java-generate-class-from-json)
|
||||
- [A Guide to FastJson](https://www.baeldung.com/fastjson)
|
||||
- [Check Whether a String is Valid JSON in Java](https://www.baeldung.com/java-validate-json-string)
|
||||
- More Articles: [[<-- prev]](/json)
|
||||
163
json-modules/json-2/pom.xml
Normal file
163
json-modules/json-2/pom.xml
Normal file
@@ -0,0 +1,163 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>json-2</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>json-modules</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.json</groupId>
|
||||
<artifactId>json</artifactId>
|
||||
<version>${json.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>fastjson</artifactId>
|
||||
<version>${fastjson.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jsonschema2pojo</groupId>
|
||||
<artifactId>jsonschema2pojo-core</artifactId>
|
||||
<version>${jsonschema2pojo-core.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.jsoniter</groupId>
|
||||
<artifactId>jsoniter</artifactId>
|
||||
<version>${jsoniter.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.squareup.moshi</groupId>
|
||||
<artifactId>moshi</artifactId>
|
||||
<version>${moshi.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.squareup.moshi</groupId>
|
||||
<artifactId>moshi-adapters</artifactId>
|
||||
<version>${moshi.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>${commons-lang3.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-annotations</artifactId>
|
||||
<version>${jackson.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
<version>${jackson.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.io-informatics.oss</groupId>
|
||||
<artifactId>jackson-jsonld</artifactId>
|
||||
<version>${jackson-jsonld.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<artifactId>jackson-annotations</artifactId>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<artifactId>jackson-core</artifactId>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<artifactId>jsonld-java</artifactId>
|
||||
<groupId>com.github.jsonld-java</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>de.escalon.hypermedia</groupId>
|
||||
<artifactId>hydra-jsonld</artifactId>
|
||||
<version>${hydra-jsonld.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.jsonld-java</groupId>
|
||||
<artifactId>jsonld-java</artifactId>
|
||||
<version>${jsonld-java.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>jackson-core</artifactId>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<!--This plugin's configuration is used to store Eclipse m2e settings only. It has no
|
||||
influence on the Maven build itself. -->
|
||||
<plugin>
|
||||
<groupId>org.eclipse.m2e</groupId>
|
||||
<artifactId>lifecycle-mapping</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<configuration>
|
||||
<lifecycleMappingMetadata>
|
||||
<pluginExecutions>
|
||||
<pluginExecution>
|
||||
<pluginExecutionFilter>
|
||||
<groupId>
|
||||
org.apache.maven.plugins
|
||||
</groupId>
|
||||
<artifactId>
|
||||
maven-pmd-plugin
|
||||
</artifactId>
|
||||
<versionRange>
|
||||
[3.13.0,)
|
||||
</versionRange>
|
||||
<goals>
|
||||
<goal>check</goal>
|
||||
</goals>
|
||||
</pluginExecutionFilter>
|
||||
<action>
|
||||
<ignore></ignore>
|
||||
</action>
|
||||
</pluginExecution>
|
||||
</pluginExecutions>
|
||||
</lifecycleMappingMetadata>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
</build>
|
||||
|
||||
<properties>
|
||||
<jsoniter.version>0.9.23</jsoniter.version>
|
||||
<moshi.version>1.9.2</moshi.version>
|
||||
<fastjson.version>1.2.21</fastjson.version>
|
||||
<json.version>20211205</json.version>
|
||||
<jsonschema2pojo-core.version>1.1.1</jsonschema2pojo-core.version>
|
||||
<jackson-jsonld.version>0.1.1</jackson-jsonld.version>
|
||||
<hydra-jsonld.version>0.4.2</hydra-jsonld.version>
|
||||
<jsonld-java.version>0.13.0</jsonld-java.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.baeldung.jsoniter.model;
|
||||
|
||||
public class Name {
|
||||
private String firstName;
|
||||
private String surname;
|
||||
|
||||
public String getFirstName() {
|
||||
return firstName;
|
||||
}
|
||||
|
||||
public void setFirstName(String firstName) {
|
||||
this.firstName = firstName;
|
||||
}
|
||||
|
||||
public String getSurname() {
|
||||
return surname;
|
||||
}
|
||||
|
||||
public void setSurname(String surname) {
|
||||
this.surname = surname;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.baeldung.jsoniter.model;
|
||||
|
||||
import com.jsoniter.annotation.JsonProperty;
|
||||
import com.jsoniter.fuzzy.MaybeStringIntDecoder;
|
||||
|
||||
public class Student {
|
||||
@JsonProperty(decoder = MaybeStringIntDecoder.class)
|
||||
private int id;
|
||||
private Name name;
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Name getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(Name name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
package com.baeldung.jsonoptimization;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Objects;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
public class Customer {
|
||||
|
||||
private long id;
|
||||
private String firstName;
|
||||
private String lastName;
|
||||
private String street;
|
||||
private String postalCode;
|
||||
private String city;
|
||||
private String state;
|
||||
private String phoneNumber;
|
||||
private String email;
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getFirstName() {
|
||||
return firstName;
|
||||
}
|
||||
|
||||
public void setFirstName(String firstName) {
|
||||
this.firstName = firstName;
|
||||
}
|
||||
|
||||
public String getLastName() {
|
||||
return lastName;
|
||||
}
|
||||
|
||||
public void setLastName(String lastName) {
|
||||
this.lastName = lastName;
|
||||
}
|
||||
|
||||
public String getStreet() {
|
||||
return street;
|
||||
}
|
||||
|
||||
public void setStreet(String street) {
|
||||
this.street = street;
|
||||
}
|
||||
|
||||
public String getPostalCode() {
|
||||
return postalCode;
|
||||
}
|
||||
|
||||
public void setPostalCode(String postalCode) {
|
||||
this.postalCode = postalCode;
|
||||
}
|
||||
|
||||
public String getCity() {
|
||||
return city;
|
||||
}
|
||||
|
||||
public void setCity(String city) {
|
||||
this.city = city;
|
||||
}
|
||||
|
||||
public String getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
public void setState(String state) {
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
public String getPhoneNumber() {
|
||||
return phoneNumber;
|
||||
}
|
||||
|
||||
public void setPhoneNumber(String phoneNumber) {
|
||||
this.phoneNumber = phoneNumber;
|
||||
}
|
||||
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
public void setEmail(String email) {
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(city, email, firstName, id, lastName, phoneNumber, postalCode, state, street);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (!(obj instanceof Customer)) {
|
||||
return false;
|
||||
}
|
||||
Customer other = (Customer) obj;
|
||||
return Objects.equals(city, other.city) && Objects.equals(email, other.email) && Objects.equals(firstName, other.firstName) && id == other.id && Objects.equals(lastName, other.lastName) && Objects.equals(phoneNumber, other.phoneNumber)
|
||||
&& Objects.equals(postalCode, other.postalCode) && Objects.equals(state, other.state) && Objects.equals(street, other.street);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Customer [id=" + id + ", firstName=" + firstName + ", lastName=" + lastName + ", street=" + street + ", postalCode=" + postalCode + ", city=" + city + ", state=" + state + ", phoneNumber=" + phoneNumber + ", email=" + email + "]";
|
||||
}
|
||||
|
||||
public static Customer[] fromMockFile() throws IOException {
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
InputStream jsonFile = new FileInputStream("src/test/resources/json_optimization_mock_data.json");
|
||||
Customer[] feedback = objectMapper.readValue(jsonFile, Customer[].class);
|
||||
return feedback;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package com.baeldung.jsonoptimization;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.ObjectCodec;
|
||||
import com.fasterxml.jackson.databind.DeserializationContext;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
|
||||
|
||||
public class CustomerDeserializer extends StdDeserializer<Customer> {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public CustomerDeserializer() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
public CustomerDeserializer(Class<Customer> t) {
|
||||
super(t);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Customer deserialize(JsonParser parser, DeserializationContext deserializer) throws IOException {
|
||||
Customer feedback = new Customer();
|
||||
ObjectCodec codec = parser.getCodec();
|
||||
JsonNode node = codec.readTree(parser);
|
||||
|
||||
feedback.setId(node.get(0)
|
||||
.asLong());
|
||||
feedback.setFirstName(node.get(1)
|
||||
.asText());
|
||||
feedback.setLastName(node.get(2)
|
||||
.asText());
|
||||
feedback.setStreet(node.get(3)
|
||||
.asText());
|
||||
feedback.setPostalCode(node.get(4)
|
||||
.asText());
|
||||
feedback.setCity(node.get(5)
|
||||
.asText());
|
||||
feedback.setState(node.get(6)
|
||||
.asText());
|
||||
JsonNode phoneNumber = node.get(7);
|
||||
feedback.setPhoneNumber(phoneNumber.isNull() ? null : phoneNumber.asText());
|
||||
JsonNode email = node.get(8);
|
||||
feedback.setEmail(email.isNull() ? null : email.asText());
|
||||
|
||||
return feedback;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.baeldung.jsonoptimization;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.databind.SerializerProvider;
|
||||
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
|
||||
|
||||
public class CustomerSerializer extends StdSerializer<Customer> {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public CustomerSerializer() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
public CustomerSerializer(Class<Customer> t) {
|
||||
super(t);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serialize(Customer customer, JsonGenerator jsonGenerator, SerializerProvider serializer) throws IOException {
|
||||
jsonGenerator.writeStartArray();
|
||||
jsonGenerator.writeNumber(customer.getId());
|
||||
jsonGenerator.writeString(customer.getFirstName());
|
||||
jsonGenerator.writeString(customer.getLastName());
|
||||
jsonGenerator.writeString(customer.getStreet());
|
||||
jsonGenerator.writeString(customer.getPostalCode());
|
||||
jsonGenerator.writeString(customer.getCity());
|
||||
jsonGenerator.writeString(customer.getState());
|
||||
jsonGenerator.writeString(customer.getPhoneNumber());
|
||||
jsonGenerator.writeString(customer.getEmail());
|
||||
jsonGenerator.writeEndArray();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,155 @@
|
||||
package com.baeldung.jsonoptimization;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
public class CustomerShortNames {
|
||||
|
||||
@JsonProperty("i")
|
||||
private long id;
|
||||
|
||||
@JsonProperty("f")
|
||||
private String firstName;
|
||||
|
||||
@JsonProperty("l")
|
||||
private String lastName;
|
||||
|
||||
@JsonProperty("s")
|
||||
private String street;
|
||||
|
||||
@JsonProperty("p")
|
||||
private String postalCode;
|
||||
|
||||
@JsonProperty("c")
|
||||
private String city;
|
||||
|
||||
@JsonProperty("a")
|
||||
private String state;
|
||||
|
||||
@JsonProperty("o")
|
||||
private String phoneNumber;
|
||||
|
||||
@JsonProperty("e")
|
||||
private String email;
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getFirstName() {
|
||||
return firstName;
|
||||
}
|
||||
|
||||
public void setFirstName(String firstName) {
|
||||
this.firstName = firstName;
|
||||
}
|
||||
|
||||
public String getLastName() {
|
||||
return lastName;
|
||||
}
|
||||
|
||||
public void setLastName(String lastName) {
|
||||
this.lastName = lastName;
|
||||
}
|
||||
|
||||
public String getStreet() {
|
||||
return street;
|
||||
}
|
||||
|
||||
public void setStreet(String street) {
|
||||
this.street = street;
|
||||
}
|
||||
|
||||
public String getPostalCode() {
|
||||
return postalCode;
|
||||
}
|
||||
|
||||
public void setPostalCode(String postalCode) {
|
||||
this.postalCode = postalCode;
|
||||
}
|
||||
|
||||
public String getCity() {
|
||||
return city;
|
||||
}
|
||||
|
||||
public void setCity(String city) {
|
||||
this.city = city;
|
||||
}
|
||||
|
||||
public String getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
public void setState(String state) {
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
public String getPhoneNumber() {
|
||||
return phoneNumber;
|
||||
}
|
||||
|
||||
public void setPhoneNumber(String phoneNumber) {
|
||||
this.phoneNumber = phoneNumber;
|
||||
}
|
||||
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
public void setEmail(String email) {
|
||||
this.email = email;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(city, email, firstName, id, lastName, phoneNumber, postalCode, state, street);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (!(obj instanceof CustomerShortNames)) {
|
||||
return false;
|
||||
}
|
||||
CustomerShortNames other = (CustomerShortNames) obj;
|
||||
return Objects.equals(city, other.city) && Objects.equals(email, other.email) && Objects.equals(firstName, other.firstName) && id == other.id && Objects.equals(lastName, other.lastName) && Objects.equals(phoneNumber, other.phoneNumber)
|
||||
&& Objects.equals(postalCode, other.postalCode) && Objects.equals(state, other.state) && Objects.equals(street, other.street);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CustomerWithShorterAttributes [id=" + id + ", firstName=" + firstName + ", lastName=" + lastName + ", street=" + street + ", postalCode=" + postalCode + ", city=" + city + ", state=" + state + ", phoneNumber=" + phoneNumber + ", email=" + email
|
||||
+ "]";
|
||||
}
|
||||
|
||||
public static CustomerShortNames[] fromCustomers(Customer[] customers) {
|
||||
CustomerShortNames[] feedback = new CustomerShortNames[customers.length];
|
||||
|
||||
for (int i = 0; i < customers.length; i++) {
|
||||
Customer aCustomer = customers[i];
|
||||
CustomerShortNames newOne = new CustomerShortNames();
|
||||
|
||||
newOne.setId(aCustomer.getId());
|
||||
newOne.setFirstName(aCustomer.getFirstName());
|
||||
newOne.setLastName(aCustomer.getLastName());
|
||||
newOne.setStreet(aCustomer.getStreet());
|
||||
newOne.setCity(aCustomer.getCity());
|
||||
newOne.setPostalCode(aCustomer.getPostalCode());
|
||||
newOne.setState(aCustomer.getState());
|
||||
newOne.setPhoneNumber(aCustomer.getPhoneNumber());
|
||||
newOne.setEmail(aCustomer.getEmail());
|
||||
|
||||
feedback[i] = newOne;
|
||||
}
|
||||
|
||||
return feedback;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
package com.baeldung.jsonoptimization;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
public class CustomerSlim {
|
||||
private long id;
|
||||
private String name;
|
||||
private String address;
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
public void setAddress(String address) {
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(address, id, name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (!(obj instanceof CustomerSlim)) {
|
||||
return false;
|
||||
}
|
||||
CustomerSlim other = (CustomerSlim) obj;
|
||||
return Objects.equals(address, other.address) && id == other.id && Objects.equals(name, other.name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CustomerSlim [id=" + id + ", name=" + name + ", address=" + address + "]";
|
||||
}
|
||||
|
||||
public static CustomerSlim[] fromCustomers(Customer[] customers) {
|
||||
CustomerSlim[] feedback = new CustomerSlim[customers.length];
|
||||
|
||||
for (int i = 0; i < customers.length; i++) {
|
||||
Customer aCustomer = customers[i];
|
||||
CustomerSlim newOne = new CustomerSlim();
|
||||
|
||||
newOne.setId(aCustomer.getId());
|
||||
newOne.setName(aCustomer.getFirstName() + " " + aCustomer.getLastName());
|
||||
newOne.setAddress(aCustomer.getStreet() + ", " + aCustomer.getCity() + " " + aCustomer.getState() + " " + aCustomer.getPostalCode());
|
||||
|
||||
feedback[i] = newOne;
|
||||
}
|
||||
|
||||
return feedback;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.baeldung.jsonoptimization;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.core.ObjectCodec;
|
||||
import com.fasterxml.jackson.databind.DeserializationContext;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
|
||||
|
||||
public class CustomerSlimDeserializer extends StdDeserializer<CustomerSlim> {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public CustomerSlimDeserializer() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
public CustomerSlimDeserializer(Class<CustomerSlim> t) {
|
||||
super(t);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CustomerSlim deserialize(JsonParser parser, DeserializationContext deserializer) throws IOException {
|
||||
CustomerSlim feedback = new CustomerSlim();
|
||||
ObjectCodec codec = parser.getCodec();
|
||||
JsonNode node = codec.readTree(parser);
|
||||
|
||||
feedback.setId(node.get(0)
|
||||
.asLong());
|
||||
feedback.setName(node.get(1)
|
||||
.asText());
|
||||
feedback.setAddress(node.get(2)
|
||||
.asText());
|
||||
|
||||
return feedback;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.baeldung.jsonoptimization;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.databind.SerializerProvider;
|
||||
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
|
||||
|
||||
public class CustomerSlimSerializer extends StdSerializer<CustomerSlim> {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public CustomerSlimSerializer() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
public CustomerSlimSerializer(Class<CustomerSlim> t) {
|
||||
super(t);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serialize(CustomerSlim customer, JsonGenerator jsonGenerator, SerializerProvider serializer) throws IOException {
|
||||
jsonGenerator.writeStartArray();
|
||||
jsonGenerator.writeNumber(customer.getId());
|
||||
jsonGenerator.writeString(customer.getName());
|
||||
jsonGenerator.writeString(customer.getAddress());
|
||||
jsonGenerator.writeEndArray();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
package com.baeldung.jsonoptimization;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
public class CustomerSlimShortNames {
|
||||
|
||||
@JsonProperty("i")
|
||||
private long id;
|
||||
|
||||
@JsonProperty("n")
|
||||
private String name;
|
||||
|
||||
@JsonProperty("a")
|
||||
private String address;
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
public void setAddress(String address) {
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(address, id, name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (!(obj instanceof CustomerSlimShortNames)) {
|
||||
return false;
|
||||
}
|
||||
CustomerSlimShortNames other = (CustomerSlimShortNames) obj;
|
||||
return Objects.equals(address, other.address) && id == other.id && Objects.equals(name, other.name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CustomerSlim [id=" + id + ", name=" + name + ", address=" + address + "]";
|
||||
}
|
||||
|
||||
public static CustomerSlimShortNames[] fromCustomers(Customer[] customers) {
|
||||
CustomerSlimShortNames[] feedback = new CustomerSlimShortNames[customers.length];
|
||||
|
||||
for (int i = 0; i < customers.length; i++) {
|
||||
Customer aCustomer = customers[i];
|
||||
CustomerSlimShortNames newOne = new CustomerSlimShortNames();
|
||||
|
||||
newOne.setId(aCustomer.getId());
|
||||
newOne.setName(aCustomer.getFirstName() + " " + aCustomer.getLastName());
|
||||
newOne.setAddress(aCustomer.getStreet() + ", " + aCustomer.getCity() + " " + aCustomer.getState() + " " + aCustomer.getPostalCode());
|
||||
|
||||
feedback[i] = newOne;
|
||||
}
|
||||
|
||||
return feedback;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package com.baeldung.jsontojavaclass;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
|
||||
import org.jsonschema2pojo.DefaultGenerationConfig;
|
||||
import org.jsonschema2pojo.GenerationConfig;
|
||||
import org.jsonschema2pojo.Jackson2Annotator;
|
||||
import org.jsonschema2pojo.SchemaGenerator;
|
||||
import org.jsonschema2pojo.SchemaMapper;
|
||||
import org.jsonschema2pojo.SchemaStore;
|
||||
import org.jsonschema2pojo.SourceType;
|
||||
import org.jsonschema2pojo.rules.RuleFactory;
|
||||
|
||||
import com.sun.codemodel.JCodeModel;
|
||||
|
||||
public class JsonToJavaClassConversion {
|
||||
|
||||
public static void main(String[] args) {
|
||||
String packageName = "com.baeldung.jsontojavaclass.pojo";
|
||||
String basePath = "src/main/resources";
|
||||
File inputJson = new File(basePath + File.separator + "input.json");
|
||||
File outputPojoDirectory = new File(basePath + File.separator + "convertedPojo");
|
||||
outputPojoDirectory.mkdirs();
|
||||
try {
|
||||
new JsonToJavaClassConversion().convertJsonToJavaClass(inputJson.toURI().toURL(), outputPojoDirectory, packageName, inputJson.getName().replace(".json", ""));
|
||||
} catch (IOException e) {
|
||||
System.out.println("Encountered issue while converting to pojo: " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void convertJsonToJavaClass(URL inputJsonUrl, File outputJavaClassDirectory, String packageName, String javaClassName) throws IOException {
|
||||
JCodeModel jcodeModel = new JCodeModel();
|
||||
|
||||
GenerationConfig config = new DefaultGenerationConfig() {
|
||||
@Override
|
||||
public boolean isGenerateBuilders() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SourceType getSourceType() {
|
||||
return SourceType.JSON;
|
||||
}
|
||||
};
|
||||
|
||||
SchemaMapper mapper = new SchemaMapper(new RuleFactory(config, new Jackson2Annotator(config), new SchemaStore()), new SchemaGenerator());
|
||||
mapper.generate(jcodeModel, javaClassName, packageName, inputJsonUrl);
|
||||
|
||||
jcodeModel.build(outputJavaClassDirectory);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,213 @@
|
||||
|
||||
package com.baeldung.jsontojavaclass.pojo;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.annotation.Generated;
|
||||
import com.fasterxml.jackson.annotation.JsonAnyGetter;
|
||||
import com.fasterxml.jackson.annotation.JsonAnySetter;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
|
||||
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
@JsonPropertyOrder({
|
||||
"name",
|
||||
"area",
|
||||
"author",
|
||||
"id",
|
||||
"salary",
|
||||
"topics"
|
||||
})
|
||||
@Generated("jsonschema2pojo")
|
||||
public class SamplePojo {
|
||||
|
||||
@JsonProperty("name")
|
||||
private String name;
|
||||
@JsonProperty("area")
|
||||
private String area;
|
||||
@JsonProperty("author")
|
||||
private String author;
|
||||
@JsonProperty("id")
|
||||
private Integer id;
|
||||
@JsonProperty("salary")
|
||||
private Integer salary;
|
||||
@JsonProperty("topics")
|
||||
private List<String> topics = new ArrayList<String>();
|
||||
@JsonIgnore
|
||||
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
|
||||
|
||||
@JsonProperty("name")
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@JsonProperty("name")
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public SamplePojo withName(String name) {
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
@JsonProperty("area")
|
||||
public String getArea() {
|
||||
return area;
|
||||
}
|
||||
|
||||
@JsonProperty("area")
|
||||
public void setArea(String area) {
|
||||
this.area = area;
|
||||
}
|
||||
|
||||
public SamplePojo withArea(String area) {
|
||||
this.area = area;
|
||||
return this;
|
||||
}
|
||||
|
||||
@JsonProperty("author")
|
||||
public String getAuthor() {
|
||||
return author;
|
||||
}
|
||||
|
||||
@JsonProperty("author")
|
||||
public void setAuthor(String author) {
|
||||
this.author = author;
|
||||
}
|
||||
|
||||
public SamplePojo withAuthor(String author) {
|
||||
this.author = author;
|
||||
return this;
|
||||
}
|
||||
|
||||
@JsonProperty("id")
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@JsonProperty("id")
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public SamplePojo withId(Integer id) {
|
||||
this.id = id;
|
||||
return this;
|
||||
}
|
||||
|
||||
@JsonProperty("salary")
|
||||
public Integer getSalary() {
|
||||
return salary;
|
||||
}
|
||||
|
||||
@JsonProperty("salary")
|
||||
public void setSalary(Integer salary) {
|
||||
this.salary = salary;
|
||||
}
|
||||
|
||||
public SamplePojo withSalary(Integer salary) {
|
||||
this.salary = salary;
|
||||
return this;
|
||||
}
|
||||
|
||||
@JsonProperty("topics")
|
||||
public List<String> getTopics() {
|
||||
return topics;
|
||||
}
|
||||
|
||||
@JsonProperty("topics")
|
||||
public void setTopics(List<String> topics) {
|
||||
this.topics = topics;
|
||||
}
|
||||
|
||||
public SamplePojo withTopics(List<String> topics) {
|
||||
this.topics = topics;
|
||||
return this;
|
||||
}
|
||||
|
||||
@JsonAnyGetter
|
||||
public Map<String, Object> getAdditionalProperties() {
|
||||
return this.additionalProperties;
|
||||
}
|
||||
|
||||
@JsonAnySetter
|
||||
public void setAdditionalProperty(String name, Object value) {
|
||||
this.additionalProperties.put(name, value);
|
||||
}
|
||||
|
||||
public SamplePojo withAdditionalProperty(String name, Object value) {
|
||||
this.additionalProperties.put(name, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(SamplePojo.class.getName()).append('@').append(Integer.toHexString(System.identityHashCode(this))).append('[');
|
||||
sb.append("name");
|
||||
sb.append('=');
|
||||
sb.append(((this.name == null)?"<null>":this.name));
|
||||
sb.append(',');
|
||||
sb.append("area");
|
||||
sb.append('=');
|
||||
sb.append(((this.area == null)?"<null>":this.area));
|
||||
sb.append(',');
|
||||
sb.append("author");
|
||||
sb.append('=');
|
||||
sb.append(((this.author == null)?"<null>":this.author));
|
||||
sb.append(',');
|
||||
sb.append("id");
|
||||
sb.append('=');
|
||||
sb.append(((this.id == null)?"<null>":this.id));
|
||||
sb.append(',');
|
||||
sb.append("salary");
|
||||
sb.append('=');
|
||||
sb.append(((this.salary == null)?"<null>":this.salary));
|
||||
sb.append(',');
|
||||
sb.append("topics");
|
||||
sb.append('=');
|
||||
sb.append(((this.topics == null)?"<null>":this.topics));
|
||||
sb.append(',');
|
||||
sb.append("additionalProperties");
|
||||
sb.append('=');
|
||||
sb.append(((this.additionalProperties == null)?"<null>":this.additionalProperties));
|
||||
sb.append(',');
|
||||
if (sb.charAt((sb.length()- 1)) == ',') {
|
||||
sb.setCharAt((sb.length()- 1), ']');
|
||||
} else {
|
||||
sb.append(']');
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = 1;
|
||||
result = ((result* 31)+((this.area == null)? 0 :this.area.hashCode()));
|
||||
result = ((result* 31)+((this.author == null)? 0 :this.author.hashCode()));
|
||||
result = ((result* 31)+((this.topics == null)? 0 :this.topics.hashCode()));
|
||||
result = ((result* 31)+((this.name == null)? 0 :this.name.hashCode()));
|
||||
result = ((result* 31)+((this.id == null)? 0 :this.id.hashCode()));
|
||||
result = ((result* 31)+((this.additionalProperties == null)? 0 :this.additionalProperties.hashCode()));
|
||||
result = ((result* 31)+((this.salary == null)? 0 :this.salary.hashCode()));
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if (other == this) {
|
||||
return true;
|
||||
}
|
||||
if ((other instanceof SamplePojo) == false) {
|
||||
return false;
|
||||
}
|
||||
SamplePojo rhs = ((SamplePojo) other);
|
||||
return ((((((((this.area == rhs.area)||((this.area!= null)&&this.area.equals(rhs.area)))&&((this.author == rhs.author)||((this.author!= null)&&this.author.equals(rhs.author))))&&((this.topics == rhs.topics)||((this.topics!= null)&&this.topics.equals(rhs.topics))))&&((this.name == rhs.name)||((this.name!= null)&&this.name.equals(rhs.name))))&&((this.id == rhs.id)||((this.id!= null)&&this.id.equals(rhs.id))))&&((this.additionalProperties == rhs.additionalProperties)||((this.additionalProperties!= null)&&this.additionalProperties.equals(rhs.additionalProperties))))&&((this.salary == rhs.salary)||((this.salary!= null)&&this.salary.equals(rhs.salary))));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.baeldung.jsonvalidation;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import com.google.gson.TypeAdapter;
|
||||
|
||||
public class GsonValidator {
|
||||
|
||||
final TypeAdapter<JsonElement> strictAdapter = new Gson().getAdapter(JsonElement.class);
|
||||
|
||||
public boolean isValid(String json) {
|
||||
try {
|
||||
JsonParser.parseString(json);
|
||||
} catch (JsonSyntaxException e) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isValidStrict(String json) {
|
||||
try {
|
||||
strictAdapter.fromJson(json);
|
||||
} catch (JsonSyntaxException | IOException e) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.baeldung.jsonvalidation;
|
||||
|
||||
import com.fasterxml.jackson.core.JacksonException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
public class JacksonValidator {
|
||||
|
||||
final ObjectMapper mapper = new ObjectMapper();
|
||||
|
||||
public boolean isValid(String json) {
|
||||
try {
|
||||
mapper.readTree(json);
|
||||
} catch (JacksonException e) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.baeldung.jsonvalidation;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
public class JsonValidator {
|
||||
|
||||
public boolean isValidObject(String json) {
|
||||
try {
|
||||
new JSONObject(json);
|
||||
} catch (JSONException e) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isValidJson(String json) {
|
||||
try {
|
||||
new JSONObject(json);
|
||||
} catch (JSONException e) {
|
||||
try {
|
||||
new JSONArray(json);
|
||||
} catch (JSONException ne) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
|
||||
package com.baeldung.jsontojavaclass.pojo;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import javax.annotation.Generated;
|
||||
import com.fasterxml.jackson.annotation.JsonAnyGetter;
|
||||
import com.fasterxml.jackson.annotation.JsonAnySetter;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
|
||||
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
@JsonPropertyOrder({
|
||||
"city",
|
||||
"country"
|
||||
})
|
||||
@Generated("jsonschema2pojo")
|
||||
public class Address {
|
||||
|
||||
@JsonProperty("city")
|
||||
private String city;
|
||||
@JsonProperty("country")
|
||||
private String country;
|
||||
@JsonIgnore
|
||||
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
|
||||
|
||||
@JsonProperty("city")
|
||||
public String getCity() {
|
||||
return city;
|
||||
}
|
||||
|
||||
@JsonProperty("city")
|
||||
public void setCity(String city) {
|
||||
this.city = city;
|
||||
}
|
||||
|
||||
public Address withCity(String city) {
|
||||
this.city = city;
|
||||
return this;
|
||||
}
|
||||
|
||||
@JsonProperty("country")
|
||||
public String getCountry() {
|
||||
return country;
|
||||
}
|
||||
|
||||
@JsonProperty("country")
|
||||
public void setCountry(String country) {
|
||||
this.country = country;
|
||||
}
|
||||
|
||||
public Address withCountry(String country) {
|
||||
this.country = country;
|
||||
return this;
|
||||
}
|
||||
|
||||
@JsonAnyGetter
|
||||
public Map<String, Object> getAdditionalProperties() {
|
||||
return this.additionalProperties;
|
||||
}
|
||||
|
||||
@JsonAnySetter
|
||||
public void setAdditionalProperty(String name, Object value) {
|
||||
this.additionalProperties.put(name, value);
|
||||
}
|
||||
|
||||
public Address withAdditionalProperty(String name, Object value) {
|
||||
this.additionalProperties.put(name, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(Address.class.getName()).append('@').append(Integer.toHexString(System.identityHashCode(this))).append('[');
|
||||
sb.append("city");
|
||||
sb.append('=');
|
||||
sb.append(((this.city == null)?"<null>":this.city));
|
||||
sb.append(',');
|
||||
sb.append("country");
|
||||
sb.append('=');
|
||||
sb.append(((this.country == null)?"<null>":this.country));
|
||||
sb.append(',');
|
||||
sb.append("additionalProperties");
|
||||
sb.append('=');
|
||||
sb.append(((this.additionalProperties == null)?"<null>":this.additionalProperties));
|
||||
sb.append(',');
|
||||
if (sb.charAt((sb.length()- 1)) == ',') {
|
||||
sb.setCharAt((sb.length()- 1), ']');
|
||||
} else {
|
||||
sb.append(']');
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = 1;
|
||||
result = ((result* 31)+((this.country == null)? 0 :this.country.hashCode()));
|
||||
result = ((result* 31)+((this.additionalProperties == null)? 0 :this.additionalProperties.hashCode()));
|
||||
result = ((result* 31)+((this.city == null)? 0 :this.city.hashCode()));
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if (other == this) {
|
||||
return true;
|
||||
}
|
||||
if ((other instanceof Address) == false) {
|
||||
return false;
|
||||
}
|
||||
Address rhs = ((Address) other);
|
||||
return ((((this.country == rhs.country)||((this.country!= null)&&this.country.equals(rhs.country)))&&((this.additionalProperties == rhs.additionalProperties)||((this.additionalProperties!= null)&&this.additionalProperties.equals(rhs.additionalProperties))))&&((this.city == rhs.city)||((this.city!= null)&&this.city.equals(rhs.city))));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,213 @@
|
||||
|
||||
package com.baeldung.jsontojavaclass.pojo;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.annotation.Generated;
|
||||
import com.fasterxml.jackson.annotation.JsonAnyGetter;
|
||||
import com.fasterxml.jackson.annotation.JsonAnySetter;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
|
||||
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
@JsonPropertyOrder({
|
||||
"name",
|
||||
"area",
|
||||
"author",
|
||||
"id",
|
||||
"topics",
|
||||
"address"
|
||||
})
|
||||
@Generated("jsonschema2pojo")
|
||||
public class Input {
|
||||
|
||||
@JsonProperty("name")
|
||||
private String name;
|
||||
@JsonProperty("area")
|
||||
private String area;
|
||||
@JsonProperty("author")
|
||||
private String author;
|
||||
@JsonProperty("id")
|
||||
private Integer id;
|
||||
@JsonProperty("topics")
|
||||
private List<String> topics = new ArrayList<String>();
|
||||
@JsonProperty("address")
|
||||
private Address address;
|
||||
@JsonIgnore
|
||||
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
|
||||
|
||||
@JsonProperty("name")
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@JsonProperty("name")
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Input withName(String name) {
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
@JsonProperty("area")
|
||||
public String getArea() {
|
||||
return area;
|
||||
}
|
||||
|
||||
@JsonProperty("area")
|
||||
public void setArea(String area) {
|
||||
this.area = area;
|
||||
}
|
||||
|
||||
public Input withArea(String area) {
|
||||
this.area = area;
|
||||
return this;
|
||||
}
|
||||
|
||||
@JsonProperty("author")
|
||||
public String getAuthor() {
|
||||
return author;
|
||||
}
|
||||
|
||||
@JsonProperty("author")
|
||||
public void setAuthor(String author) {
|
||||
this.author = author;
|
||||
}
|
||||
|
||||
public Input withAuthor(String author) {
|
||||
this.author = author;
|
||||
return this;
|
||||
}
|
||||
|
||||
@JsonProperty("id")
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@JsonProperty("id")
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Input withId(Integer id) {
|
||||
this.id = id;
|
||||
return this;
|
||||
}
|
||||
|
||||
@JsonProperty("topics")
|
||||
public List<String> getTopics() {
|
||||
return topics;
|
||||
}
|
||||
|
||||
@JsonProperty("topics")
|
||||
public void setTopics(List<String> topics) {
|
||||
this.topics = topics;
|
||||
}
|
||||
|
||||
public Input withTopics(List<String> topics) {
|
||||
this.topics = topics;
|
||||
return this;
|
||||
}
|
||||
|
||||
@JsonProperty("address")
|
||||
public Address getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
@JsonProperty("address")
|
||||
public void setAddress(Address address) {
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
public Input withAddress(Address address) {
|
||||
this.address = address;
|
||||
return this;
|
||||
}
|
||||
|
||||
@JsonAnyGetter
|
||||
public Map<String, Object> getAdditionalProperties() {
|
||||
return this.additionalProperties;
|
||||
}
|
||||
|
||||
@JsonAnySetter
|
||||
public void setAdditionalProperty(String name, Object value) {
|
||||
this.additionalProperties.put(name, value);
|
||||
}
|
||||
|
||||
public Input withAdditionalProperty(String name, Object value) {
|
||||
this.additionalProperties.put(name, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(Input.class.getName()).append('@').append(Integer.toHexString(System.identityHashCode(this))).append('[');
|
||||
sb.append("name");
|
||||
sb.append('=');
|
||||
sb.append(((this.name == null)?"<null>":this.name));
|
||||
sb.append(',');
|
||||
sb.append("area");
|
||||
sb.append('=');
|
||||
sb.append(((this.area == null)?"<null>":this.area));
|
||||
sb.append(',');
|
||||
sb.append("author");
|
||||
sb.append('=');
|
||||
sb.append(((this.author == null)?"<null>":this.author));
|
||||
sb.append(',');
|
||||
sb.append("id");
|
||||
sb.append('=');
|
||||
sb.append(((this.id == null)?"<null>":this.id));
|
||||
sb.append(',');
|
||||
sb.append("topics");
|
||||
sb.append('=');
|
||||
sb.append(((this.topics == null)?"<null>":this.topics));
|
||||
sb.append(',');
|
||||
sb.append("address");
|
||||
sb.append('=');
|
||||
sb.append(((this.address == null)?"<null>":this.address));
|
||||
sb.append(',');
|
||||
sb.append("additionalProperties");
|
||||
sb.append('=');
|
||||
sb.append(((this.additionalProperties == null)?"<null>":this.additionalProperties));
|
||||
sb.append(',');
|
||||
if (sb.charAt((sb.length()- 1)) == ',') {
|
||||
sb.setCharAt((sb.length()- 1), ']');
|
||||
} else {
|
||||
sb.append(']');
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = 1;
|
||||
result = ((result* 31)+((this.area == null)? 0 :this.area.hashCode()));
|
||||
result = ((result* 31)+((this.address == null)? 0 :this.address.hashCode()));
|
||||
result = ((result* 31)+((this.author == null)? 0 :this.author.hashCode()));
|
||||
result = ((result* 31)+((this.topics == null)? 0 :this.topics.hashCode()));
|
||||
result = ((result* 31)+((this.name == null)? 0 :this.name.hashCode()));
|
||||
result = ((result* 31)+((this.id == null)? 0 :this.id.hashCode()));
|
||||
result = ((result* 31)+((this.additionalProperties == null)? 0 :this.additionalProperties.hashCode()));
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if (other == this) {
|
||||
return true;
|
||||
}
|
||||
if ((other instanceof Input) == false) {
|
||||
return false;
|
||||
}
|
||||
Input rhs = ((Input) other);
|
||||
return ((((((((this.area == rhs.area)||((this.area!= null)&&this.area.equals(rhs.area)))&&((this.address == rhs.address)||((this.address!= null)&&this.address.equals(rhs.address))))&&((this.author == rhs.author)||((this.author!= null)&&this.author.equals(rhs.author))))&&((this.topics == rhs.topics)||((this.topics!= null)&&this.topics.equals(rhs.topics))))&&((this.name == rhs.name)||((this.name!= null)&&this.name.equals(rhs.name))))&&((this.id == rhs.id)||((this.id!= null)&&this.id.equals(rhs.id))))&&((this.additionalProperties == rhs.additionalProperties)||((this.additionalProperties!= null)&&this.additionalProperties.equals(rhs.additionalProperties))));
|
||||
}
|
||||
|
||||
}
|
||||
16
json-modules/json-2/src/main/resources/input.json
Normal file
16
json-modules/json-2/src/main/resources/input.json
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"name": "Baeldung",
|
||||
"area": "tech blogs",
|
||||
"author": "Eugen",
|
||||
"id": 32134,
|
||||
"topics": [
|
||||
"java",
|
||||
"kotlin",
|
||||
"cs",
|
||||
"linux"
|
||||
],
|
||||
"address": {
|
||||
"city": "Bucharest",
|
||||
"country": "Romania"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
package com.baeldung.fastjson;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.alibaba.fastjson.serializer.BeanContext;
|
||||
import com.alibaba.fastjson.serializer.ContextValueFilter;
|
||||
import com.alibaba.fastjson.serializer.NameFilter;
|
||||
import com.alibaba.fastjson.serializer.SerializeConfig;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class FastJsonUnitTest {
|
||||
private List<Person> listOfPersons;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
listOfPersons = new ArrayList<Person>();
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.set(2016, 6, 24);
|
||||
listOfPersons.add(new Person(15, "John", "Doe", calendar.getTime()));
|
||||
listOfPersons.add(new Person(20, "Janette", "Doe", calendar.getTime()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenJavaList_thanConvertToJsonCorrect() {
|
||||
String personJsonFormat = JSON.toJSONString(listOfPersons);
|
||||
assertEquals(personJsonFormat, "[{\"FIRST NAME\":\"Doe\",\"LAST NAME\":\"John\",\"DATE OF BIRTH\":" + "\"24/07/2016\"},{\"FIRST NAME\":\"Doe\",\"LAST NAME\":\"Janette\",\"DATE OF BIRTH\":" + "\"24/07/2016\"}]");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenJson_thanConvertToObjectCorrect() {
|
||||
String personJsonFormat = JSON.toJSONString(listOfPersons.get(0));
|
||||
Person newPerson = JSON.parseObject(personJsonFormat, Person.class);
|
||||
assertEquals(newPerson.getAge(), 0); // serialize is set to false for age attribute
|
||||
assertEquals(newPerson.getFirstName(), listOfPersons.get(0)
|
||||
.getFirstName());
|
||||
assertEquals(newPerson.getLastName(), listOfPersons.get(0)
|
||||
.getLastName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenGenerateJson_thanGenerationCorrect() throws ParseException {
|
||||
JSONArray jsonArray = new JSONArray();
|
||||
for (int i = 0; i < 2; i++) {
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("FIRST NAME", "John" + i);
|
||||
jsonObject.put("LAST NAME", "Doe" + i);
|
||||
jsonObject.put("DATE OF BIRTH", "2016/12/12 12:12:12");
|
||||
jsonArray.add(jsonObject);
|
||||
}
|
||||
assertEquals(jsonArray.toString(), "[{\"LAST NAME\":\"Doe0\",\"DATE OF BIRTH\":" + "\"2016/12/12 12:12:12\",\"FIRST NAME\":\"John0\"},{\"LAST NAME\":\"Doe1\"," + "\"DATE OF BIRTH\":\"2016/12/12 12:12:12\",\"FIRST NAME\":\"John1\"}]");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenContextFilter_whenJavaObject_thanJsonCorrect() {
|
||||
ContextValueFilter valueFilter = new ContextValueFilter() {
|
||||
public Object process(BeanContext context, Object object, String name, Object value) {
|
||||
if (name.equals("DATE OF BIRTH")) {
|
||||
return "NOT TO DISCLOSE";
|
||||
}
|
||||
if (value.equals("John") || value.equals("Doe")) {
|
||||
return ((String) value).toUpperCase();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
};
|
||||
JSON.toJSONString(listOfPersons, valueFilter);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenSerializeConfig_whenJavaObject_thanJsonCorrect() {
|
||||
NameFilter formatName = new NameFilter() {
|
||||
public String process(Object object, String name, Object value) {
|
||||
return name.toLowerCase()
|
||||
.replace(" ", "_");
|
||||
}
|
||||
};
|
||||
SerializeConfig.getGlobalInstance()
|
||||
.addFilter(Person.class, formatName);
|
||||
String jsonOutput = JSON.toJSONStringWithDateFormat(listOfPersons, "yyyy-MM-dd");
|
||||
assertEquals(jsonOutput, "[{\"first_name\":\"Doe\",\"last_name\":\"John\"," + "\"date_of_birth\":\"2016-07-24\"},{\"first_name\":\"Doe\",\"last_name\":" + "\"Janette\",\"date_of_birth\":\"2016-07-24\"}]");
|
||||
// resetting custom serializer
|
||||
SerializeConfig.getGlobalInstance()
|
||||
.put(Person.class, null);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
package com.baeldung.fastjson;
|
||||
|
||||
import com.alibaba.fastjson.annotation.JSONField;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
public class Person {
|
||||
|
||||
@JSONField(name = "AGE", serialize = false, deserialize = false)
|
||||
private int age;
|
||||
|
||||
@JSONField(name = "LAST NAME", ordinal = 2)
|
||||
private String lastName;
|
||||
|
||||
@JSONField(name = "FIRST NAME", ordinal = 1)
|
||||
private String firstName;
|
||||
|
||||
@JSONField(name = "DATE OF BIRTH", format = "dd/MM/yyyy", ordinal = 3)
|
||||
private Date dateOfBirth;
|
||||
|
||||
public Person() {
|
||||
|
||||
}
|
||||
|
||||
public Person(int age, String lastName, String firstName, Date dateOfBirth) {
|
||||
super();
|
||||
this.age = age;
|
||||
this.lastName = lastName;
|
||||
this.firstName = firstName;
|
||||
this.dateOfBirth = dateOfBirth;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Person [age=" + age + ", lastName=" + lastName + ", firstName=" + firstName + ", dateOfBirth=" + dateOfBirth + "]";
|
||||
}
|
||||
|
||||
public int getAge() {
|
||||
return age;
|
||||
}
|
||||
|
||||
public void setAge(int age) {
|
||||
this.age = age;
|
||||
}
|
||||
|
||||
public String getLastName() {
|
||||
return lastName;
|
||||
}
|
||||
|
||||
public void setLastName(String lastName) {
|
||||
this.lastName = lastName;
|
||||
}
|
||||
|
||||
public String getFirstName() {
|
||||
return firstName;
|
||||
}
|
||||
|
||||
public void setFirstName(String firstName) {
|
||||
this.firstName = firstName;
|
||||
}
|
||||
|
||||
public Date getDateOfBirth() {
|
||||
return dateOfBirth;
|
||||
}
|
||||
|
||||
public void setDateOfBirth(Date dateOfBirth) {
|
||||
this.dateOfBirth = dateOfBirth;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
package com.baeldung.jsoniter;
|
||||
|
||||
import com.baeldung.jsoniter.model.Name;
|
||||
import com.baeldung.jsoniter.model.Student;
|
||||
import com.jsoniter.JsonIterator;
|
||||
import com.jsoniter.ValueType;
|
||||
import com.jsoniter.any.Any;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static com.jsoniter.ValueType.STRING;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class JsoniterIntroUnitTest {
|
||||
|
||||
@Test
|
||||
public void whenParsedUsingBindAPI_thenConvertedToJavaObjectCorrectly() {
|
||||
String input = "{\"id\":1,\"name\":{\"firstName\":\"Joe\",\"surname\":\"Blogg\"}}";
|
||||
|
||||
Student student = JsonIterator.deserialize(input, Student.class);
|
||||
|
||||
assertThat(student.getId()).isEqualTo(1);
|
||||
assertThat(student.getName().getFirstName()).isEqualTo("Joe");
|
||||
assertThat(student.getName().getSurname()).isEqualTo("Blogg");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenTypeInJsonFuzzy_whenFieldIsMaybeDecoded_thenFieldParsedCorrectly() {
|
||||
String input = "{\"id\":\"1\",\"name\":{\"firstName\":\"Joe\",\"surname\":\"Blogg\"}}";
|
||||
|
||||
Student student = JsonIterator.deserialize(input, Student.class);
|
||||
|
||||
assertThat(student.getId()).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenParsedUsingAnyAPI_thenFieldValueCanBeExtractedUsingTheFieldName() {
|
||||
String input = "{\"id\":1,\"name\":{\"firstName\":\"Joe\",\"surname\":\"Blogg\"}}";
|
||||
|
||||
Any any = JsonIterator.deserialize(input);
|
||||
|
||||
assertThat(any.toInt("id")).isEqualTo(1);
|
||||
assertThat(any.toString("name", "firstName")).isEqualTo("Joe");
|
||||
assertThat(any.toString("name", "surname")).isEqualTo("Blogg");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenParsedUsingAnyAPI_thenFieldValueTypeIsCorrect() {
|
||||
String input = "{\"id\":1,\"name\":{\"firstName\":\"Joe\",\"surname\":\"Blogg\"}}";
|
||||
|
||||
Any any = JsonIterator.deserialize(input);
|
||||
|
||||
assertThat(any.get("id").valueType()).isEqualTo(ValueType.NUMBER);
|
||||
assertThat(any.get("name").valueType()).isEqualTo(ValueType.OBJECT);
|
||||
assertThat(any.get("error").valueType()).isEqualTo(ValueType.INVALID);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenParsedUsingIteratorAPI_thenFieldValuesExtractedCorrectly() throws Exception {
|
||||
Name name = new Name();
|
||||
String input = "{ \"firstName\" : \"Joe\", \"surname\" : \"Blogg\" }";
|
||||
JsonIterator iterator = JsonIterator.parse(input);
|
||||
|
||||
for (String field = iterator.readObject(); field != null; field = iterator.readObject()) {
|
||||
switch (field) {
|
||||
case "firstName":
|
||||
if (iterator.whatIsNext() == ValueType.STRING) {
|
||||
name.setFirstName(iterator.readString());
|
||||
}
|
||||
continue;
|
||||
case "surname":
|
||||
if (iterator.whatIsNext() == ValueType.STRING) {
|
||||
name.setSurname(iterator.readString());
|
||||
}
|
||||
continue;
|
||||
default:
|
||||
iterator.skip();
|
||||
}
|
||||
}
|
||||
|
||||
assertThat(name.getFirstName()).isEqualTo("Joe");
|
||||
assertThat(name.getSurname()).isEqualTo("Blogg");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package com.baeldung.jsonld.deserialization.jsonldjava.jackson;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import com.baeldung.jsonld.deserialization.jsonldjava.jackson.Person.Link;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.github.jsonldjava.core.JsonLdOptions;
|
||||
import com.github.jsonldjava.core.JsonLdProcessor;
|
||||
import com.github.jsonldjava.utils.JsonUtils;
|
||||
|
||||
public class JacksonDeserializationUnitTest {
|
||||
|
||||
@Test
|
||||
void givenAJsonLdObject_whenCompactIsUsedWithEmptyContext_thenItCanBeDeserializedWithJackson() throws IOException {
|
||||
String inputJsonLd = "{"
|
||||
+ "\"@context\":{"
|
||||
+ "\"@vocab\":\"http://schema.org/\","
|
||||
+ "\"knows\":{\"@type\":\"@id\"}"
|
||||
+ "},"
|
||||
+ "\"@type\":\"Person\","
|
||||
+ "\"@id\":\"http://example.com/person/1234\","
|
||||
+ "\"name\":\"Example Name\","
|
||||
+ "\"knows\":\"http://example.com/person/2345\""
|
||||
+ "}";
|
||||
|
||||
Object jsonObject = JsonUtils.fromString(inputJsonLd);
|
||||
Object compact = JsonLdProcessor.compact(jsonObject, new HashMap<>(), new JsonLdOptions());
|
||||
String compactContent = JsonUtils.toString(compact);
|
||||
|
||||
assertEquals("{"
|
||||
+ "\"@id\":\"http://example.com/person/1234\","
|
||||
+ "\"@type\":\"http://schema.org/Person\","
|
||||
+ "\"http://schema.org/knows\":{\"@id\":\"http://example.com/person/2345\"},"
|
||||
+ "\"http://schema.org/name\":\"Example Name\""
|
||||
+ "}", compactContent);
|
||||
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
Person person = objectMapper.readValue(compactContent, Person.class);
|
||||
|
||||
Person expectedPerson = new Person("http://example.com/person/1234", "Example Name", new Link("http://example.com/person/2345"));
|
||||
|
||||
assertEquals(expectedPerson.getId(), person.getId());
|
||||
assertEquals(expectedPerson.getName(), person.getName());
|
||||
assertEquals(expectedPerson.getKnows().getId(), person.getKnows().getId());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
package com.baeldung.jsonld.deserialization.jsonldjava.jackson;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class Person {
|
||||
@JsonProperty("@id")
|
||||
private String id;
|
||||
@JsonProperty("http://schema.org/name")
|
||||
private String name;
|
||||
@JsonProperty("http://schema.org/knows")
|
||||
private Link knows;
|
||||
|
||||
public Person() {
|
||||
}
|
||||
|
||||
public Person(String id, String name, Link knows) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.knows = knows;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Link getKnows() {
|
||||
return knows;
|
||||
}
|
||||
|
||||
public void setKnows(Link knows) {
|
||||
this.knows = knows;
|
||||
}
|
||||
|
||||
public static class Link {
|
||||
@JsonProperty("@id")
|
||||
private String id;
|
||||
|
||||
public Link() {
|
||||
}
|
||||
|
||||
public Link(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
package com.baeldung.jsonld.serialization.hydrajsonld;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.BeanDescription;
|
||||
import com.fasterxml.jackson.databind.JsonSerializer;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.SerializationConfig;
|
||||
import com.fasterxml.jackson.databind.module.SimpleModule;
|
||||
import com.fasterxml.jackson.databind.ser.BeanSerializerModifier;
|
||||
import com.fasterxml.jackson.databind.ser.std.BeanSerializerBase;
|
||||
|
||||
import de.escalon.hypermedia.hydra.serialize.JacksonHydraSerializer;
|
||||
|
||||
public class HydraJsonldSerializationUnitTest {
|
||||
@Test
|
||||
void givenAHydraJsonldAnnotatedObject_whenJacksonHydraSerializerIsUsed_thenAJsonLdDocumentIsGenerated() throws JsonProcessingException {
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
objectMapper.registerModule(getJacksonHydraSerializerModule());
|
||||
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
|
||||
|
||||
Person person = new Person("http://example.com/person/1234", "Example Name");
|
||||
|
||||
String personJsonLd = objectMapper.writeValueAsString(person);
|
||||
|
||||
assertEquals("{"
|
||||
+ "\"@context\":{"
|
||||
+ "\"@vocab\":\"http://example.com/vocab/\","
|
||||
+ "\"name\":\"fullName\""
|
||||
+ "},"
|
||||
+ "\"@type\":\"person\","
|
||||
+ "\"name\":\"Example Name\","
|
||||
+ "\"@id\":\"http://example.com/person/1234\""
|
||||
+ "}", personJsonLd);
|
||||
}
|
||||
|
||||
static SimpleModule getJacksonHydraSerializerModule() {
|
||||
return new SimpleModule() {
|
||||
|
||||
@Override
|
||||
public void setupModule(SetupContext context) {
|
||||
super.setupModule(context);
|
||||
|
||||
context.addBeanSerializerModifier(new BeanSerializerModifier() {
|
||||
|
||||
@Override
|
||||
public JsonSerializer<?> modifySerializer(SerializationConfig config, BeanDescription beanDesc, JsonSerializer<?> serializer) {
|
||||
|
||||
if (serializer instanceof BeanSerializerBase) {
|
||||
return new JacksonHydraSerializer((BeanSerializerBase) serializer);
|
||||
} else {
|
||||
return serializer;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.baeldung.jsonld.serialization.hydrajsonld;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
import de.escalon.hypermedia.hydra.mapping.Expose;
|
||||
import de.escalon.hypermedia.hydra.mapping.Vocab;
|
||||
|
||||
@Vocab("http://example.com/vocab/")
|
||||
@Expose("person")
|
||||
public class Person {
|
||||
private String id;
|
||||
private String name;
|
||||
|
||||
public Person(String id, String name) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@JsonProperty("@id")
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Expose("fullName")
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.baeldung.jsonld.serialization.jacksonjsonld;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
import ioinformarics.oss.jackson.module.jsonld.JsonldModule;
|
||||
|
||||
public class JacksonJsonLdSerializationUnitTest {
|
||||
@Test
|
||||
void givenAJacksonJsonldAnnotatedObject_whenJsonldModuleIsUsed_thenAJsonLdDocumentIsGenerated() throws JsonProcessingException {
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
objectMapper.registerModule(new JsonldModule());
|
||||
|
||||
Person person = new Person("http://example.com/person/1234", "Example Name");
|
||||
String personJsonLd = objectMapper.writeValueAsString(person);
|
||||
|
||||
assertEquals("{"
|
||||
+ "\"@type\":\"s:Person\","
|
||||
+ "\"@context\":{"
|
||||
+ "\"s\":\"http://schema.org/\","
|
||||
+ "\"name\":\"s:name\","
|
||||
+ "\"knows\":{\"@id\":\"s:knows\",\"@type\":\"@id\"}"
|
||||
+ "},"
|
||||
+ "\"name\":\"Example Name\","
|
||||
+ "\"@id\":\"http://example.com/person/1234\","
|
||||
+ "\"knows\":\"http://example.com/person/2345\""
|
||||
+ "}", personJsonLd);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.baeldung.jsonld.serialization.jacksonjsonld;
|
||||
|
||||
import ioinformarics.oss.jackson.module.jsonld.annotation.JsonldId;
|
||||
import ioinformarics.oss.jackson.module.jsonld.annotation.JsonldLink;
|
||||
import ioinformarics.oss.jackson.module.jsonld.annotation.JsonldNamespace;
|
||||
import ioinformarics.oss.jackson.module.jsonld.annotation.JsonldProperty;
|
||||
import ioinformarics.oss.jackson.module.jsonld.annotation.JsonldResource;
|
||||
import ioinformarics.oss.jackson.module.jsonld.annotation.JsonldType;
|
||||
|
||||
@JsonldResource
|
||||
@JsonldNamespace(name = "s", uri = "http://schema.org/")
|
||||
@JsonldType("s:Person")
|
||||
@JsonldLink(rel = "s:knows", name = "knows", href = "http://example.com/person/2345")
|
||||
public class Person {
|
||||
@JsonldId
|
||||
private String id;
|
||||
@JsonldProperty("s:name")
|
||||
private String name;
|
||||
|
||||
public Person(String id, String name) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,180 @@
|
||||
package com.baeldung.jsonoptimization;
|
||||
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude.Include;
|
||||
import com.fasterxml.jackson.core.Version;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.ObjectWriter;
|
||||
import com.fasterxml.jackson.databind.module.SimpleModule;
|
||||
|
||||
class JsonOptimizationUnitTest {
|
||||
private static final String TEST_LABEL_JACKSON_DEFAULT_OPTIONS = "Default JSON";
|
||||
private static final String TEST_LABEL_DEFAULT_JSON_NO_NULL = "Default JSON without null";
|
||||
private static final String TEST_LABEL_SHORTER_FIELD_NAMES = "Shorter field names";
|
||||
private static final String TEST_LABEL_SHORTER_FIELD_NAMES_AND_NO_NULL = "Shorter field names without null";
|
||||
private static final String TEST_LABEL_SERIALIZING_TO_ARRAY = "Custom serializer";
|
||||
private static final String TEST_LABEL_SLIM_CUSTOM_SERIALIZER = "Slim custom serializer";
|
||||
private static final String TEST_LABEL_SLIM_CUSTOMER = "Slim customer";
|
||||
private static final String TEST_LABEL_SLIM_CUSTOMER_SHORT_NAMES = "Slim customer with shorter field names";
|
||||
private static DecimalFormat LENGTH_FORMATTER = new DecimalFormat("###,###.0");
|
||||
private static DecimalFormat PERCENT_FORMATTER = new DecimalFormat("###.0");
|
||||
private static Customer[] customers;
|
||||
private ObjectMapper mapper;
|
||||
private static int defaultJsonLength;
|
||||
|
||||
@BeforeAll
|
||||
static void setUpOnce() throws Exception {
|
||||
customers = Customer.fromMockFile();
|
||||
ObjectMapper oneTimeMapper = new ObjectMapper();
|
||||
byte[] feedback = oneTimeMapper.writeValueAsBytes(customers);
|
||||
defaultJsonLength = feedback.length;
|
||||
System.out.println();
|
||||
System.out.println("Default JSON length: " + defaultJsonLength);
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
mapper = new ObjectMapper();
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenSetUp_ThenOneThousandCustomers() {
|
||||
assertEquals(1000, customers.length, "There should be a 1000 customers");
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenJacksonDefaultOptions_thenValid() throws IOException {
|
||||
printBanner(TEST_LABEL_JACKSON_DEFAULT_OPTIONS);
|
||||
byte[] plainJson = createJsonAndVerify(TEST_LABEL_JACKSON_DEFAULT_OPTIONS, customers);
|
||||
compressJson(TEST_LABEL_JACKSON_DEFAULT_OPTIONS, plainJson);
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenExcludingNull_thenValid() throws IOException {
|
||||
printBanner(TEST_LABEL_DEFAULT_JSON_NO_NULL);
|
||||
mapper.setSerializationInclusion(Include.NON_NULL);
|
||||
byte[] plainJson = createJsonAndVerify(TEST_LABEL_DEFAULT_JSON_NO_NULL, customers);
|
||||
compressJson(TEST_LABEL_DEFAULT_JSON_NO_NULL, plainJson);
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenShorterFieldNames_thenValid() throws IOException {
|
||||
printBanner(TEST_LABEL_SHORTER_FIELD_NAMES);
|
||||
CustomerShortNames[] shorterOnes = CustomerShortNames.fromCustomers(customers);
|
||||
byte[] shorterJson = createJsonAndVerify(TEST_LABEL_SHORTER_FIELD_NAMES, shorterOnes);
|
||||
compressJson(TEST_LABEL_SHORTER_FIELD_NAMES, shorterJson);
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenShorterFieldNamesAndExcludingNull_thenValid() throws IOException {
|
||||
printBanner(TEST_LABEL_SHORTER_FIELD_NAMES_AND_NO_NULL);
|
||||
CustomerShortNames[] shorterOnes = CustomerShortNames.fromCustomers(customers);
|
||||
mapper.setSerializationInclusion(Include.NON_NULL);
|
||||
byte[] shorterJson = createJsonAndVerify(TEST_LABEL_SHORTER_FIELD_NAMES_AND_NO_NULL, shorterOnes);
|
||||
compressJson(TEST_LABEL_SHORTER_FIELD_NAMES_AND_NO_NULL, shorterJson);
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenSlimCustomer_thenValid() throws IOException {
|
||||
printBanner(TEST_LABEL_SLIM_CUSTOMER);
|
||||
CustomerSlim[] slimOnes = CustomerSlim.fromCustomers(customers);
|
||||
byte[] slimJson = createJsonAndVerify(TEST_LABEL_SLIM_CUSTOMER, slimOnes);
|
||||
compressJson(TEST_LABEL_SLIM_CUSTOMER, slimJson);
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenSlimCustomerAndShorterFieldNames_thenValid() throws IOException {
|
||||
printBanner(TEST_LABEL_SLIM_CUSTOMER_SHORT_NAMES);
|
||||
CustomerSlimShortNames[] slimOnes = CustomerSlimShortNames.fromCustomers(customers);
|
||||
byte[] slimJson = createJsonAndVerify(TEST_LABEL_SLIM_CUSTOMER_SHORT_NAMES, slimOnes);
|
||||
compressJson(TEST_LABEL_SLIM_CUSTOMER_SHORT_NAMES, slimJson);
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenSerializingToArray_thenValid() throws IOException {
|
||||
printBanner(TEST_LABEL_SERIALIZING_TO_ARRAY);
|
||||
SimpleModule serializer = new SimpleModule("CustomDeSerializer", new Version(1, 0, 0, null, null, null));
|
||||
serializer.addSerializer(Customer.class, new CustomerSerializer());
|
||||
serializer.addDeserializer(Customer.class, new CustomerDeserializer());
|
||||
mapper.registerModule(serializer);
|
||||
|
||||
byte[] plainJson = createJsonAndVerify(TEST_LABEL_SERIALIZING_TO_ARRAY, customers);
|
||||
compressJson(TEST_LABEL_SERIALIZING_TO_ARRAY, plainJson);
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenSerializingToArrayAndSlimCustomer_thenValid() throws IOException {
|
||||
printBanner(TEST_LABEL_SLIM_CUSTOM_SERIALIZER);
|
||||
SimpleModule serializer = new SimpleModule("SlimCustomDeSerializer", new Version(1, 0, 0, null, null, null));
|
||||
serializer.addSerializer(CustomerSlim.class, new CustomerSlimSerializer());
|
||||
serializer.addDeserializer(CustomerSlim.class, new CustomerSlimDeserializer());
|
||||
mapper.registerModule(serializer);
|
||||
|
||||
CustomerSlim[] slimOnes = CustomerSlim.fromCustomers(customers);
|
||||
byte[] plainJson = createJsonAndVerify(TEST_LABEL_SLIM_CUSTOM_SERIALIZER, slimOnes);
|
||||
compressJson(TEST_LABEL_SLIM_CUSTOM_SERIALIZER, plainJson);
|
||||
}
|
||||
|
||||
private void printBanner(String name) {
|
||||
System.out.println();
|
||||
System.out.println("************************************************");
|
||||
System.out.println("Testing " + name);
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
void compressJson(String label, byte[] plainJson) throws IOException {
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
GZIPOutputStream gzipStream = new GZIPOutputStream(outputStream);
|
||||
gzipStream.write(plainJson);
|
||||
gzipStream.close();
|
||||
outputStream.close();
|
||||
byte[] gzippedJson = outputStream.toByteArray();
|
||||
double length = gzippedJson.length / 1024d;
|
||||
double percent = gzippedJson.length * 100d / defaultJsonLength;
|
||||
System.out.println(label + " GZIPped length: " + LENGTH_FORMATTER.format(length)
|
||||
+ "kB (" + PERCENT_FORMATTER.format(percent) + "%)");
|
||||
assertTrue(plainJson.length > gzippedJson.length, label + " should be longer than GZIPped data");
|
||||
}
|
||||
|
||||
private byte[] createJsonAndVerify(String label, Object[] customers) throws IOException {
|
||||
System.out.println(label + " sample: ");
|
||||
ObjectWriter prettyWritter = mapper.writerWithDefaultPrettyPrinter();
|
||||
System.out.println(prettyWritter.writeValueAsString(customers[0]));
|
||||
|
||||
byte[] feedback = mapper.writeValueAsBytes(customers);
|
||||
double length = feedback.length / 1024d;
|
||||
double percent = feedback.length * 100d / defaultJsonLength;
|
||||
System.out.println(label + " length: " + LENGTH_FORMATTER.format(length)
|
||||
+ "kB (" + PERCENT_FORMATTER.format(percent) + "%)");
|
||||
assertTrue(feedback.length > 1, label + " should be there");
|
||||
|
||||
String prefix = label.replaceAll(" ", "-")
|
||||
.toLowerCase();
|
||||
File tempFile = File.createTempFile("jon-optimization-" + prefix, ".json");
|
||||
FileOutputStream fos = new FileOutputStream(tempFile);
|
||||
fos.write(feedback);
|
||||
fos.close();
|
||||
System.out.println(label + " file: " + tempFile.toString());
|
||||
|
||||
Object[] restoredOnes = mapper.readValue(feedback, customers.getClass());
|
||||
assertArrayEquals(TEST_LABEL_JACKSON_DEFAULT_OPTIONS + ": restoring from JSON should work", customers, restoredOnes);
|
||||
|
||||
return feedback;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.baeldung.jsontojavaclass;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
class JsonToJavaClassConversionUnitTest {
|
||||
|
||||
private JsonToJavaClassConversion jsonToJavaConversion = new JsonToJavaClassConversion();
|
||||
|
||||
@Test
|
||||
void whenProvideInputJSON_thenGenerateJavaClass() throws MalformedURLException, IOException {
|
||||
|
||||
String packageName = "com.baeldung.jsontojavaclass.pojo";
|
||||
|
||||
// load input JSON file
|
||||
String jsonPath = "src/test/resources/";
|
||||
File inputJson = new File(jsonPath + "sample_input.json");
|
||||
|
||||
// create the local directory for generating the Java Class file
|
||||
String outputPath = "src/test/resources/";
|
||||
File outputJavaClassDirectory = new File(outputPath);
|
||||
|
||||
String javaClassName = "SamplePojo";
|
||||
|
||||
jsonToJavaConversion.convertJsonToJavaClass(inputJson.toURI()
|
||||
.toURL(), outputJavaClassDirectory, packageName, javaClassName);
|
||||
|
||||
File outputJavaClassPath = new File(outputPath + packageName.replace(".", "/"));
|
||||
Assertions.assertTrue(Arrays.stream(outputJavaClassPath.listFiles()).peek(System.out::println).anyMatch(file -> (javaClassName+".java").equalsIgnoreCase(file.getName())));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.baeldung.jsonvalidation;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class GsonValidatorUnitTest {
|
||||
|
||||
private final GsonValidator validator = new GsonValidator();
|
||||
|
||||
@Test
|
||||
public void givenValidObjectJson_whenValidatingNonStrict_thenValid() {
|
||||
String json = "{\"email\": \"example@com\", \"name\": \"John\"}";
|
||||
assertTrue(validator.isValid(json));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenValidArrayJson_whenValidatingNonStrict_thenValid() {
|
||||
String json = "[{\"email\": \"example@com\", \"name\": \"John\"},{\"email\": \"example1@com\", \"name\": \"Bob\"}]";
|
||||
assertTrue(validator.isValid(json));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenInvalidJson_whenValidatingNonStrict_thenValid() {
|
||||
String json = "Invalid_Json";
|
||||
assertTrue(validator.isValid(json));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenInvalidJson_whenValidatingStrict_thenInvalid() {
|
||||
String json = "Invalid_Json";
|
||||
assertFalse(validator.isValidStrict(json));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.baeldung.jsonvalidation;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class JacksonValidatorUnitTest {
|
||||
|
||||
private final JacksonValidator validator = new JacksonValidator();
|
||||
|
||||
@Test
|
||||
public void givenValidObjectJson_whenValidating_thenValid() {
|
||||
String json = "{\"email\": \"example@com\", \"name\": \"John\"}";
|
||||
assertTrue(validator.isValid(json));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenValidArrayJson_whenValidating_thenValid() {
|
||||
String json = "[{\"email\": \"example@com\", \"name\": \"John\"},{\"email\": \"example1@com\", \"name\": \"Bob\"}]";
|
||||
assertTrue(validator.isValid(json));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenInvalidJson_whenValidating_thenInvalid() {
|
||||
String json = "Invalid_Json";
|
||||
assertFalse(validator.isValid(json));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.baeldung.jsonvalidation;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class JsonValidatorUnitTest {
|
||||
|
||||
private final JsonValidator validator = new JsonValidator();
|
||||
|
||||
@Test
|
||||
public void givenValidObjectJson_whenValidatingObject_thenValid() {
|
||||
String json = "{\"email\": \"example@com\", \"name\": \"John\"}";
|
||||
assertTrue(validator.isValidObject(json));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenInvalidJson_whenValidating_thenInvalid() {
|
||||
String json = "Invalid_Json";
|
||||
assertFalse(validator.isValidObject(json));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenValidArrayJson_whenValidatingObject_thenInvalid() {
|
||||
String json = "[{\"email\": \"example@com\", \"name\": \"John\"},{\"email\": \"example1@com\", \"name\": \"Bob\"}]";
|
||||
assertFalse(validator.isValidObject(json));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenValidJson_whenValidatingJson_thenValid() {
|
||||
String json = "[{\"email\": \"example@com\", \"name\": \"John\"},{\"email\": \"example1@com\", \"name\": \"Bob\"}]";
|
||||
assertTrue(validator.isValidJson(json));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
package com.baeldung.moshi;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import java.time.Instant;
|
||||
|
||||
import com.squareup.moshi.FromJson;
|
||||
import com.squareup.moshi.JsonAdapter;
|
||||
import com.squareup.moshi.JsonQualifier;
|
||||
import com.squareup.moshi.Moshi;
|
||||
import com.squareup.moshi.ToJson;
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
import org.junit.Test;
|
||||
|
||||
public class AlternativeAdapterUnitTest {
|
||||
@Test
|
||||
public void whenSerializing_thenAlternativeAdapterUsed() {
|
||||
Moshi moshi = new Moshi.Builder()
|
||||
.add(new EpochMillisAdapter())
|
||||
.build();
|
||||
JsonAdapter<Post> jsonAdapter = moshi.adapter(Post.class);
|
||||
|
||||
String json = jsonAdapter.toJson(new Post("Introduction to Moshi Json", "Baeldung", Instant.now()));
|
||||
System.out.println(json);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenDeserializing_thenAlternativeAdapterUsed() throws IOException {
|
||||
Moshi moshi = new Moshi.Builder()
|
||||
.add(new EpochMillisAdapter())
|
||||
.build();
|
||||
JsonAdapter<Post> jsonAdapter = moshi.adapter(Post.class);
|
||||
|
||||
String json = "{\"author\":\"Baeldung\",\"posted\":1582095269204,\"title\":\"Introduction to Moshi Json\"}";
|
||||
Post post = jsonAdapter.fromJson(json);
|
||||
System.out.println(post);
|
||||
|
||||
}
|
||||
|
||||
public static class Post {
|
||||
String title;
|
||||
String author;
|
||||
@EpochMillis Instant posted;
|
||||
|
||||
public Post() {
|
||||
}
|
||||
|
||||
public Post(String title, String author, Instant posted) {
|
||||
this.title = title;
|
||||
this.author = author;
|
||||
this.posted = posted;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public String getAuthor() {
|
||||
return author;
|
||||
}
|
||||
|
||||
public void setAuthor(String author) {
|
||||
this.author = author;
|
||||
}
|
||||
|
||||
public Instant getPosted() {
|
||||
return posted;
|
||||
}
|
||||
|
||||
public void setPosted(Instant posted) {
|
||||
this.posted = posted;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringBuilder(this).append("title", title).append("author", author).append("posted", posted)
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD})
|
||||
@JsonQualifier
|
||||
public @interface EpochMillis {
|
||||
}
|
||||
|
||||
public static class EpochMillisAdapter {
|
||||
@ToJson
|
||||
public Long toJson(@EpochMillis Instant input) {
|
||||
return input.toEpochMilli();
|
||||
}
|
||||
@FromJson
|
||||
@EpochMillis
|
||||
public Instant fromJson(Long input) {
|
||||
return Instant.ofEpochMilli(input);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.baeldung.moshi;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import com.squareup.moshi.JsonAdapter;
|
||||
import com.squareup.moshi.Moshi;
|
||||
import com.squareup.moshi.Types;
|
||||
import org.junit.Test;
|
||||
|
||||
public class ArrayUnitTest {
|
||||
@Test
|
||||
public void whenSerializingList_thenJsonArrayProduced() {
|
||||
Moshi moshi = new Moshi.Builder()
|
||||
.build();
|
||||
Type type = Types.newParameterizedType(List.class, String.class);
|
||||
JsonAdapter<List<String>> jsonAdapter = moshi.adapter(type);
|
||||
|
||||
String json = jsonAdapter.toJson(Arrays.asList("One", "Two", "Three"));
|
||||
System.out.println(json);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenDeserializingJsonArray_thenListProduced() throws IOException {
|
||||
Moshi moshi = new Moshi.Builder()
|
||||
.build();
|
||||
Type type = Types.newParameterizedType(List.class, String.class);
|
||||
JsonAdapter<List<String>> jsonAdapter = moshi.adapter(type);
|
||||
|
||||
String json = "[\"One\",\"Two\",\"Three\"]";
|
||||
List<String> result = jsonAdapter.fromJson(json);
|
||||
System.out.println(result);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
package com.baeldung.moshi;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
|
||||
import com.squareup.moshi.FromJson;
|
||||
import com.squareup.moshi.JsonAdapter;
|
||||
import com.squareup.moshi.Moshi;
|
||||
import com.squareup.moshi.ToJson;
|
||||
import org.junit.Test;
|
||||
|
||||
public class ComplexAdapterUnitTest {
|
||||
@Test
|
||||
public void whenSerializing_thenCorrectJsonProduced() {
|
||||
Moshi moshi = new Moshi.Builder()
|
||||
.add(new JsonDateTimeAdapter())
|
||||
.build();
|
||||
JsonAdapter<ZonedDateTime> jsonAdapter = moshi.adapter(ZonedDateTime.class);
|
||||
|
||||
String json = jsonAdapter.toJson(ZonedDateTime.now());
|
||||
System.out.println(json);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenDeserializing_thenCorrectJsonConsumed() throws IOException {
|
||||
Moshi moshi = new Moshi.Builder()
|
||||
.add(new JsonDateTimeAdapter())
|
||||
.build();
|
||||
JsonAdapter<ZonedDateTime> jsonAdapter = moshi.adapter(ZonedDateTime.class);
|
||||
|
||||
String json = "{\"date\":\"2020-02-17\",\"time\":\"07:53:27.064\",\"timezone\":\"Europe/London\"}";
|
||||
ZonedDateTime now = jsonAdapter.fromJson(json);
|
||||
System.out.println(now);
|
||||
|
||||
}
|
||||
|
||||
public static class JsonDateTimeAdapter {
|
||||
@ToJson
|
||||
public JsonDateTime toJson(ZonedDateTime input) {
|
||||
String date = input.toLocalDate().toString();
|
||||
String time = input.toLocalTime().toString();
|
||||
String timezone = input.getZone().toString();
|
||||
return new JsonDateTime(date, time, timezone);
|
||||
}
|
||||
@FromJson
|
||||
public ZonedDateTime fromJson(JsonDateTime input) {
|
||||
LocalDate date = LocalDate.parse(input.getDate());
|
||||
LocalTime time = LocalTime.parse(input.getTime());
|
||||
ZoneId timezone = ZoneId.of(input.getTimezone());
|
||||
return ZonedDateTime.of(date, time, timezone);
|
||||
}
|
||||
}
|
||||
public static class JsonDateTime {
|
||||
private String date;
|
||||
private String time;
|
||||
private String timezone;
|
||||
|
||||
public JsonDateTime() {
|
||||
}
|
||||
|
||||
public JsonDateTime(String date, String time, String timezone) {
|
||||
this.date = date;
|
||||
this.time = time;
|
||||
this.timezone = timezone;
|
||||
}
|
||||
|
||||
public String getDate() {
|
||||
return date;
|
||||
}
|
||||
|
||||
public void setDate(String date) {
|
||||
this.date = date;
|
||||
}
|
||||
|
||||
public String getTime() {
|
||||
return time;
|
||||
}
|
||||
|
||||
public void setTime(String time) {
|
||||
this.time = time;
|
||||
}
|
||||
|
||||
public String getTimezone() {
|
||||
return timezone;
|
||||
}
|
||||
|
||||
public void setTimezone(String timezone) {
|
||||
this.timezone = timezone;
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user