java对象转json字符串工具Gson简单入门

本文介绍如何使用Gson库实现Java对象与JSON字符串之间的相互转换,包括基本使用、处理JSON对象及嵌套对象等内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

java对象转json字符串工具Gson简单入门

一、下载与安装

在使用GSON API工作之前,你需要下载库(jar文件),并将其包含到类路径中。库,连同源代码和Java文档,都可以从 http://code.google.com/p/google-gson/downloads/list下载。下载完毕后,添加gson-<version>.jar到类路径。对于那些偏好使用Maven管理依赖(JAR文件)的读者,添加如下依赖到pom.xml。

需要修改 <version>2.2.4</version>。本文所有代码示例使用上面列出的版本。pom.xml文件拷贝可以在 这里找到。

如果这个库用于web应用,请确保在WEB-INF/lib文件夹中保持一份拷贝。或者,GSON库可以放到应用服务器提供给web应用。

二、一个简单示例

GSON API提供一个类文件,Gson( Java文档),它被用来处理Java和JSON对象的转换。可以调用默认构造器,或如下代码的形式,使用GsonBuilder( Java文档)类创建这个类的实例。GsonBuilder类是可定制化的,并且允许开发者按需实例化Gson。

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

这不是火箭科学,但它是一个开始。注意,上述的结果都将输入到命令行。该toJson()方法有两个参数,Java对象转换为JSON和可追加(Java的文档)的一个实例。我们可以很容易地改变了一个文件或网络流。

import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
 public class SimpleExample2 {
    public static void main(String[] args) throws IOException {
        Writer writer = new FileWriter("Output.json");
         Gson gson = new GsonBuilder().create();
        gson.toJson("Hello", writer);
        gson.toJson(123, writer);
         writer.close();
    }
}



注意:
为什么变量声明为Writer类型,而实际类型是FileWriter?
尽量使用泛型是一个很好的方法。在上例中,我们只使用了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类时,如果不提供编码或者字符集,转换将使用平台默认字符集。这将降低代码的可移植性,且在其他平台上运行将可能产生错误行为。

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对象
比方说,我们需要使用JSON对象并加载他们为Java对象。假设web服务器查询时产生如下JSON对象:
{
  NAME:"Albert Attard",
  P_LANGUAGE:"Java",
  LOCATION:"Malta"
}

首先创建一个Java类来表示name和location。类命名为Person。类的名字无关紧要,但域的名字必须一致。域名必须匹配(大小写敏感)JSON对象中的名字。更进一步,类必须包含一个默认构造函数(即使它被设置为private)。如下所示,name和location域在JSON中是大写的。JSON中域P_LANGUAGE被忽略了,因为Java对象中不包括该名称的域。请理解域名不遵守Java命名规范,暂时只是为了简化。更多内容将在 第2部分中讨论。

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文件夹的文件里(这不是常规做法)。

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("/Server1.json"), "UTF-8")){
            Gson gson = new GsonBuilder().create();
            Person p = gson.fromJson(reader, Person.class);
            System.out.println(p);
        }
    }
}

 输出如下:
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中的域名匹配。

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>不同的包。

public class Person {
 	   private String NAME;
    private String LOCATION;
    private Exam EXAM;
     @Override
    public String toString() {
        return NAME + " - " + LOCATION + " (" + EXAM + ")";
    }
}

注意,所需的变化是最小的,因为Gson动态发现(使用反射)类和它的域。本文不包含反射,对于更多关于反射的信息,请参考: Reflection in Action.
最后,让我们尝试新的变化。

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);
        }
    }
}
JsonToJava类没有做任何改变,因为Gson使用了模型(Person和Exam类)将Json映射成Java。

五、结论

即使JSON可能是一个新概念,但它十分简单与直接。此外,相比于 需要增加标签进行消息/数据转换而不断膨胀的笨重的XML,它因为简单更加流行。需要指出 JSON是JavaScript的一个子集,JavaScript将它作为一个完美的方案来进行数据交换,例如网页。GSON API使它更便于使用,即使在这里没有讨论的部分,它也提供了强大的灵活性。

欲了解更多GSON的例子,请 移步第2部分,我们会探索更复杂的例子,并讨论如何使用GSON解串器来完全控制反序列化过程。





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值