译文链接: http://www.importnew.com/16630.html
一个简单的示例
package com.javacreed.examples.gson.part1;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
public class SimpleExample1 {
public static void main(String[] args) {
Gson gson = new GsonBuilder().create();
gson.toJson("Hello", System.out);
gson.toJson(123, System.out);
}
}
在上面的例子中,我们创建了一个Gson实例,并把Java String和int转化为JSON对象。以上代码命令行里的输出结果如下:"Hello"123
"Hello"123
该toJason()方法有两个参数,Java对象转换为JSON和可追加(Java的文档)的一个实例。我们可以很容易地改变了一个文件或网络流。
注意
尽量使用泛型是一个很好的方法。在上例中,我们只使用了Appendable和Writer接口定义的方法。使用泛型使代码更易于移植和维护,下面是个不好的例子。
注意,上面例子中,我们没有正确处理流(Writer)。理想情况下,资源在finaly块 (教程) 中关闭或者用在try-with-resource(教程)中。我们忽略了这个是为了保持代码简洁。
public static void main(String[] args) throws IOException {
try (Writer writer = new FileWriter("Output.json")) {
Gson gson = new GsonBuilder().create();
gson.toJson("Hello", writer);
gson.toJson(123, writer);
}
}
以上代码生成文件:包含JSON对象的Output.json。注意,这里我们使用了字符流而不是字节流。因为toJson()方法需要一个Appendanble实例,而字节流不能实现Appendable接口,所以我们使用了字符流。Appendable接口处理字符而不是字节。Java提供了InputStreanReader(Java文档)和OutputStreamWriter(Java文档)类进行字节流与字符流的转换,如下面的例子。
注意
注意,使用InputStreamREader和OutputStreamWriter类时,如果不提供编码或者字符集,转换将使用平台默认字符集。这将降低代码的可移植性,且在其他平台上运行将可能产生错误行为。
package com.javacreed.examples.gson.part1;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
public class SimpleExample3 {
public static void main(String[] args) throws IOException {
try(Writer writer = new OutputStreamWriter(new FileOutputStream("Output.json") , "UTF-8")){
Gson gson = new GsonBuilder().create();
gson.toJson("Hello", writer);
gson.toJson(123, writer);
}
}
}
如你所见,我们只需要改变实例的一部分。代码的剩余部分没有任何变化。这就是使用接口代替类作为变量类型的好处之一。
使用Json对象
{
NAME:"Albert Attard",
P_LANGUAGE:"Java",
LOCATION:"Malta"
}
此JSON对象包含3个不同值的域。比如我们需要使用JSON对象并创建一个Java对象来展示它。为了使这个例子更有趣,假设我们只关心name和location域。
首先创建一个Java类来表示name和location。类命名为Person。类的名字无关紧要,但域的名字必须一致。域名必须匹配(大小写敏感)JSON对象中的名字。更进一步,类必须包含一个默认构造函数(即使它被设置为private)。如下所示,name和location域在JSON中是大写的。JSON中域P_LANGUAGE被忽略了,因为Java对象中不包括该名称的域。请理解域名不遵守Java命名规范,暂时只是为了简化。更多内容将在第2部分中讨论。
package com.javacreed.examples.gson.part2;
public class Person {
private String NAME;
private String LOCATION;
// Getters and setters are not required for this example.
// GSON sets the fields directly using reflection.
@Override
public String toString() {
return NAME + " - " + LOCATION;
}
}
准备好Java对象后,我们可以读取JSON对象并加载为Java对象,如下代码所示。为了模拟真实情况,我们使用了字节流作为输入。还要注意,JSON内容保存在resource文件夹的文件里(这不是常规做法)。
输出如下:
Albert Attard - Malta
Gson解析JSON对象并创建了一个Person类的实例,并打印到命令行中。
嵌套JSON对象
让我们对上面的例子更进一步,以下所示JSON代码段包含了一个嵌套对象。
{
NAME:"Albert Attard",
P_LANGUAGE:"Java",
LOCATION:"Malta",
EXAM: {
SUBJECT:"Programming",
GRADE:4.5
}
}
EXAM域由两个域组成,分别是SUBJECT和
GRADE。我们需要修改Person类的定义来包含EXAM域,并创建一个新的Java类来表示EXAM,该类包含SUBJECT和GRADE域。
我们首先创建新的类来表示嵌套对象。就像之前讨论那样,类名无关紧要,但是域名必须与JSON中的域名匹配。
package com.javacreed.examples.gson.part3;
public class Exam {
private String SUBJECT;
private double GRADE;
// Getters and setters are not required for this example.
// GSON sets the fields directly using reflection.
@Override
public String toString() {
return SUBJECT + " - " + GRADE;
}
}
现在我们可以修改Person类,引入一个与JSON中EXAM同名的域,类型为Exam。注意,下面的Person类与前一个<span style=”color: #ff0000;”>位于</span>不同的包。
package com.javacreed.examples.gson.part3;
public class Person {
private String NAME;
private String LOCATION;
private Exam EXAM;
@Override
public String toString() {
return NAME + " - " + LOCATION + " (" + EXAM + ")";
}
}
注意,所需的变化是最小的,因为Gson动态发现(使用反射)类和它的域。本文不包含反射,对于更多关于反射的信息,请参考:Reflection in Action.
最后,让我们尝试新的变化。
package com.javacreed.examples.gson.part3;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
public class JsonToJava {
public static void main(String[] args) throws IOException {
try(Reader reader = new InputStreamReader(JsonToJava.class.getResourceAsStream("/Server2.json"), "UTF-8")){
Gson gson = new GsonBuilder().create();
Person p = gson.fromJson(reader, Person.class);
System.out.println(p);
}
}
}