Jackson和Gson的区别
Jackson 和 Gson 都是库/API。 这两个库都使用 JSON 数据。 这些也用于将 JSON 数据序列化和反序列化为 Java 对象。 这两个库都是 Java 的完整库,提供 JSON 数据绑定支持并能够处理复杂的数据类型。 这些库提供对 Java 泛型的支持。
Jackson 和 Gson 都可以反序列化 JSON 数据,而无需对实体类进行任何更改。 为了在代码中使用 Jackson 和 Gson,我们需要在 pom.xml 文件中添加以下依赖项。
Gson依赖
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.9.0</version>
</dependency>
Jackson依赖
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.13.2</version>
</dependency>
下面来看看如何使用 Jackson 和 Gson 库来序列化和反序列化 JSON 数据。
Gson序列化
将 Java 对象序列化为 JSON 有两种方法,即简单序列化(使用 toJson()
方法)和自定义序列化(使用自定义序列化程序)。
在简单序列化中,我们使用 Gson 库的 toJson()
方法来序列化一个 Java 对象。通过以下方式使用 toJson()
方法:
String jsonString = new Gson().toJson(object);
下面举个例子来看看如何使用它来序列化特定的 Java 对象。
文件代码: GsonSerializationExample1.java
//import required classes and package if any
import java.util.Scanner;
import com.google.gson.Gson;
//create class GsonSerializationExample1
public class GsonSerializationExample1 {
//main() methods start
public static void main(String args[]) {
// create Scanner class object
Scanner sc= new Scanner(System.in);
College colg;
String name, university, street, state, city, rank;
System.out.println("Enter College Name:");
name = sc.nextLine();
System.out.println("Enter University Name:");
university = sc.nextLine();
System.out.println("Enter Street:");
street = sc.nextLine();
System.out.println("Enter City:");
city = sc.nextLine();
System.out.println("Enter State:");
state = sc.nextLine();
System.out.println("Enter College Rank:");
rank = sc.nextLine();
// set values to College object by using constructor
colg = new College(name, university, new Address(street, state, city), rank);
// serialize College using Gson
String jsonString = new Gson().toJson(colg);
System.out.println(jsonString);
//close Scanner class object
sc.close();
}
}
//create class College
class College {
//Creating properties of College class
public String name;
public String university;
public Address address;
public String rank;
// constructor
College(String name, String university, Address address, String rank){
this.name = name;
this.university = university;
this.address = address;
this.rank = rank;
}
}
//create class Address
class Address {
public String street;
public String state;
public String city;
Address(String street, String state, String city){
this.street = street;
this.state = state;
this.city = city;
}
}
但是,也可以使用自定义序列化程序来序列化 Java 对象。 通过使用自定义序列化程序,可以修改标准行为。 可以处理空值、使用带有 html 的输出格式化程序、添加新输出或从输出中排除属性。
创建序列化程序文件: CollegeGsonSerializer.java -
import java.lang.reflect.Type;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
// create custom serializer for College class
public class CollegeGsonSerializer implements JsonSerializer<College> {
// create an instance of SimpleDateFormat class
private SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
@Override
public JsonElement serialize(College colg, Type type, JsonSerializationContext context) {
// create an instance of JsonObject
JsonObject colgJsonObj = new JsonObject();
// use addProperty() method to add properties to JsonObject
colgJsonObj.addProperty("<strong>College Name</strong>", colg.getCollegeName());
colgJsonObj.addProperty("<strong>University Name</strong>", colg.getUniversityName());
colgJsonObj.addProperty("<strong>College Est.</strong>", colg.getEst() != null ? sdf.format(colg.getEst()) : null);
colgJsonObj.addProperty("<strong>College Address</strong> ", colg.getAddress().size() > 0 ? convertAddress(colg.getAddress()) : null);
colgJsonObj.addProperty("College Rank", colg.getRank() != null ? colg.getRank() : null);
return colgJsonObj;
}
private String convertAddress(List<String> address) {
return address.stream()
.collect(Collectors.joining("-"));
}
}
//create class College
class College {
//Creating properties of College class
public String name;
public String university;
public List<String> address;
public Date est;
public String rank;
// constructor
College(String name, String university, List<String> address, Date est, String rank){
this.name = name;
this.university = university;
this.address = address;
this.est = est;
this.rank = rank;
}
//Getter and Setters
public String getCollegeName() {
return name;
}
public String getUniversityName() {
return university;
}
public Date getEst() {
return est;
}
public List<String> getAddress() {
return address;
}
public String getRank() {
return rank;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return ""College [College Name: "+ name + ", College University = " + university + ", College Est. = " + est + ", Address = "+address+", College Rank = "+rank+"]";
}
}
现在,使用上面的序列化器来序列化 College 类,示例代码: GsonSerializationExample2.java
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
//import required classes and package if any
import java.util.Scanner;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
//create class GsonSerializationExample2 to serialize POJO using custom serializer
public class GsonSerializationExample2 {
//main() methods start
public static void main(String args[]) {
// create Scanner class object
Scanner sc= new Scanner(System.in);
College colg;
String name, university, add1, add2, rank, est;
List<String> address = new ArrayList<String>();
System.out.println("Enter College Name:");
name = sc.nextLine();
System.out.println("Enter University Name:");
university = sc.nextLine();
System.out.println("Enter College Address:");
add1 = sc.nextLine();
System.out.println("Enter University Address:");
add2 = sc.nextLine();
System.out.println("Enter College Est. in dd-mm-yyy format: ");
est = sc.nextLine();
System.out.println("Enter College Rank:");
rank = sc.nextLine();
address.add(add1);
address.add(add2);
Gson gson = new GsonBuilder()
.setPrettyPrinting()
.excludeFieldsWithoutExposeAnnotation()
.serializeNulls()
.disableHtmlEscaping()
.registerTypeAdapter(College.class, new CollegeGsonSerializer())
.create();
// create an instance of SimpleDateFormat
SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
try {
colg = new College(name, university, address, sdf.parse(est), rank);
// convert college to JSON
String jsonString = gson.toJson(colg);
System.out.println("After serializing College using custom serializer: "+jsonString);
} catch (ParseException e) {
e.printStackTrace();
}
//close Scanner class object
sc.close();
}
}
Jackson序列化
就像 Gson 一样,也可以通过两种方式使用 Jackson 将 Java 对象序列化为 JSON,即简单序列化(使用 writeValueAsString()
方法)和自定义序列化(使用自定义序列化程序)。
在简单序列化中,使用 Jackson 库的 writeValueAsString()
方法来序列化 Java 对象。通过以下方式使用 writeValueAsString()
方法:
ObjectMapper mapper = new ObjectMapper();
String jsonString = mapper.writeValueAsString(Object);
下面举个例子来了解如何使用它来序列化特定的 Java 对象。示例代码: JacksonSerializationExample1.java
//import required classes and package if any
import java.util.Scanner;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
//create class JacksonSerializationExample1
public class JacksonSerializationExample1 {
//main() methods start
public static void main(String args[]) {
// create an instance of ObjectMapper class
ObjectMapper mapper = new ObjectMapper();
// create Scanner class object
Scanner sc= new Scanner(System.in);
College colg;
String name, university, street, state, city, rank;
System.out.println("Enter College Name:");
name = sc.nextLine();
System.out.println("Enter University Name:");
university = sc.nextLine();
System.out.println("Enter Street:");
street = sc.nextLine();
System.out.println("Enter City:");
city = sc.nextLine();
System.out.println("Enter State:");
state = sc.nextLine();
System.out.println("Enter College Rank:");
rank = sc.nextLine();
// set values to College object by using constructor
colg = new College(name, university, new Address(street, state, city), rank);
String jsonString;
try {
// serialize College using Jackson
jsonString = mapper.writeValueAsString(colg);
System.out.println(jsonString);
} catch (JsonProcessingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//close Scanner class object
sc.close();
}
}
//create class College
class College {
//Creating properties of College class
public String name;
public String university;
public Address address;
public String rank;
// constructor
College(String name, String university, Address address, String rank){
this.name = name;
this.university = university;
this.address = address;
this.rank = rank;
}
}
//create class Address
class Address {
public String street;
public String state;
public String city;
Address(String street, String state, String city){
this.street = street;
this.state = state;
this.city = city;
}
}
就像 Gson 自定义序列化一样,也可以通过简单地创建一个序列化器来执行 Jackson 自定义序列化。 College.java 创建一个自定义序列化程序,稍后使用 Jackson 进行序列化。
代码文件:CollegeJacksonSerializer.java
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
// create custom serializer for College class
public class CollegeJacksonSerializer extends StdSerializer<College> {
// create an instance of SimpleDateFormat class
private SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
public CollegeJacksonSerializer(Class t) {
super(t);
}
@Override
public void serialize(College colg, JsonGenerator gen, SerializerProvider provider) throws IOException {
gen.writeStartObject();
gen.writeStringField("College Name ", colg.getCollegeName());
gen.writeStringField("College University ", colg.getUniversityName());
gen.writeStringField("Address ", colg.getAddress().stream().collect(Collectors.joining("-")));
gen.writeObjectField("College Est. ", colg.getEst() != null ? sdf.format(colg.getEst()) : null);
gen.writeStringField("College Rank: ", colg.getRank());
gen.writeEndObject();
}
}
//create class College
class College {
//Creating properties of College class
public String name;
public String university;
public List<String> address;
public Date est;
public String rank;
// constructor
College(String name, String university, List<String> address, Date est, String rank){
this.name = name;
this.university = university;
this.address = address;
this.est = est;
this.rank = rank;
}
//Getter and Setters
public String getCollegeName() {
return name;
}
public String getUniversityName() {
return university;
}
public Date getEst() {
return est;
}
public List<String> getAddress() {
return address;
}
public String getRank() {
return rank;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return "\"College [College Name: "+ name + ", College University = " + university + ", College Est. = " + est + ", Address = "+address+", College Rank = "+rank+"]";
}
}
下面使用上面的序列化器来序列化 College 类。文件: JacksonSerializationExample2.java -
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
//import required classes and package if any
import java.util.Scanner;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.util.DefaultPrettyPrinter;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
//create class JacksonSerializationExample2 to serialize POJO using the custom serializer
public class JacksonSerializationExample2 {
//main() methods start
public static void main(String args[]) throws ParseException {
// create Scanner class object
Scanner sc= new Scanner(System.in);
College colg;
String name, university, add1, add2, rank, est;
List<String> address = new ArrayList<String>();
System.out.println("Enter College Name:");
name = sc.nextLine();
System.out.println("Enter University Name:");
university = sc.nextLine();
System.out.println("Enter College Address:");
add1 = sc.nextLine();
System.out.println("Enter University Address:");
add2 = sc.nextLine();
System.out.println("Enter College Est. in dd-mm-yyy format: ");
est = sc.nextLine();
System.out.println("Enter College Rank:");
rank = sc.nextLine();
address.add(add1);
address.add(add2);
// create an instance of SimpleDateFormat
SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
colg = new College(name, university, address, sdf.parse(est), rank);
SimpleModule module = new SimpleModule();
module.addSerializer(new CollegeJacksonSerializer(College.class));
ObjectMapper mapper = new ObjectMapper();
try {
String jsonResult = mapper
.registerModule(module)
.writer(new DefaultPrettyPrinter())
.writeValueAsString(colg);
System.out.println(jsonResult);
} catch (JsonProcessingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//close Scanner class object
sc.close();
}
}
Gson反序列化
反序列化是将 JSON 字符串转换为 Java 对象的另一个重要概念。在两个实体类中都实现了 toString()
方法来说明输出。还可以通过两种方式将 JSON 字符串反序列化为 Java 对象,即简单反序列化和自定义反序列化。
下面以一个简单反序列化的例子来了解如何将 JSON 字符串反序列化为 Java 对象。
文件: GsonDeserializationExample1.java -
import java.text.ParseException;
import java.util.Date;
import java.util.List;
import com.google.gson.Gson;
//create class GsonDeserializationExample1 to deserialize JSON string into POJO
public class GsonDeserializationExample1 {
//main() methods start
public static void main(String args[]) throws ParseException {
String jsonString = "{\"name\":\"JavaDeveloper\",\"expReq\":2,\"valid\":\"05-04-2022\","
+ "\"ctc\":700001,\"employees\":[{\"empName\":\"Nicholas\",\"empId\":\"12001\","
+ "\"empAdd\":\"Noida\",\"empContact\":\"123456\"},{\"empName\":\"Brittany\","
+ "\"empId\":\"1002\",\"empAdd\":\"Noida\",\"empContact\":\"123457\"}]}";
JobPosition position = new Gson().fromJson(jsonString, JobPosition.class);
System.out.println(position);
}
}
//create class JobPosition
class JobPosition {
//Creating properties of College class
public String name;
public int expReq;
public String valid;
public int ctc;
public List<Employee> employees;
// constructor
JobPosition(String name, int expReq, List<Employee> employees, String valid, int ctc){
this.name = name;
this.expReq = expReq;
this.valid = valid;
this.ctc = ctc;
this.employees = employees;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return "\"Job Position [Job Position: "+ name + ", Experience Required: " + expReq + ", Last Date To Apply: " + valid + ", CTC: "+ctc+", Employees Details "+employees+"]";
}
}
//create class Employee
class Employee {
public String empName;
public String empId;
public String empAdd;
public String empContact;
Employee(String empName, String empId, String empAdd, String empContact){
this.empName = empName;
this.empId = empId;
this.empAdd = empAdd;
this.empContact = empContact;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return "\"Employee [Employee Name: "+ empName + ", Employee Id: " + empId + ", Employee Address: " + empAdd + ", Employee Contact: "+empContact+"]";
}
}
在自定义反序列化中,使用自定义反序列化器。它允许修改标准的解串器行为。使用反序列化器来反映 Last Date To Apply
的正确时区。
下面再举一个自定义反序列化的例子,将 JSON 字符串反序列化为 Java 对象。
JobPositionGsonDeserializer.java
import java.lang.reflect.Type;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
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 JobPositionGsonDeserializer implements JsonDeserializer<JobPosition> {
// create an instance of the SimpleDateFormat
private SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
@Override
public JobPosition deserialize(JsonElement element, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException {
// read element as JSON Object
JsonObject obj = element.getAsJsonObject();
JsonElement JobPositionName = obj.get("name");
JsonElement expRequired = obj.get("expReq");
JsonElement ctc = obj.get("ctc");
JsonElement dateToApply = obj.get("valid");
JsonArray employeesData = obj.getAsJsonArray("employees");
ArrayList<String> empList = new ArrayList<String>();
if (employeesData != null) {
for (int i = 0; i < employeesData.size(); i++) {
empList.add(employeesData.get(i).getAsString());
}
}
JobPosition pos;
try {
pos = new JobPosition(JobPositionName.getAsString(), expRequired.getAsInt(), empList, sdf.parse(dateToApply.getAsString()), ctc.getAsInt());
return pos;
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
GsonDeserializationExample2.java
import java.text.ParseException;
import java.util.Date;
import java.util.List;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
//create class GsonDeserializationExample2 to deserialize JSON string into POJO using custom deserializer
public class GsonDeserializationExample2 {
//main() methods start
public static void main(String args[]) throws ParseException {
String jsonString = "{\"name\":\"JavaDeveloper\",\"expReq\":2,"
+ "\"valid\":\"05-04-2022\",\"ctc\":700001,\"employees\":[\"Nicholas\",\"Brittany\",Sharon]}";
Gson gson = new GsonBuilder()
.registerTypeAdapter(JobPosition.class, new JobPositionGsonDeserializer())
.create();
JobPosition position = gson.fromJson(jsonString, JobPosition.class);
System.out.println(position);
}
}
//create class JobPosition
class JobPosition {
//Creating properties of College class
public String name;
public int expReq;
public Date valid;
public int ctc;
public List<String> employees;
// constructor
JobPosition(String name, int expReq, List<String> employees, Date valid, int ctc){
this.name = name;
this.expReq = expReq;
this.valid = valid;
this.ctc = ctc;
this.employees = employees;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return "\"Job Position [Job Position: "+ name + ", Experience Required: " + expReq + ", Last Date To Apply: " + valid + ", CTC: "+ctc+", Employees Details "+employees+"]";
}
}
Jackson反序列化
就像 Gson 一样,可以通过两种方式对 JSON 字符串进行反序列化,即简单反序列化和自定义反序列化。下面举一个例子来了解如何使用 Jackson 反序列化带有/不带有反序列化器的 JSON 字符串。
JacksonDeserializationExample1.java -
import java.text.ParseException;
import java.util.List;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
//create class JacksonDeserializationExample1 to deserialize JSON string into POJO
public class JacksonDeserializationExample1 {
//main() methods start
public static void main(String args[]) throws ParseException {
String jsonString = "{\"name\":\"JavaDeveloper\",\"expReq\":2,"
+ "\"valid\":\"05-04-2022\",\"ctc\":700000,\"employees\":[\"Brittany\",\"Nicholas\",\"Sharon\"]}";
// create an instance of ObjectMapper class
ObjectMapper mapper = new ObjectMapper();
// deserialize jsonString into POJO
try {
JobPosition position = mapper.readValue(jsonString, JobPosition.class);
System.out.println(position);
} catch (JsonMappingException e) {
e.printStackTrace();
} catch (JsonProcessingException e) {
e.printStackTrace();
}
}
}
//create class JobPosition
class JobPosition {
//Creating properties of College class
public String name;
public int expReq;
public String valid;
public int ctc;
public List<String> employees;
// default constructor
JobPosition(){
this.name = null;
this.expReq = 0;
this.valid = null;
this.ctc = 0;
this.employees = null;
}
// constructor
JobPosition(String name, int expReq, List<String> employees, String valid, int ctc){
this.name = name;
this.expReq = expReq;
this.valid = valid;
this.ctc = ctc;
this.employees = employees;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return "\"Job Position [Job Position: "+ name + ", Experience Required: " + expReq + ", Last Date To Apply: " + valid + ", CTC: "+ctc+", Employees Details "+employees+"]";
}
}
文件: JacksonDeserializationExample2.java
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
//create class JacksonDeserializationExample2 to deserialize JSON string into POJO
public class JacksonDeserializationExample2 {
//main() methods start
public static void main(String args[]) throws ParseException {
String jsonString = "{\"name\":\"JavaDeveloper\",\"expReq\":2,"
+ "\"valid\":\"2022-09-21T12:00:00+01:00\",\"ctc\":700000,\"employees\":[\"Brittany\",\"Nicholas\",\"Sharon\"]}";
// create an instance of SimpleDateFormat class
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
// create an instance of ObjectMapper class
ObjectMapper mapper = new ObjectMapper();
// add date format to ObjectMapper class
mapper.setDateFormat(sdf);
// deserialize jsonString into POJO
try {
JobPosition position = mapper.readValue(jsonString, JobPosition.class);
System.out.println(position);
} catch (JsonMappingException e) {
e.printStackTrace();
} catch (JsonProcessingException e) {
e.printStackTrace();
}
}
}
//create class JobPosition
class JobPosition {
//Creating properties of College class
public String name;
public int expReq;
public Date valid;
public int ctc;
public List<String> employees;
// default constructor
JobPosition(){
this.name = null;
this.expReq = 0;
this.valid = null;
this.ctc = 0;
this.employees = null;
}
// constructor
JobPosition(String name, int expReq, List<String> employees, Date valid, int ctc){
this.name = name;
this.expReq = expReq;
this.valid = valid;
this.ctc = ctc;
this.employees = employees;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return "\"Job Position [Job Position: "+ name + ", Experience Required: " + expReq + ", Last Date To Apply: " + valid + ", CTC: "+ctc+", Employees Details "+employees+"]";
}
}