gson 安卓 java_android gson的使用

项目中一直使用的原生解析JSONObject.

参考链接https://www.jianshu.com/p/e740196225a4#

基于Gson V2.8.5

序列化: 把Java对象转换为字节序列的过程。 eg:toJson(对象)

反序列化:把字节序列恢复为Java对象的过程。eg:fromJson("字节序列",对象)

Gson基本用法

toJson序列化.

public String toJson(Object src) {

public String toJson(Object src, Type typeOfSrc) {}

public void toJson(Object src, Appendable writer) throws JsonIOException {}

public void toJson(Object src, Type typeOfSrc, Appendable writer) throws JsonIOException {}

public void toJson(Object src, Type typeOfSrc, JsonWriter writer) throws JsonIOException {}

public String toJson(JsonElement jsonElement) {}

public void toJson(JsonElement jsonElement, Appendable writer) throws JsonIOException {}

public void toJson(JsonElement jsonElement, JsonWriter writer) throws JsonIOException {}

fromJson反序列化.

public T fromJson(String json, Class classOfT) throws JsonSyntaxException {}

public T fromJson(String json, Type typeOfT) throws JsonSyntaxException {}

public T fromJson(Reader json, Class classOfT) throws JsonSyntaxException, JsonIOException {}

public T fromJson(Reader json, Type typeOfT) throws JsonIOException, JsonSyntaxException {}

public T fromJson(JsonReader reader, Type typeOfT) throws JsonIOException, JsonSyntaxException {}

public T fromJson(JsonElement json, Class classOfT) throws JsonSyntaxException {}

public T fromJson(JsonElement json, Type typeOfT) throws JsonSyntaxException {}

基本数据类型的生成、

Gson gson=new Gson();

String jsonString=gson.toJson("java");//java

String jsonNumber=gson.toJson(2018);//2018

String jsonBoolean=gson.toJson(true);//true

POJO类的生成与解析普通java类

String jsonResponse="{

"code": 200,

"msg": "OK",

"user": [

{

"name": "cqx1",

"age": "2018",

"phone": "166...111",

"email": "183xxxx111@qq.com"

},

{

"name": "cqx2",

"age": "2018",

"phone": "166...222",

"email": "183xxxx222@qq.com"

}

]

}";

private class StudentEntity {

private String code;

@Expose

private String msg;

/**

* 此处user为json串的key,下面的userList为自己定义的别名

*/

@SerializedName("user")

private List userList;

private class UserEntity {

private String name;

private String age;

private String phone;

private String emails;

...

如果此时按照以下解析,哪怕try catch也拦截不到。

/**

* 从raw包下读取数据

* @param context

* @param rawName R.raw.cqx

* @return

*/

public static String getFileStremFromRaw(Activity context, int rawName) {

try {

InputStreamReader inputReader = new InputStreamReader(context.getResources().openRawResource(rawName));

BufferedReader bufReader = new BufferedReader(inputReader);

String line = "";

String Result = "";

while ((line = bufReader.readLine()) != null)

Result += line;

return Result;

} catch (Exception e) {

e.printStackTrace();

}

return "";

}

解析上面的报文。

private void parseJsonReponse() {

String response = FileTools.getFileStremFromRaw(this, R.raw.test);

JsonParser jsonParser = new JsonParser();

JsonObject jsonObject = jsonParser.parse(response).getAsJsonObject();

try {

//因为对应的为Object,所以这样的解析就会异常崩溃,并且拦截无用。

JsonArray jsonArray = jsonParser.parse(response).getAsJsonArray();

} catch (JsonSyntaxException e) {

e.printStackTrace();

}

String msg=jsonObject.get("msg").getAsString();

}

错误日志如下:

Caused by: java.lang.IllegalStateException: Not a JSON Array: {"code":200,"msg":"OK","user":[{"name":"cqx1","age":"2018","phone":"166...111","email":"183xxxx111@qq.com"},{"name":"cqx2","age":"2018","phone":"166...222","email":"183xxxx222@qq.com"}]}

at com.google.gson.JsonElement.getAsJsonArray(JsonElement.java:107)

at com.cc.rxjava.gson.GsonActivity.parseJsonReponse(GsonActivity.java:76)

at com.cc.rxjava.gson.GsonActivity.onCreate(GsonActivity.java:68)

at android.app.Activity.performCreate(Activity.java:6715)

然后实际开发中,后台返回的json格式可能跟我们要的不一致,如果线上的因为后台返回的数据格式而崩溃,哪怕最终查出原因是后台的问题,最终客户端还是得背锅,谁叫没有做容错处理呢。

如果服务端返回的为正确的数据解析方式:

private void parseJsonReponse() {

String response = FileTools.getFileStremFromRaw(this, R.raw.test);

StudentEntity studentEntity = new Gson().fromJson(response, StudentEntity.class);

Type type =new TypeToken(){}.getType();

StudentEntity studentEntity2 = new Gson().fromJson(response, type);

// userList = studentEntity.userList;

}

json的生成

将对象转换为字节序列的过程。toJson

Gson gson = new Gson();

UserEntity user = new UserEntity("cc","2018","1660....","183...@qq.com");

String jsonObject = gson.toJson(user);//{"age":"2018","emails":"183...@qq.com","name":"cc","phone":"1660...."}

解析Json

将字节系列转为为对象的过程。fromJson

UserEntity userEntity = gson.fromJson(jsonObject, UserEntity.class);

List list = gson.fromJson(jsonArray, new TypeToken>() {

}.getType());

数组

String[] strings = gson.fromJson(jsonArray, String[].class);

List

List stringList = gson.fromJson(jsonArray, new TypeToken>() {}.getType());

@Expose、@SerializeName注解

json解析的字段(key)的名称和类型是一一对应的,当客户端和后台使用的语言不同,二者语言命名规范不同,命名规则常常不统一的情况下,使用@Expose和@SerializeName注解。

@Expose注解:区分实体中序列号的属性,包含两个属性,deserialize(反序列化)和serialize(序列化),默认为true。使用@Expose进行序列化,如果不想被序列化也可以使用transient。

@Documented

@Retention(RetentionPolicy.RUNTIME)

@Target(ElementType.FIELD)

public @interface Expose {

/**

* If {@code true}, the field marked with this annotation is written out in the JSON while

* serializing. If {@code false}, the field marked with this annotation is skipped from the

* serialized output. Defaults to {@code true}.

* @since 1.4

*/

public boolean serialize() default true;

/**

* If {@code true}, the field marked with this annotation is deserialized from the JSON.

* If {@code false}, the field marked with this annotation is skipped during deserialization.

* Defaults to {@code true}.

* @since 1.4

*/

public boolean deserialize() default true;

}

@SerializeName注解:属性重命名

//使用这样的方式创建gson对象。

Gson gson=new Gson().newBuilder().excludeFieldsWithoutExposeAnnotation().create();

@Documented

@Retention(RetentionPolicy.RUNTIME)

@Target({ElementType.FIELD, ElementType.METHOD})

public @interface SerializedName {

/**

* @return the desired name of the field when it is serialized or deserialized

*/

String value();

/**

* @return the alternative names of the field when it is deserialized

*/

String[] alternate() default {};

}

用例

@SerializedName("email_address")

public String emailAddress;

如果存在一个key多个写法,则可以选择@SerializeName的alternate别名的选择,根据以上代码可知为一个字符串数组。

借用例子

{"name":"怪盗kidou","age":24,"emailAddress":"ikidou@example.com"}

{"name":"怪盗kidou","age":24,"email_address":"ikidou@example.com"}

{"name":"怪盗kidou","age":24,"email":"ikidou@example.com"}

作者:怪盗kidou

链接:https://www.jianshu.com/p/e740196225a4#

所以处理办法是:

@SerializedName(value = "emailAddress", alternate = {"email", "email_address"})

public String emailAddress;

多个情况同时存在时:

Gson gson = new Gson();

String json = "{\"name\":\"怪盗kidou\",\"age\":24,\"emailAddress\":\"ikidou_1@example.com\",\"email\":\"ikidou_2@example.com\",\"email_address\":\"ikidou_3@example.com\"}";

User user = gson.fromJson(json, User.class);

System.out.println(user.emailAddress); // ikidou_3@example.com

作者:怪盗kidou

链接:https://www.jianshu.com/p/e740196225a4#

补充demo

6016be95d4f9

image.png

如上图可以看到该json格式为外层JsonObject,里面有个key为rltInfo的JsonObject,rltInfo里面存在两个JsonArray的数组list.可以简易封装一下解析:

//基类

public class BaseResult {

public boolean rltFlag;

public RltInfoEntity rltInfo;

}

public class RltInfoEntity {

public String status;

public String statusDesc;

@SerializedName("taskList")

public List mGcTaskList;

//mShTaskList客户端命名规则,shTaskList为服务端返回来的json的key

@SerializedName("shTaskList")

public List mShTaskList;

}

/**

* created by cheng.qx on 2018/8/20 17:10

*/

public class XJTaskEntity {

/**

* 任务ID

*/

private String taskId;

/**

* 任务名称

*/

private String taskName;

/**

* 所属用户ID

*/

private String personId;

/**

* 所属用户名称

*/

private String personName;

/**

* 门店ID

*/

private String storeId;

/**

* 门店名称

*/

@SerializedName("orgName")

private String storeName;

/**

* 区域ID

*/

private String areaId;

/**

* 区域名称

*/

private String areaName;

/**

* 任务开始时间-天

*/

@SerializedName(value ="beginTimeStr",alternate={"submitTimeStr"})

private String taskBeginDay;

/**

* 任务开始时间-时分秒

*/

private String taskBeginHour;

/**

* 任务结束时间-天

*/

@SerializedName("endTimeStr")

private String taskEndDay;

/**

* 任务结束时间-时分秒

*/

private String taskEndHour;

在Activity中解析数据:

private void initParseToDoList() {

try {

String response = FileTools.getFileStremFromRaw(activityContext, R.raw.done_gson);

Gson gson = new Gson();

Type type = new TypeToken>() {

}.getType();

BaseResult baseResult = gson.fromJson(response, type);

if (baseResult.rltInfo.mGcTaskList != null) {

taskList.addAll(baseResult.rltInfo.mGcTaskList);

}

if (baseResult.rltInfo.mShTaskList != null) {

taskList.addAll(baseResult.rltInfo.mShTaskList);

}

mGsonAdapter.notifyDataSetChanged();

} catch (Exception e) {

e.printStackTrace();

}

}

/**

* 从raw包下读取数据

*

* @param context

* @param rawName R.raw.cqx

* @return

*/

public static String getFileStremFromRaw(Activity context, int rawName) {

try {

InputStreamReader inputReader = new InputStreamReader(context.getResources().openRawResource(rawName));

BufferedReader bufReader = new BufferedReader(inputReader);

String line = "";

String Result = "";

while ((line = bufReader.readLine()) != null)

Result += line;

return Result;

} catch (Exception e) {

e.printStackTrace();

}

return "";

}

Gson解析复杂json的数据。

JsonParse:

通过getAsJsonObject和getAsJsonArray解析成JsonObject和JsonArray。

JsonElement抽象类。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值