gson的使用细节

title: gson的使用细节
date: 2016-01-24 12:23:39

tags: json解析

关于json,gson是最常用到的一个库。
平常使用时我通常使用Gson gson = new Gson();的方式创建。
但是最近在使用木哥给的一个volley工具时,出现了解析不出来的情况,很是郁闷。
自己看了半天也没找到原因。所以专门再吧gson的使用方法总结一下。
Gson的api地址
Gson User Guide
google也有github page,哈哈,竟然有35页的开源项目。

new Gson()

我之前都是用的这种方式。。。
Gson有两个重要的方法,一个是toJson,一个是fromJson,也就是序列化和反序列化。
比如解析下面这个gson串:

{
    "name" : "Ravi Tamada", 
    "email" : "ravi8x@gmail.com",
    "phone" : {
        "home" : "08947 000000",
        "mobile" : "9999999999"
    }

}
先写一个User
public class User {
private String name;
private String email;
private Phone phone;}
再写一个Phone
public class Phone {
private String home;
private String mobile;}
接下来一切都简单了
Gson gson = new Gson();
User user = gson.fromJson(response.toString(), User.class);
mTextViewVolley.setText(user.getName()+"\n"+user.getEmail()+"\n"+"phone:"+user.getPhone().getHome());

gson常用的方法示例

Gson gson = new Gson();
//序列化
MyObject myobj = new MyObject();  
String jsonstr = gson .toJson(myobj);
//反序列化
MyObject myobj = gson.fromJson(jsonstr, MyObject.class);  
//序列化数组
String[] days = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
String numbersJson = gson.toJson(days);
//序列化集合
List<String> myobjs = new ArrayList<String>();
String jsonstr = gson.toJson(myobjs);
//反序列化集合数组
List<MyObject> myobjs = gson.fromJson(str, new TypeToken<ArrayList<MyObject>>(){}.getType());
// Deserialization
Type collectionType = new TypeToken<Collection<Integer>>(){}.getType();
Collection<Integer> ints2 = gson.fromJson(json, collectionType);

PS:如果需要转换的类包括泛型,那么也需要用到TypeToken,通过这个类可以获取具体的类型

注解

然而Gson并没有那么简单。他还可以使用注解:

Expose

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

publicclass 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。

PS:
如果不希望有某些属性,也可以使用transient屏蔽,如:
transient int val;

SerializedName

  用于修改属性序列化成json之后的名字。
  此注解作用在属性上,表明这个属性在序列化成Json的时候,需要将名字序列化成注解的value属性指定的值。
  这个注解将会覆盖任何的FieldNamingPolicy, 包括默认的命名策略。下面是一个介绍@SerializedName注解如何使用的例子:

publicclass SomeClassWithFields {
    @SerializedName("name") privatefinal String someField;
    private final String someOtherField;
    public SomeClassWithFields(String a, String b) {
      this.someField = a;
      this.someOtherField = b;
    }
}

序列化结果是:{“name”:”a”,”someOtherField”:”b”}

Since

使用@Since注解去维护版本,比如你有一个REST的API,并且有多个版本的JSON,如果下一个版本JSON中增加了字段,但又不希望所有的版本都在使用这些字段的话,就可以使用

publicclass Example33 {  
  publicstaticvoid main(String[] args) {  
    Gson gson = new GsonBuilder().setVersion(2.0).create();  
    String json = gson.toJson(new ExampleClass());  
    System.out.println("Output for version 2.0...");  
    System.out.println(json);  

    gson= new GsonBuilder().setVersion(1.0).create();  
    json = gson.toJson(new ExampleClass());  
    System.out.println("\nOutput for version 1.0...");  
    System.out.println(json);  

    gson= new Gson();  
    json = gson.toJson(new ExampleClass());  
    System.out.println("\nOutput for No version set...");  
    System.out.println(json);  
  }  
}  

class ExampleClass{  
  String field=  "field";  
  // this is in version 1.0  
  @Since(1.0) String newField1 = "field 1";  
  // following will be included in the version 1.1  
  @Since(2.0) String newField2 = "field 2";  
}  
输出为: 
Output for version 2.0... 
{"field":"field","newField1":"field 1","newField2":"field 2"} 
Output for version 1.0... 
{"field":"field","newField1":"field 1"} 
Output for No version set... 
{"field":"field","newField1":"field 1","newField2":"field 2"} 
Until

和Since相反,如果下一个版本JSON中删除了某个字段,就可以使用,原理同上。

GsonBulider

使用注释之后,我们创建gson就需要用到GsonBuilder
具体设置参数如下

Gson gson = new GsonBuilder()  
        .excludeFieldsWithoutExposeAnnotation() //不导出实体中没有用@Expose注解的属性  
        .enableComplexMapKeySerialization() //支持Map的key为复杂对象的形式  
        .setDateFormat("yyyy-MM-dd HH:mm:ss:SSS")//时间转化为特定格式    
        .setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE)//会把字段首字母大写,注:对于实体上使用了@SerializedName注解的不会生效.  
        .setPrettyPrinting() //对json结果格式化.  
        .setVersion(1.0)
      .disableHtmlEscaping()//默认是GSON把HTML 转义的,但也可以设置不转义
        .serializeNulls()//把null值也转换,默认是不转换null值的,可以选择也转换,为空时输出为{a:null},而不是{}
        .create();

泛型

如果需要转换的类包括泛型,那么也需要用到TypeToken,通过这个类可以获取具体的类型

publicclass ApiResult<T> {
    privateint ret;
    private String msg;
    private T data;
    publicint getRet() {
        return ret;
    }
  publicvoid setRet(int ret) {
        this.ret = ret;
    }
  public String getMsg() {
        return msg;
    }
  publicvoid setMsg(String msg) {
        this.msg = msg;
    }
  public T getData() {
        return data;
    }
  publicvoid setData(T data) {
        this.data = data;
    }
}
ApiResult<UserInfo> r = GsonUtils.parse(json, new TypeToken<ApiResult<UserInfo>>() {}.getType());

解析JsonArray

以前不知道Gson可以解析JsonArray.所以使用了如下方法,想想真是无知

public static <T> List<T> readJsonArray(JSONArray array, Class<T> entityType){
        Gson gson =new Gson();
        List<T> list = new ArrayList<>();
        for(int i=0;i<array.length();i++){
            try {
                T t = gson.fromJson(array.getJSONObject(i).toString(),entityType);
                list.add(t);
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
        return list;
    }

以下是gson user guideu中的内容:
Array Examples

Gson gson = new Gson();
int[] ints = {1, 2, 3, 4, 5};
String[] strings = {"abc", "def", "ghi"};

// Serialization
gson.toJson(ints);     // ==> [1,2,3,4,5]
gson.toJson(strings);  // ==> ["abc", "def", "ghi"]

// Deserialization
int[] ints2 = gson.fromJson("[1,2,3,4,5]", int[].class); 
// ==> ints2 will be same as ints
We also support multi-dimensional arrays, with arbitrarily complex element types.

Collections Examples

Gson gson = new Gson();
Collection<Integer> ints = Lists.immutableList(1,2,3,4,5);

// Serialization
String json = gson.toJson(ints);  // ==> json is [1,2,3,4,5]

// Deserialization
Type collectionType = new TypeToken<Collection<Integer>>(){}.getType();
Collection<Integer> ints2 = gson.fromJson(json, collectionType);
// ==> ints2 is same as ints

Fairly hideous: note how we define the type of collection. Unfortunately, there is no way to get around this in Java.

Collections Limitations

Can serialize collection of arbitrary objects but can not deserialize from it
Because there is no way for the user to indicate the type of the resulting object
While deserializing, Collection must be of a specific generic type
All of this makes sense, and is rarely a problem when following good Java coding practices.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,这是一个比较具体的问题,我会尽力回答,但是需要您提供更多的细节来让我更详细地回答。 首先,您需要将三个Json文件读入您的安卓应用程序中。您可以使用GSON库来解析JSON数据,GSON是一个开源的Java库,用于将Java对象转换为JSON格式,并将JSON格式转换为Java对象。 在您的应用程序中,您需要添加以下依赖项到您的build.gradle文件中: ``` dependencies { implementation 'com.google.code.gson:gson:2.8.6' implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0' } ``` 这将使您的应用程序能够使用GSON和MPAndroidChart库。 接下来,您需要编写代码来读取Json文件并将其转换为Java对象。您可以使用以下代码来读取Json文件: ``` String json = null; try { InputStream is = getAssets().open("your_file.json"); int size = is.available(); byte[] buffer = new byte[size]; is.read(buffer); is.close(); json = new String(buffer, "UTF-8"); } catch (IOException ex) { ex.printStackTrace(); } Gson gson = new Gson(); YourObject yourObject = gson.fromJson(json, YourObject.class); ``` 这将从assets文件夹中读取名为"your_file.json"的Json文件,并将其转换为您的Java对象。您需要重复这个过程来读取三个Json文件,并将它们转换为三个Java对象。 接下来,您需要使用MPAndroidChart库来绘制多线图。您可以使用以下代码来创建一个多线图: ``` LineChart chart = findViewById(R.id.chart); List<Entry> temperatureEntries = new ArrayList<>(); List<Entry> humidityEntries = new ArrayList<>(); List<Entry> smokeEntries = new ArrayList<>(); for (int i = 0; i < yourObject.getTemperature().size(); i++) { temperatureEntries.add(new Entry(i, yourObject.getTemperature().get(i))); humidityEntries.add(new Entry(i, yourObject.getHumidity().get(i))); smokeEntries.add(new Entry(i, yourObject.getSmoke().get(i))); } LineDataSet temperatureDataSet = new LineDataSet(temperatureEntries, "Temperature"); LineDataSet humidityDataSet = new LineDataSet(humidityEntries, "Humidity"); LineDataSet smokeDataSet = new LineDataSet(smokeEntries, "Smoke"); LineData lineData = new LineData(); lineData.addDataSet(temperatureDataSet); lineData.addDataSet(humidityDataSet); lineData.addDataSet(smokeDataSet); chart.setData(lineData); chart.invalidate(); ``` 这将创建一个LineChart对象,并将三个数据集添加到图表中。每个数据集都有一个名称,可以在图例中显示。最后,将图表数据设置为LineData对象,并刷新图表。 希望这些代码可以帮助您创建一个多线图,并使用GSON库读取Json文件。请注意,这只是一个基本的示例,您需要根据您的实际需求进行更改。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值