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資料文檔的幫助,這裏有一些網址是很是有用的: