Gson解析--之方法使用篇一

一、前言

本篇主要是对Json字符串转换成Java对象的方法进行总结。在介绍前需要对序列化和反序列化这两个名词进行一番解释。
序列化:将Java对象转换成Json字符串。
反序列化:将JSon字符串转换成Java对象。

二、Gson的基本用法

将Json字符串转换为对应的类对象。参见如下范例:

//Json字符串
{
  "rst": 0,
  "msg": "ok",
  "data": {
    "cookie": "JSESSIONID=abcntKeuJhop56LGykfdw"
  }
}

//对应的Java类
public class JsonRootBean {

    private int rst;
    private String msg;
    private Data data;
    public void setRst(int rst) {
        this.rst = rst;
    }
    public int getRst() {
        return rst;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }
    public String getMsg() {
        return msg;
    }

    public void setData(Data data) {
        this.data = data;
    }
    public Data getData() {
        return data;
    }

}

public class Data {

    private String cookie;
    public void setCookie(String cookie) {
        this.cookie = cookie;
    }
    public String getCookie() {
        return cookie;
    }

}

//Json字符串转换成Java对象
String json = "{\n" +
                "  \"rst\": 0,\n" +
                "  \"msg\": \"ok\",\n" +
                "  \"data\": {\n" +
                "    \"cookie\": \"JSESSIONID=abcntKeuJhop56LGykfdw\"\n" +
                "  }\n" +
                "}";
JsonRootBean jsonRootBean = new Gson().fromJson(json, JsonRootBean.class);

备注 :在定义Json对应的Java对象的过程中,只需要保证变量名与Json字符串中变量名相同,类型相同即可,变量的顺序不重要,对不计划进行获取的Json字段信息,Java对象中的变量可以容忍变量的缺失。

三、注解字段的使用

@Expose: Gson字段使用@Expose注解实现字段过滤,该注解必须和com.google.gson.GsonBuilder类配合使用,如果使用com.google.gson.Gson类则不会产生任何作用。
1.@Expose(serialized = true, deserialized = true):序列化和反序列化时都生效,即序列化和反序列都会处理,和不写@Expose注解的含义等同。
2.@Expose(serialized = false, deserialized = false):序列化和反序列化都不生效,即序列化和反序列化都将被忽略。
3.@Expose(serialized = true, deserialized = false):序列化时生效,反序列化时会忽略。
4.@Expose(serialized = false, deserialized = true):反序列化时生效处理,序列化时忽略。
参考代码范例

//Json对应的Java类代码
public class User {

    @Expose(serialize = true, deserialize = true)
    private String account;

    @Expose(serialize = false, deserialize = false)
    private String password;

    @Expose(serialize = true, deserialize = false)
    private String name;

    @Expose(serialize = false, deserialize = true)
    private int age;

    public User() {}

    public User(String account, String password, String name, int age) {
        this.account = account;
        this.password = password;
        this.name = name;
        this.age = age;
    }

    public String getAccount() {
        return account;
    }

    public void setAccount(String account) {
        this.account = account;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    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;
    }

    @Override
    public String toString() {
        return "User [account=" + account + ", password=" + password + ", name=" + name + ", age=" + age + "]";
    }

}

//测试代码
public void test() throws IOException {
    Gson gson = new GsonBuilder()
        .excludeFieldsWithoutExposeAnnotation()
        .create();

    User user = new User("admin", "123456", "John", 30);
    System.out.println(gson.toJson(user));

    String userStr = "{\"account\":\"normal\",\"password\":\"xyz123\",\"name\":\"Normal\",\"age\":25}";
    User normalUser = gson.fromJson(userStr, User.class);
    System.out.println(normalUser);
}

//测试结果输出
{"account":"admin","name":"John"}
User [account=normal, password=null, name=null, age=25]

@SerializeName:重定义属性序列化后的名称,主要是为了保留前端、后台,Android,java不同的命名习惯和规则。参考如下示例:

//Json字符串
{"name":"怪盗kidou","age":24,"email_address":"[email protected]"}
//对应的Java类
public class JavaBean {
    private String name;
    private String age;
    @SerializedName("email_address")
    private String emailAddess;
    ...
}

@SerializedName附带属性alternate的使用,alternate在Gson 2.4版本之后才引入。参考如下:

//当Json字符串中存在email_address、email和emailAddress时都会被序列化成emailAddress
@SerializedName(value = "emailAddress", alternate = {"email", "email_address"})
public String emailAddress;

四、Gson中的类和方法字段

