GSON是一个Java语言编写的用于处理JSON数据格式的开源应用程序编程接口项目。它将Java对象转换为JSON表示。还能够用于将JSON字符串转换为等效的Java对象。html
gson
包包含了JSON数据处理的全部常见类和接口。gson
内部的子包reflect
, annotation
, 和 stream
。reflect
包包含处理Java泛型类型信息的类和接口。annotation
包包含相关的类和接口,用于对象属性的自定义名称映射。stream
包包含与读写相关的类和接口。java
GSON设计的初衷以下:jquery
在本节中,将学习实例化GSON及其各类方法的含义,而后是一个快速示例代码,展现包装类型Java对象的基本序列化。web
要使用GSON库,Gson类须要实例化一个com .google.GSON
的对象。GSON对象不维护任何状态,这个特性有助于在多个地方重用GSON对象。ajax
GSON库提供了实例化的两种方法:编程
在这种方法中,可使用new
关键字实例化GSON
类对象。这种方法建立了一个没有设置的object
实例。json
在这种方法中,可使用GsonBuilder
类和create
方法建立一个GSON类对象:api
Gson gson = new GsonBuilder ().create ();
前面的代码调用了GsonBuilder
的create
方法,它返回一个Gson
对象进行初始化。数组
下表列举了GSON
公共的一些方法:浏览器
方法 | 描述 |
---|---|
fromJson | 此方法用于反序列化以获取Java对象。 API中有此方法的重载的形式。 |
toJson | 该方法将Java对象序列化为等效的JSON表示形式。 API中有此方法的重载的形式。 |
toJsonTree | 该方法使用它们的泛型类型序列化对象。API中有此方法的重载的形式。 |
让咱们看看一个简单的例子代码,展现的基本使用GSON库对Java包装类进行序列化/反序列化对象的JSON字符串:
import com.google.gson.Gson; public class QuickStartDemo { public static void main(String[] args) { Gson gson = new Gson(); /*Java Wrapper Type*/ String jsonInteger = gson.toJson(new Integer(1)); String jsonDouble = gson.toJson(new Double(12345.5432)); System.out.println("GSON toJson Method Use "); System.out.println(jsonInteger); System.out.println(jsonDouble); Integer javaInteger = gson.fromJson(jsonInteger, Integer.class); Double javaDouble = gson.fromJson(jsonDouble, Double.class); System.out.println("GSON fromJson Method Use "); System.out.println(javaInteger); System.out.println(javaDouble); } }
输出结果为:
GSON toJson Method Use 1 12345.5432 GSON fromJson Method Use 1 12345.5432
前面的代码演示了toJson
和fromJson
的两种方法的快速使用。
在代码的第一部分中,使用默认方法实例化了一个Gson
类对象,并使用值1
和12345.5432
实例化了两个Java 包装类对象,即Integer
类和Double
类。这些对象传递给toJson
方法,该方法生成JSON等效字符串形式。
方法 | 详细说明 |
---|---|
toJSON |
参数:使用Java类对象进行序列化。 返回:JSON对象的字符串表示形式 |
fromJSON |
参数:第一个参数是JSON表示的字符串类型,第二个参数是预期的Java类类型。返回:预期的Java类对象 |
在代码的最后一部分中,JSON等效字符串传递给fromJson
方法。 该方法有两个参数,第一个参数是一个字符串,第二个参数是一个预期的Java类类型。 fromJson
方法的返回类型始终是Java类型。
在本节中,将了解GSON库支持的主要功能以及如何实现这些功能。
GSON中的对象被称为JsonElement
的类型:
GSON库能够将任何用户定义的类对象转换为JSON表示。Student
类是一个用户定义的类,GSON能够将任何Student
对象序列化为JSON。
如下是 Student.java
的代码:
package com.lee.jsondemo; public class Student { private String name; private String subject; private int mark; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSubject() { return subject; } public void setSubject(String subject) { this.subject = subject; } public int getMark() { return mark; } public void setMark(int mark) { this.mark = mark; } }
对Student
类进行操做的JavaObjectFeaturesUse.java
代码以下:
import com.google.gson.Gson; importcom.packt.chapter.vo.Student; public class JavaObjectFeaturesUse { public static void main(String[] args){ Gsongson = new Gson(); Student aStudent = new Student(); aStudent.setName("Sandeep"); aStudent.setMark(128); aStudent.setSubject("Computer Science"); String studentJson = gson.toJson(aStudent); System.out.println(studentJson); Student anotherStudent = gson.fromJson(studentJson, Student.class); System.out.println(anotherStudentinstanceof Student); } }
执行结果为:
{"name":"Sandeep","subject":"Computer Science","mark":128} true
上面的代码建立了一个name
属性为sandeep
的学生对象,subject
属性设置为Computer Scienc
,mark
为128
。而后将一个Gson
对象实例化,并将学生对象做为一个参数传递给toJson()
方法。它返回一个字符串,该字符串具备Java对象的JSON表示。该字符串做为控制台中的第一行打印。学生对象的输出JSON表示是键/值对的集合。学生类的Java属性成为JSON字符串中的键。
在代码的最后一部分中,fromJson()
方法将JSON生成的字符串做为第一个输入参数,Student.class
做为第二个参数,将JSON字符串转换回Java对象。代码的最后一行使用Student
做为第二行操做符的实例来验证由fromJson()
方法生成的Java对象是不是Student
类型的。在控制台中,它输出true
,则表示咱们将获得与JSON相同的值。
GSON有一些类的隐式序列化,好比Java包装类(Integer
、Long
、Double
等等)、Java.net.url
、java.net.URI
、java.util.Date
,等等。
让我看个例子:
import java.util.Date; import com.google.gson.Gson; public class InbuiltSerializerFeature { public static void main(String[] args) { Date aDateJson = new Date(); Gson gson = new Gson(); String jsonDate = gson.toJson(aDateJson); System.out.println(jsonDate); } }
输出结果为:
"Sep 15, 2017 10:38:35 PM"
前面的代码是将Java的Date
类对象序列化为JSON表示。在前面的部分中,您已经了解了如何使用GSON来序列化和反序列化对象,以及它如何为用户定义的Java类对象提供定制化的序列化器和反序列化器。让咱们看看它是如何工做的。
另外,GSON还为开发人员提供了可定制的序列化的特性。
下面的代码是一个可定制序列化器的示例:
public class StudentTypeSerializer implements JsonSerializer<Student> { @Override public JsonElement serialize(Student student, Type type, JsonSerializationContext context) { JsonObject obj = new JsonObject(); obj.addProperty("studentname", student.getName()); obj.addProperty("subjecttaken", student.getSubject()); obj.addProperty("marksecured", student.getMark()); return obj; } }
下面的代码是一个自定义反序列化器的例子:
class StudentTypeDeserializer implements JsonDeserializer<Student> { @Override public Student deserialize(JsonElement jsonelment, Type type, JsonDeserializationContext context) throws JsonParseException { JsonObject jsonObject = jsonelment.getAsJsonObject(); Student aStudent = new Student(); aStudent.setName(jsonObject.get("studentname").getAsString()); aStudent.setSubject(jsonObject.get("subjecttaken").getAsString()); aStudent.setMark(jsonObject.get("marksecured").getAsInt()); return aStudent; } }
如下代码测试自定义序列化器和反序列化器:
import com.google.gson.Gson; import com.google.gson.GsonBuilder; public class CustomSerializerFeature { public static void main(String[] args) { GsonBuilder gsonBuilder = new GsonBuilder(); gsonBuilder.registerTypeAdapter(Student.class, new StudentTypeSerializer()); Gson gson = gsonBuilder.create(); Student aStudent = new Student(); aStudent.setName("Sandeep"); aStudent.setMark(150); aStudent.setSubject("Arithmetic"); String studentJson = gson.toJson(aStudent); System.out.println("Custom Serializer : Json String Representation "); System.out.println(studentJson); gsonBuilder.registerTypeAdapter(Student.class, new StudentTypeDeserializer()); Gson gsonde = gsonBuilder.create(); Student deStudent = gsonde.fromJson(studentJson, Student.class); System.out.println("Custom DeSerializer : Java Object Creation"); System.out.println("Student Name " + deStudent.getName()); System.out.println("Student Mark " + deStudent.getMark()); System.out.println("Student Subject " + deStudent.getSubject()); System.out.println("is anotherStudent is type of Student " + (deStudent instanceof Student)); } }
输出结果为:
Custom Serializer : Json String Representation {"studentname":"Sandeep","subjecttaken":"Arithmetic","marksecured":150} Custom DeSerializer : Java Object Creation Student Name Sandeep Student Mark 150 Student Subject Arithmetic is anotherStudent is type of Student true
GSON的序列化输出的JSON表示格式紧凑。若是有大量的Java对象集合,而且每一个对象都有许多序列化的属性,那么它们紧凑的JSON表示的可读性是很是差的,并且看起来很难看。
为了解决这个问题,GsonBuilder
支持漂亮的打印配置,同时为序列化使用建立一个Gson
对象。这个漂亮的打印功能经过适当的标签缩进和新的换行来美化JSON字符串的输出。
如下是关于格式化程序的一些重要内容:
JsonPrintFormatter
和JsonCompactFormatter
是GSON中的两种格式化类型的表示。JsonCompactFormatter
是GSON的默认格式化程序。JsonPrintFormatter
用于漂亮的打印,它不会暴露在API中。因此开发者不能修改。JsonPrintFormatter
支持一个默认行长度为80个字符,两个字符缩进,以及右侧保持四个字符。GsonBuilder
的setPrettyPrinting()
方法来使用JsonPrintFormatter
。具体看一个例子:
import java.util.ArrayList; import java.util.List; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.packt.chapter.vo.Student; public class PrettyPrintFeature { public static void main(String[] args) { Gson gson = new GsonBuilder().setPrettyPrinting().create(); List<Student> listOfStudent = new ArrayList<Student>(); Student student1 = new Student(); student1.setName("Sandeep Kumar Patel"); student1.setSubject("Arithmetic"); student1.setMark(234); Student student2 = new Student(); student2.setName("Sangeeta Patel"); student2.setSubject("Geography"); student2.setMark(214); listOfStudent.add(student1); listOfStudent.add(student2); String prettyJsonString = gson.toJson(listOfStudent); System.out.println(prettyJsonString); } }
输出结果为:
[ { "name": "Sandeep Kumar Patel", "subject": "Arithmetic", "mark": 234 }, { "name": "Sangeeta Patel", "subject": "Geography", "mark": 214 } ]
上面的代码将学生列表序列化为JSON表示。它使用GsonBuilder
类得到一个Gson
对象。使用setPrettyPrinting()
方法配置漂亮的打印。能够看到之前的代码的输出已经正确地缩进,而且阅读起来很愉快。
Java内部类能够有两种类型:
下面将看到GSON如何处理这些类型的内部类类对象的。
GSON能够隐式地序列化/反序列化静态内部类。不须要额外的配置。
让咱们看一个静态内部类的例子:
import com.google.gson.Gson; import com.google.gson.GsonBuilder; class Student { private String studentName; private int mark; public String getStudentName() { return studentName; } public void setStudentName(String studentName) { this.studentName = studentName; } public int getMark() { return mark; } public void setMark(int mark) { this.mark = mark; } public static class Course { private String courseName; private String duration; public String getCourseName() { return courseName; } public void setCourseName(String courseName) { this.courseName = courseName; } public String getDuration() { return duration; } public void setDuration(String duration) { this.duration = duration; } } } public class StaticNestedClassFeature { public static void main(String[] args) { Gson gson = new GsonBuilder().setPrettyPrinting().create(); Student.Course aCourse = new Student.Course(); aCourse.setCourseName("M.TECH."); aCourse.setDuration("120 hr"); String jsonCourse = gson.toJson(aCourse); System.out.println(jsonCourse); Student.Course anotherCourse = gson.fromJson(jsonCourse, Student.Course.class); System.out.println("Course : " + anotherCourse.getCourseName() + "Duration : " + anotherCourse.getDuration()); } }
输出结果为:
{ "courseName": "M.TECH.", "duration": "120 hr" } Course : M.TECH.Duration : 120 hr
在上面的代码中,Course
类是Student
类内的静态内部类。courseName
和duration
是两个属性,以及各自的getter和setter方法在。经过外部类的.
操做符调用,能够在Java中实例化一个静态的内部类。Student.Course aCourse = new Student.Course()
用来初始化内部Course
类的。M.TECH.
和120 hr
则是用来实例化它的两个值。从输出中能够看出,GSON可以序列化生成Course
对象的JSON表示的静态内部类。输出的最后一行显示GSON成功地将其反序列化。
Java中的一个实例内部类能够经过使用外部类对象来实例化。下面的代码演示了GSON如何序列化和反序列化一个实例内部类的Java类对象:
import com.google.gson.Gson; import com.google.gson.GsonBuilder; class Student { private String studentName; private int mark; public String getStudentName() { return studentName; } public void setStudentName(String studentName) { this.studentName = studentName; } public int getMark() { return mark; } public void setMark(int mark) { this.mark = mark; } public class Course { private String courseName; private String duration; public String getCourseName() { return courseName; } public void setCourseName(String courseName) { this.courseName = courseName; } public String getDuration() { return duration; } public void setDuration(String duration) { this.duration = duration; } } } public class InstanceNestedClassFeature { public static void main(String[] args) { Gson gson = new GsonBuilder().setPrettyPrinting().create(); Student outstudent = new Student(); Student.Course instanceCourse = outstudent.new Course(); instanceCourse.setCourseName("M.TECH."); instanceCourse.setDuration("12 hr"); String jsonCourse = gson.toJson(instanceCourse); System.out.println(jsonCourse); Student.Course anotherCourse = gson.fromJson(jsonCourse, Student.Course.class); System.out.println("Course : " + anotherCourse.getCourseName() + "Duration : " + anotherCourse.getDuration()); } }
输出结果为:
{ "courseName": "M.TECH.", "duration": "12 hr" } Course : M.TECH.Duration : 12 hr
在前面的代码中,Course
是一个实例内部类,有两个字段和它们的getter和setter方法。Course
对象的nstanceccourse
是使用外部类对象outstudent
实例化的。这个内部类对象被放置到序列化和反序列化中,从而在控制台上产生结果。在反序列化过程当中,fromJson()
方法使用Student
做为第二个参数。固然,它帮助GSON成功地将其反序列化到内部类对象中。
GSON支持将Java数组转换为JSON表示。
让咱们来看一个数组的例子:
import com.google.gson.Gson; import com.google.gson.GsonBuilder; public class ArrayFeature { public static void main(String[] args) { Gson gson = new GsonBuilder().create(); int[] numberArray = { 121, 23, 34, 44, 52 }; String[] fruitsArray = { "apple", "oranges", "grapes" }; String jsonNumber = gson.toJson(numberArray); String jsonString = gson.toJson(fruitsArray); System.out.println(jsonNumber); System.out.println(jsonString); int[] numCollectionArray = gson.fromJson(jsonNumber, int[].class); String[] fruitBasketArray = gson.fromJson(jsonString, String[].class); System.out.println("Number Array Length " + numCollectionArray.length); System.out.println("Fruit Array Length " + fruitBasketArray.length); } }
输出结果为:
[121,23,34,44,52] ["apple","oranges","grapes"] Number Array Length 5 Fruit Array Length 3
GSON使用com.google.gson.reflect.TypeToken
来支持泛型类型的Java类对象,用于序列化和反序列化。使用TypeToken
类的目的是使用Java泛型类型的类型擦除的特性。
类型擦除发生在编译期,在这里,Java泛型类型被彻底删除,以产生字节码。所以,在将JSON字符串反序列化为泛型Java类时,它可能会没有正确地反序列化。
下面的代码演示了泛型类型序列化/反序列化以及TypeToken
类是用来解决这个问题:
import java.lang.reflect.Type; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; class StudentGeneric<T, E> { T mark; E name; public T getMark() { return mark; } public void setMark(T mark) { this.mark = mark; } public E getName() { return name; } public void setName(E name) { this.name = name; } } public class GenericTypeFeature { @SuppressWarnings("unchecked") public static void main(String[] args) { Gson gson = new Gson(); StudentGeneric<Integer, String> studGenericObj1 = new StudentGeneric<Integer, String>(); studGenericObj1.setMark(25); studGenericObj1.setName("Sandeep"); String json = gson.toJson(studGenericObj1); System.out.println("Serialized Output :"); System.out.println(json); StudentGeneric<Integer, String> studGenericObj2 = gson.fromJson(json, StudentGeneric.class); System.out.println("DeSerialized Output :"); System.out.println("Mark : " + studGenericObj2.getMark()); Type studentGenericType = new TypeToken<StudentGeneric<Integer, String>>() {}.getType(); StudentGeneric<Integer, String> studGenericObj3 = gson.fromJson(json, studentGenericType); System.out.println("TypeToken Use DeSerialized Output :"); System.out.println("Mark : " + studGenericObj3.getMark()); } }
输出结果为:
Serialized Output : {"mark":25,"name":"Sandeep"} DeSerialized Output : Mark : 25.0 TypeToken Use DeSerialized Output : Mark : 25
在上面的代码中,StudentGeneric
类接受两个泛型参数,并有各自的getter和setter方法。StudentGeneric
类对象使用Integer
和String
做为mark
和name
的类型来建立的。在序列化时,mark
被初始化为25,但反序列化输出显示为25.0,这是一个不正确的值,由于类型擦除属性在编译时从类中删除了泛型类型的参数。使用TypeToken
类来解决这个问题。getType()
方法返回具备泛型参数的原始类类型,它帮助GSON正确地反序列化对象,并将正确值输出为25。
GSON也可以对null
对象进行序列化/反序列化的JSON表示。
让咱们看一个空对象的例子:
import com.google.gson.Gson; import com.google.gson.GsonBuilder; public class NullSupportFeature { public static void main(String[] args) { Gson gson = new GsonBuilder().serializeNulls().setPrettyPrinting().create(); Student aStudent = new Student(); aStudent.setName("Sandeep Kumar Patel"); aStudent.setSubject(null); aStudent.setMark(234); String studentJson = gson.toJson(aStudent); System.out.println(studentJson); Student javaStudentObject = gson.fromJson(studentJson, Student.class); System.out.println("Student Subject: " + javaStudentObject.getSubject()); System.out.println("Student Name: " + javaStudentObject.getName()); } }
输出结果为:
{ "name": "Sandeep Kumar Patel", "subject": null, "mark": 234 } Student Subject:null Student Name:Sandeep Kumar Patel
GSON提供了版本化的序列化/反序列化的Java对象的JSON表示。这有助于迭代开发和发布值对象。GSON API提供了一种机制来知足这些不一样版本数据的请求。
让咱们看一个版本支持的例子:
import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.annotations.Since; @Since(1.0) class Student { private String name; private String subject; private int mark; @Since(1.1) private String gender; public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSubject() { return subject; } public void setSubject(String subject) { this.subject = subject; } public int getMark() { return mark; } public void setMark(int mark) { this.mark = mark; } } public class VersionSupportFeature { public static void main(String[] args) { Student aStudent = new Student(); aStudent.setName("Sandeep Kumar Patel"); aStudent.setSubject("Algebra"); aStudent.setMark(534); aStudent.setGender("Male"); System.out.println("Student json for Version 1.0 "); Gson gson = new GsonBuilder().setVersion(1.0).setPrettyPrinting().create(); String jsonOutput = gson.toJson(aStudent); System.out.println(jsonOutput); System.out.println("Student json for Version 1.1 "); gson = new GsonBuilder().setVersion(1.1).setPrettyPrinting().create(); jsonOutput = gson.toJson(aStudent); System.out.println(jsonOutput); } }
输出结果为:
Student json for Version 1.0 { "name": "Sandeep Kumar Patel", "subject": "Algebra", "mark": 534 } Student json for Version 1.1 { "name": "Sandeep Kumar Patel", "subject": "Algebra", "mark": 534, "gender": "Male" }
尽管Java对象进行序列化/反序列化或JSON字符串,GSON建立一个默认实例的类的构造方法。有一个默认的Java类的无参数构造方法是很好的。若是一个类没有默认构造函数,GSON提供一个class.google.gson.InstanceCreator
接口实现来处理它。
方法 | 详细说明 |
---|---|
createInstance | 参数:java.lang.reflect.Type类的实例;返回值:T 类型的默认对象实例,引用对象实例的类类型。 |
让咱们看一个无参构造方法的例子:
import java.lang.reflect.Type; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.InstanceCreator; class Employee { private String name; private Salary salary; public String getName() { return name; } public void setName(String name) { this.name = name; } public Salary getSalary() { return salary; } public void setSalary(Salary salary) { this.salary = salary; } @Override public String toString() { return "Employee [name=" + name + ", salary=" + salary + " ]"; } } class Salary { private int salaryAmount; Salary(int salary) { this.salaryAmount = salary; } @Override public String toString() { return "Salary [salaryAmount=" + salaryAmount + "]"; } } class SalaryInstanceCreator implements InstanceCreator<Salary> { @Override public Salary createInstance(Type type) { return new Salary(25000); } } public class InstanceCreatorUse { public static void main(String[] args) { String jsonString = "{\"name\" :\"Sandeep\" , \"salary\": {}}"; Gson gson = new GsonBuilder().serializeNulls().registerTypeAdapter(Salary.class, new SalaryInstanceCreator()) .setPrettyPrinting().create(); System.out.println(gson.fromJson(jsonString, Employee.class)); } }
上面的代码演示了一个JSON字符串类型的Employee类,该字符串被反序列化为Employee
类型的对象。
jsonString = "{\"name\" :\"Sandeep\" , \"salary\": {}}";
toString()
方法:Employee [name=Sandeep, salary=Salary [salaryAmount=25000]]
使用com .google. gson.InstanceCreator
来实现一个SalaryInstanceCreator
类,并重写createInstance()方法,该方法返回值25000的参数化的Salary
构造方法。
这个SalaryInstanceCreator
使用registerTypeAdapter()
方法注册为GSON。
当GSON找到空的Salary
字符串时,它将寻找类型Salary
的默认构造方法。因为不存在默认的Salary
构造方法,因此它寻找类型适配器的GsonBuilder
设置,并找到SalaryInstanceCreator
。并调用createInstance()
方法。
所以,当对一个空的Salary
类对象进行反序列化时,GSON将得到25000做为默认值。
该特性为开发人员在序列化Java对象时提供自定义名称提供了灵活性。JSON表示变得更有意义和可读性。
GSON提供了一个具备内置属性命名支持的FieldNamingPolicy
类:
import com.google.gson.FieldNamingPolicy; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.annotations.SerializedName; class College { @SerializedName("instituteName") private String name; private String[] coursesOffer; public String getName() { return name; } public void setName(String name) { this.name = name; } public String[] getCoursesOffer() { return coursesOffer; } public void setCoursesOffer(String[] coursesOffer) { this.coursesOffer = coursesOffer; } } public class FieldNamingFeature { public static void main(String[] args) { Gson gson = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE).setPrettyPrinting() .create(); College aCollege = new College(); aCollege.setName("VIT University, Vellore"); String[] courses = { "BTECH, MTECH, BSC, MSC" }; aCollege.setCoursesOffer(courses); String jsonCollege = gson.toJson(aCollege); System.out.println(jsonCollege); College anotherCollege = gson.fromJson(jsonCollege, College.class); System.out.println("College Name : " + anotherCollege.getName()); } }
输出结果为:
{ "instituteName": "VIT University, Vellore", "CoursesOffer": [ "BTECH, MTECH, BSC, MSC" ] } College Name : VIT University, Vellore
除了基本的属性命名功能以外,GSON还提供了一个FieldNamingStrategy
类,以使开发人员可以建立本身的属性命名策略。如下步骤演示如何建立自定义属性命名策略:
FieldNamingStrategy
接口translateName
方法方法 | 详细说明 |
---|---|
translateName | 参数:java.lang.reflect.Field ;返回:已更改的属性名字符串 |
让咱们看一个用户定义属性命名的示例:
import java.lang.reflect.Field; import com.google.gson.FieldNamingStrategy; import com.google.gson.Gson; import com.google.gson.GsonBuilder; class College { private String name; private String[] coursesOffer; public String getName() { return name; } public void setName(String name) { this.name = name; } public String[] getCoursesOffer() { return coursesOffer; } public void setCoursesOffer(String[] coursesOffer) { this.coursesOffer = coursesOffer; } } class CustomFieldStrategy implements FieldNamingStrategy { @Override public String translateName(Field aField) { String nameOfField = aField.getName(); return nameOfField.toUpperCase(); } } public class CustomFieldNamingFeature { public static void main(String[] args) { Gson gson = new GsonBuilder().setFieldNamingStrategy(new CustomFieldStrategy()).setPrettyPrinting().create(); College aCollege = new College(); aCollege.setName("VIT University, Vellore"); String[] courses = { "BTECH, MTECH, BSC, MSC" }; aCollege.setCoursesOffer(courses); String jsonCollege = gson.toJson(aCollege); System.out.println(jsonCollege); } }
输出结果为:
{ "NAME": "VIT University, Vellore", "COURSESOFFER": [ "BTECH, MTECH, BSC, MSC" ] }
GSON API也支持序列化期间的属性排除。开发人员能够在序列化Java对象时排除某些属性。GSON提供了两种不一样的方法来实现属性的排除:
GsonBuilder
前面的图形显示了GSON中两种不一样的属性排除策略方法的摘要。每一种方法都有详细的解释。
GsonBuilder
提供excludeFieldsWithModifiers()
方法来排除属性序列化。该方法提供了排除全部具备指定修饰符的类属性的能力。该方法的原型特征以下:
public GsonBuilder excludeFieldsWithModifiers(int... modifiers)
...
符号,表示入参是java.lang.reflect.Modifier
类型可变参数,例如Modifier.STATIC
,Modifier.PUBLIC
和 Modifier.PRIVATE
。GsonBuilder
类型的引用对象。让咱们来看一个配置GsonBuilder
的示例:
import java.lang.reflect.Modifier; import com.google.gson.Gson; import com.google.gson.GsonBuilder; class Employee { private String name; private transient String gender; private static String designation; protected String department; public Employee() { this("Abcd Employee", "MALE", "Tech Lead", "IT Services"); } @SuppressWarnings("static-access") public Employee(String name, String gender, String designation, String department) { this.name = name; this.gender = gender; this.designation = designation; this.department = department; } } public class FieldExclusionFeature { public static void main(String[] args) { Gson gson = new Gson(); String json = gson.toJson(new Employee("Sandeep", "Male", "Tech Lead", "IT Services")); System.out.println(json); Gson gson2 = new GsonBuilder().excludeFieldsWithModifiers().create(); json = gson2.toJson(new Employee("Sandeep", "MALE", "Tech Lead", "IT Services")); System.out.println(json); Gson gson3 = new GsonBuilder().excludeFieldsWithModifiers(Modifier.STATIC).create(); json = gson3.toJson(new Employee("Sandeep", "MALE", "Tech Lead", "IT Services")); System.out.println(json); } }
输出结果为:
{"name":"Sandeep","department":"IT Services"} {"name":"Sandeep","gender":"MALE","designation":"Tech Lead","department":"IT Services"} {"name":"Sandeep","gender":"MALE","department":"IT Services"}
咱们能够从以前的代码中获得三个启示:
Employee
类JSON字符串,它有两个属性:name
和department
。这个输出是因为Gson对象,使用默认的方法建立的。所以,在序列化时,它省略了static
和transient
修饰的属性。Employee
类JSON字符串,它有四个属性:name
、gender
、designation
和department
。这个输出是因为Gson对象使用构造器的方式和excludeFieldWithModifiers()
方法。当没有参数传递时,它会序列化Employee
对象中存在的全部字属性类型。Employee
类JSON字符串,该字符串包含三个属性:name
、gender
和department
。输出是因为Gson对象使用构造器的方式和excludeFieldsWithModifiers()
方法。Modifier.STATIC
做为一个参数传递给这个方法,它不序列化Employee
对象的任何静态属性。GSON提供@Expose
注解实如今序列化期间排除指定属性。属性标有@Expose
注解的将序列化为JSON表示。GSON的excludeFieldsWithoutExposeAnnotation()
方法必须在配置GsonBuilder
使用@Expose
注解时被调用。
让咱们来看一个使用@Expose
注解的例子:
import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.annotations.Expose; class Vegetable { private String name; @Expose private int price; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getPrice() { return price; } public void setPrice(int price) { this.price = price; } } public class FieldExclusionAnnotationUse { public static void main(String[] args) { Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation() .create(); Vegetable aVegetable = new Vegetable(); aVegetable.setName("Potato"); aVegetable.setPrice(26); String jsonVegetable = gson.toJson(aVegetable); System.out.println("JSON Representation of Vegetable : "); System.out.println(jsonVegetable); } }
输出结果为:
JSON Representation of Vegetable : {"price":26}
咱们能够从前面的代码中得出如下几点启示:
price
的JSON字符串。这个输出是因为Gson对象使用构造器的方式和excludeFieldsWithoutExposeAnnotation()
方法。@Expose
的属性。GSON为开发人员提供了灵活性,能够建立一个自定义注解,用于排除属性和类。下面的步骤演示了如何建立自定义注解:
com.google.gson.ExclusionStrategy
。ExclusionStrategy
接口提供了两种方法。经过实现这个接口,Java类提供了定制排除注解的功能。当GSON在序列化或反序列化并找到一个自定义注解时,它会查看实现了ExclusionStrategy
接口的Java类,以找出如何处理它。ExclusionStrategy
接口提供了两种方法:
方法名 | 详细说明 |
---|---|
shouldSkipField | 参数:FieldAttributes 引用类型;返回Boolean值:true:属性将被序列化/反序列化输出的一部分;false:属性将不会被序列化/反序列化输出的一部分。 |
shouldSkipClass | 参数:Class 类的引用类型。返回Boolean值:true:类将序列化/反序列化输出的一部分;false:类将不会被序列化/反序列化输出的一部分。 |
让咱们来看一个用户定义的属性排除注解的示例:
import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import com.google.gson.ExclusionStrategy; import com.google.gson.FieldAttributes; import com.google.gson.Gson; import com.google.gson.GsonBuilder; @Retention(RetentionPolicy.RUNTIME) @Target({ ElementType.FIELD }) @interface MyExclude { } class CustomExclusionStrategy implements ExclusionStrategy { private final Class<?> typeToExclude; CustomExclusionStrategy(Class<?> typeToExclude) { this.typeToExclude = typeToExclude; } public boolean shouldSkipClass(Class<?> classname) { return (classname == typeToExclude); } public boolean shouldSkipField(FieldAttributes f) { return f.getAnnotation(MyExclude.class) != null; } } class Vegetable { private String name; @MyExclude private int price; public Vegetable() { } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getPrice() { return price; } public void setPrice(int price) { this.price = price; } } public class UserDefinedFieldExclusion { public static void main(String[] args) { Gson gson = new GsonBuilder().setExclusionStrategies(new CustomExclusionStrategy(MyExclude.class)).create(); Vegetable aVegetable = new Vegetable(); aVegetable.setName("Potato"); aVegetable.setPrice(26); String jsonVegetable = gson.toJson(aVegetable); System.out.println(jsonVegetable); } }
输出结果为:
{"name":"Potato"}
上面的代码执行如下步骤:
java.lang.annotation
建立用户自定义注解@MyExclude
。MyExclude.class
参数的CustomExclusionStrategy
类实例化一个自定义排除策略。setExclusionStrategies
方法,GsonBuilder
配置这个新的排除策略。GsonBuilder
建立的Gson
对象将排除带有@MyExclude
注解的字段。在JSON格式和它相应的语言库GSON的发明以后,Java web应用程序的开发(客户端与服务器端进行通讯并以JSON格式对数据进行响应)得到了大量的流行,这使得Web 2.0应用程序很是成功。
如下StudentJsonDataServlet.java
展现了一个Java servlet如何返回Student
类型的JSON数据,并在浏览器中呈现为HTML表格:
import java.io.IOException; import java.util.ArrayList; import java.util.List; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.google.gson.Gson; import com.packt.myapp.data.Student; @WebServlet("/StudentJsonDataServlet") public class StudentJsonDataServlet extends HttpServlet { private static final long serialVersionUID = 1L; public StudentJsonDataServlet() { } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Gson gson = new Gson(); List<Student> listOfStudent = getStudentData(); String jsonString = gson.toJson(listOfStudent); response.setContentType("application/json"); response.getWriter().write(jsonString); } /** * Returns List of Static Student data */ private List<Student> getStudentData() { Student s1 = new Student(); s1.setName("Sandeep"); s1.setSubject("Computer"); s1.setMark(85); Student s2 = new Student(); s2.setName("John"); s2.setSubject("Science"); s2.setMark(85); Student s3 = new Student(); s3.setName("Ram"); s3.setSubject("Computer"); s3.setMark(85); List<Student> listOfStudent = new ArrayList<Student>(); listOfStudent.add(s1); listOfStudent.add(s2); listOfStudent.add(s3); return listOfStudent; } }
StudentJsonDataServlet
将学生的详细信息做为JSON字符串返回。并向浏览器代表,数据响应是一个json类型的头文件,须要设置为application/json
。
如下studentstableview.html
是在浏览器中渲染servlet响应的文件:
<html> <head> <title>Students JSON Table View</title> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> </head> <body> <div id="student-data-container"></div> <script> $(document).ready(function(){ var getStudentTableHtml, html, htmlStudent, container =$('#student-data-container'), ajaxRequest = $.ajax({ url: "StudentJsonDataServlet", dataType: "JSON", success: function(data){ htmlStudent = getStudentTableHtml(data); container.html(htmlStudent) } }), getStudentTableHtml = function(data){ html = []; html.push("<TABLE border='2px' cellspacing='2px'>"); html.push("<TR>"); html.push("<TH>NAME</TH>"); html.push("<TH>SUBJECT</TH>"); html.push("<TH>MARK</TH>"); html.push("</TR>"); $.each(data,function(index, aStudent){ html.push("<TR>"); html.push("<TD>"); html.push(aStudent.name); html.push("</TD>"); html.push("<TD>"); html.push(aStudent.subject); html.push("</TD>"); html.push("<TD>"); html.push(aStudent.mark); html.push("</TD>"); html.push("</TR>"); }); html.push("</TABLE>") return html.join(""); } }) </script> </body> </html>
上面的代码展现了在DOM就绪事件上调用jQuery Ajax事件。servlet使用GSON API将Student
对象的列表转换为相应的JSON表示,并将其做为响应内容发送到客户端。如下截图中的Firebug控制台显示了JSON对象中的Ajax请求和响应:
在获得响应时,jQuery调用success
方法来处理。做为返回,成功处理程序调用getStudentTableHtml()
方法在HTML中构建一个表格。
该方法使用for
循环来迭代每一个学生JSON对象来构建表格的行。下面截图显示了学生JSON响应数据构建的学生详细信息的HTML表格:
若是你须要相关GSON资料文档的帮助,这里有一些网址是很是有用的: