欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Java的JSON转换类库GSON的基础使用教程

程序员文章站 2024-03-12 16:20:38
gson (github:https://github.com/google/gson)是 google 提供的用来在 java 对象和 json 数据之间进行映射的 ja...

gson (github:https://github.com/google/gson)是 google 提供的用来在 java 对象和 json 数据之间进行映射的 java 类库。可以将一个 json 字符串转成一个 java 对象,或者反过来。
gson里最重要的对象有2个gson 和 gsonbuilder。
gson有2个最基本的方法
(1)tojson() – 转换java 对象到json
(2)fromjson() – 转换json到java对象

编写实体类:

public class people {
  string name;
  int age;
  boolean setname;
  public string getname() {
    return name;
  }
  public void setname(string name) {
    this.name = name;
  }
  public int getage() {
    return age;
  }
  public void setage(int age) {
    this.age = age;
  }
  public boolean getsetname() {
    return setname;
  }
  public void setsetname(boolean setname) {
    this.setname = setname;
  }
  @override
  public string tostring() {
    return "name=" + name + " age=" + age + " setname=" +setname;
  }
}

编写测试类gsontest

import com.google.gson.exclusionstrategy;
import com.google.gson.fieldattributes;
import com.google.gson.gson;
import com.google.gson.gsonbuilder;
/**
 * convert java object to json.
 */
public class gsontest {
  public static void main(string[] args) {
    people p = new people();
    p.setage(20);
    p.setname("people");
    p.setsetname(true);
    gson gson = new gson();
    system.out.println(gson.tojson(p));
  }
}

输出结果:

{"name":"people","age":20,"setname":true}

这只是最简单的gson的使用。如果我们需要将bool类型的属性setname在转换成json的时候不转换,怎么实现呢?

在gson的包中找半天,发现com.google.gson包下面有这么一个接口:exclusionstrategy ,虽然不清楚是干什么的,但是根据名字,可以推断,这个接口是用来设置gson转换的排除策略的,于是在官网http://google-gson.googlecode.com/svn/trunk/gson/docs/javadocs/index.html查了一下这个接口,发现只要实现这个接口,并将实现类的对象塞给gson,在转换成json的时候,gson就会过滤掉指定的类或者属性。于是有了下面的代码:

import com.google.gson.exclusionstrategy;
import com.google.gson.fieldattributes;
import com.google.gson.gson;
import com.google.gson.gsonbuilder;
/**
 * convert java object to json, skip specific fileds.
 */
public class gsontest {
  public static void main(string[] args) {
    people p = new people();
    p.setage(20);
    p.setname("people");
    p.setsetname(true);
    exclusionstrategy excludestrategy = new setterexclusionstrategy();
    gson gson1 = new gsonbuilder()
      .setexclusionstrategies(excludestrategy)
      .create();
    gson gson2 = new gson();
    string json1 = gson1.tojson(p);
    string json2 = gson2.tojson(p);
    system.out.println(json1);
    system.out.println(json2);

    people p1 = gson1.fromjson(json1, people.class);
    people p2 = gson2.fromjson(json2, people.class);
    system.out.println(p1);
    system.out.println(p2);
  }

  private static class setterexclusionstrategy implements exclusionstrategy {
    public boolean shouldskipclass(class<?> clazz) {
      return false;
    }
    public boolean shouldskipfield(fieldattributes f) {
      return f.getname().startswith("set");
    }
  }
}

原来,gson对象的创建有两种方式:new gson()表示使用默认的配置创建一个gson对象,而如果使用gsonbuilder.create()方法创建,则可以自定义一些设置,这主要是为了使创建的gson更适合于某些特定的情况。上例中第一段蓝色的代码创建了一个gson对象,这个对象拥有对以“set”字样开头的属性的过滤的配置(如果需要过滤掉某种类型,则重写exclusionstrategy接口的shouldskipclass(class<?> clazz)方法即可,如果需要过滤掉多种情况,则可以多创建几个exclusionstrategy的实现类对象,并在创建gson对象的时候设置进去即可),因此在本例中,将people对象转换成json的时候,属性setname将被过滤掉。由于json1中没有属性setname,所以将json1反序列化成people对象的时候,boolean类型的setname就没有了值,所以打印的时候取了boolean类型的默认值。于是有了以下结果:

{"name":"people","age":20}
{"name":"people","age":20,"setname":true}
name=people age=20 setname=false
name=people age=20 setname=true

gson还支持使用注解,在com.google.gson.annotation包中,有几个注解expose, serializedname, since和until,他们各有各的作用,下面使用官方例子介绍常用的注解: 

expose:

此注解作用在属性上,表明当序列化和反序列化的时候,这个属性将会暴露给gson对象。这个注解只有当创建gson对象时使用gsonbuilder方式创建并调用了gsonbuilder.excludefieldswithoutexposeannotation() 方法的时候才有效,否则无效。下面是一个介绍@expose注解如何使用的例子:

public class user {
  @expose private string firstname;
  @expose(serialize = false) private string lastname;
  @expose (serialize = false, deserialize = false) private string emailaddress;
  private string password;
}

如果你以new gson()的方式创建gson对象,tojson()方法和fromjson() 方法在序列化和反序列化的时候将会操作这4个属性。然而,如果你使用 gson gson = new gsonbuilder().excludefieldswithoutexposeannotation().create()来创建gson对象,gson 的 tojson() 和 fromjson() 方法将会排除掉 password 字段,这是因为 password 字段没有被注解 @expose 所标记。 这个 gson 对象同样会排除 lastname 和 emailaddress 字段,因为注解@expose的属性 serialize 被设置成了 false。类似的,gson 将会在反序列化时排除掉 emailaddress 字段,因为 deserialize被设置成了 false。

serializedname:

此注解作用在属性上,表明这个属性在序列化成json的时候,需要将名字序列化成注解的value属性指定的值。

这个注解将会覆盖任何的fieldnamingpolicy, 包括默认的命名策略。下面是一个介绍@serializedname注解如何使用的例子: ,

public class someclasswithfields {
  @serializedname("name") private final string somefield;
  private final string someotherfield;
  public someclasswithfields(string a, string b) {
   this.somefield = a;
   this.someotherfield = b;
  }
}

下面的代码展示了序列化上面这个测试类的结果:

someclasswithfields objecttoserialize = new someclasswithfields("a", "b");
gson gson = new gson();
string jsonrepresentation = gson.tojson(objecttoserialize);
system.out.println(jsonrepresentation);

执行结果是:

{"name":"a","someotherfield":"b"}

由此可见,属性"somefield"已经被序列化成了"name"。

注意:在@serializedname的value中指定的属性名必须为有效的json属性名。