JsonParse
一个JsonParse解析类,它可以将Json字符串数据分别通过getAsJsonObject和getAsJsonArray解析成jsonObject和JsonArray。参考范例如下:

//Json字符串
{
  "muser": [
    {
      "name": "zhangsan",
      "age": "10",
      "phone": "11111",
      "email": "[email protected]"
    },
    {
      "name": "lisi",
      "age": "20",
      "phone": "22222",
      "email": "[email protected]"
    },
    ...
  ]
}
//getAsJsonObject
 JsonObject jsonObject = new JsonParser().parse(strByJson).getAsJsonObject();
//getAsJsonArray
JsonArray jsonArray = jsonObject.getAsJsonArray("muser");

JsonElement
该类是一个抽象类,代表Json串中的某一个元素,可以是JsonObject, JsonArray和JsonPrimitive等等中的任何一种。

TypeToken
通过new TypeToken< T>(){}.getTpe(); 即可获取Java类T的Type,对T与之对应的Json字符串进行反序列化,可以考虑使用在复杂Json字符串的反序列化中。参考如下示例:

//Json字符串 在代码中表示为jsonStr
{
   [
    {
      "name": "zhangsan",
      "age": "10",
      "phone": "11111",
      "email": "[email protected]"
    },
    {
      "name": "lisi",
      "age": "20",
      "phone": "22222",
      "email": "[email protected]"
    },
    ...
  ]
}

//Java类
public class JavaBean {
   public String name;
   public String age;
   public String phone;
   public String email;
}

//Json转换使用TypeToken
Gson gson = new Gson();
List<JavaBean> javaBeans =  gson().fromJson(jsonStr, new TypeToken<List<JavaBean>>() {}.getType());

JsonReader
JsonReader使用起来比较复杂,解析json和xml文件类似,都是根据节点来,使用方式参考如下:

//Json字符串
{
  "group": {
    "user": {
      "name": "张三",
      "age": "10",
      "phone": "11111",
      "email": "[email protected]"
    },
    "info": {
      "address": "北京",
      "work": "Android Dev",
      "pay": "10K",
      "motto": "先定一个小目标,比如我先赚一个亿"
    }
  }
}

//JsonReader解析使用方法
/**
 * 通过JsonReader的方式去解析
 */
private void parseComplexJArrayByReader() throws IOException {
    String strByJson = JsonToStringUtil.getStringByJson(this, R.raw.juser_4);
    JsonReader reader = new JsonReader(new StringReader(strByJson));
    try {
        reader.beginObject();
        String tagName = reader.nextName();
        if (tagName.equals("group")) {
            //读group这个节点
            readGroup(reader);
        }
        reader.endObject();
    } finally {
        reader.close();
    }
}

/**
 * 读group这个节点
 *
 * @param reader JsonReader
 */
private void readGroup(JsonReader reader) throws IOException {
    reader.beginObject();
    while (reader.hasNext()) {
        String tagName = reader.nextName();
        if (tagName.equals("user")) {
            readUser(reader);
        } else if (tagName.equals("info")) {
            readInfo(reader);
        }
    }
    reader.endObject();
}

/**
 * 读用户基本消息 user节点
 *
 * @param reader JsonReader
 */
private void readUser(JsonReader reader) throws IOException {
    reader.beginObject();
    while (reader.hasNext()) {
        String tag = reader.nextName();
        if (tag.equals("name")) {
            String name = reader.nextString();
            nameText.setText(name);
        } else if (tag.equals("age")) {
            String age = reader.nextString();
            ageText.setText(age);
        } 
        ...
        else {
            reader.skipValue();//忽略
        }
    }
    reader.endObject();
}

/**
 * 读用户其他消息 info节点
 *
 * @param reader JsonReader
 */
private void readInfo(JsonReader reader) throws IOException {
    reader.beginObject();
    while (reader.hasNext()) {
        String tag = reader.nextName();
        if (tag.equals("address")) {
            String address = reader.nextString();
            addressText.setText(address);
        } else if (tag.equals("work")) {
            String work = reader.nextString();
            workText.setText(work);
        } 
        ...
        else {
            reader.skipValue();//忽略
        }
    }
    reader.endObject();
}

参考博客
https://www.jianshu.com/p/e740196225a4
https://blog.csdn.net/Silent_Paladin/article/details/54097942
https://www.cnblogs.com/jianyungsun/p/6647203.html
https://www.cnblogs.com/cynchanpin/p/6743858.html

猜你喜欢

转载自blog.csdn.net/polo2044/article/details/80934123