目录介绍
- 0.提问环节
- 1.基本使用
- 1.1 Gson对象创建
- 1.2 生成Json字符串
- 1.3 fromJson之Json数组转化为字符串数组
- 1.4 toJson之字符串数组转为Json数组
- 1.5 fromJson之Json数组转为List
- 1.6 toJson之List转为Json数组
- 1.7 toJson之List转为Json数组
- 1.8 fromJson之Json数组转为List
- 2.高级使用
- 2.1 序列化和反序列化
- 2.2 序列化
- 2.3 反序列化
- 2.4 字段过滤
- 2.5 属性重命名
- 2.6 个性化设置
- 2.7 TypeAdapter
- 2.8 JsonSerializer序列化接口
- 2.9 JsonDeserializer反序列化接口
- 3.0 将请求网络日志按照一定格式展示
- 3.源码分析
- 3.1 后期添加
- 4.知识拓展
关于链接
1.基本使用
1.1 Gson对象创建
- 1.1.1 直接通过new来创建对象
//通过构造函数来获取
Gson gson = new Gson();
//通过 GsonBuilder 来获取,可以进行多项特殊配置
Gson gson = new GsonBuilder().create();
- 1.1.2 通过单利方式创建全局对象
private static Gson gson = null;
static {
if (gson == null) {
gson = new GsonBuilder()
.setLenient()// json宽松
.enableComplexMapKeySerialization()//支持Map的key为复杂对象的形式
.serializeNulls() //智能null
.setPrettyPrinting()// 调教格式
.disableHtmlEscaping()
.registerTypeAdapter(int.class, new JsonDeserializer<Integer>() {//根治服务端int 返回""空字符串
@Override
public Integer deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
//try catch不影响效率
try {
return json.getAsInt();
} catch (NumberFormatException e) {
return 0;
}
}
})
.create();
}
}
public static Gson getGson() {
return gson;
}
1.2 生成Json字符串
1.2.1 代码如下所示
private void toJson() { JsonObject jsonObject = new JsonObject(); jsonObject.addProperty("String", "leavesC"); jsonObject.addProperty("Number_Integer", 23); jsonObject.addProperty("Number_Double", 22.9); jsonObject.addProperty("Boolean", true); jsonObject.addProperty("Char", 'c'); //Log.e(TAG,jsonObject.getAsString()); //这个会崩溃 Log.e(TAG,jsonObject.toString()); Log.e(TAG,jsonObject+""); //{"String":"leavesC","Number_Integer":23,"Number_Double":22.9,"Boolean":true,"Char":"c"} //{"String":"leavesC","Number_Integer":23,"Number_Double":22.9,"Boolean":true,"Char":"c"} }
1.2.2 addProperty方法
- 支持String,boolean,char,Number(包含:int,long,float,double,byte,short)
public void addProperty(String property, String value) {
add(property, createJsonElement(value));
}
public void addProperty(String property, Number value) {
add(property, createJsonElement(value));
}
public void addProperty(String property, Boolean value) {
add(property, createJsonElement(value));
}
public void addProperty(String property, Character value) {
add(property, createJsonElement(value));
}
- 1.2.3 通过 JsonObject 自己来构建一个 JsonElement
- addProperty 方法底层调用的是 add(String property, JsonElement value) 方法,即将基本数据类型转化为了 JsonElement 对象,JsonElement 是一个抽象类,而 JsonObject 继承了 JsonElement ,因此我们可以通过 JsonObject 自己来构建一个 JsonElement
//注意这个方法返回JsonElement对象
private JsonElement createJsonElement(Object value) {
return value == null ? JsonNull.INSTANCE : new JsonPrimitive(value);
}
- 1.2.4 json解析步骤
- 首先获取JSON元素数组:JSONArray jsonArray = new JSONArray(jsonData);
- 其次循环获取每个元素:JSONObject jsonObject = jsonArray.getJSONObject(index);
- 每次循环保存名称相对应的值:String name = jsonObject.getString("name");
1.3 Json数组转化为字符串数组
private void jsonToArray() {
//Json数组 转为 字符串数组
String[] arr = {"2222","3333","4444","5555"};
//這種崩潰
//String jsonArray = "{\"2222\",\"3333\",\"4444\",\"5555\"}";
//這種正常
String jsonArray = "[\"2222\",\"3333\",\"4444\",\"5555\"]";
String[] strings = gson.fromJson(jsonArray, String[].class);
System.out.println("Json数组 转为 字符串数组: ");
for (String string : strings) {
Log.e(TAG,string);
}
}
打印日志:
2222
3333
4444
5555
1.4 toJson之字符串数组转为Json数组
private void arrayToJson() {
String jsonArray = "[\"2222\",\"3333\",\"4444\",\"5555\"]";
//字符串数组 转为 Json数组
jsonArray = gson.toJson(jsonArray, new TypeToken<String>() {}.getType());
Log.e(TAG,jsonArray);
//打印日誌
//"[\"2222\",\"3333\",\"4444\",\"5555\"]"
}
1.5 fromJson之Json数组转为List
private void jsonToList() {
//Json数组 转为 List
String jsonArray = "[\"2222\",\"3333\",\"4444\",\"5555\"]";
List<String> stringList = gson.fromJson(jsonArray, new TypeToken<List<String>>() {}.getType());
for (String string : stringList) {
Log.e(TAG,string);
}
}
1.6 toJson之List转为Json数组
private void listToJson() {
String jsonArray = "[\"2222\",\"3333\",\"4444\",\"5555\"]";
List<String> stringList = gson.fromJson(jsonArray, new TypeToken<List<String>>() {}.getType());
//List 转为 Json数组
jsonArray = gson.toJson(stringList, new TypeToken<List<String>>() {}.getType());
Log.e(TAG,jsonArray);
//打印日誌
//["2222","3333","4444","5555"]
}
1.7 toJson之List转为Json数组
private void listModelToJson() {
Person model1 = new Person("yangChong", 25, true);
Person model2 = new Person("doubi", 26, false);
final ArrayList<Person> lists = new ArrayList<>();
lists.add(model1);
lists.add(model2);
Gson gson = new Gson();
String s = gson.toJson(lists);
Log.e(TAG,s);
//打印日志
//[{"age":25,"name":"yangChong","sex":true},{"age":26,"name":"doubi","sex":false}]
}
1.8 fromJson之Json数组转为List
private void jsonToListMode() {
String json = "[{\"age\":25,\"name\":\"yangChong\",\"sex\":true},{\"age\":26,\"name\":\"doubi\",\"sex\":false}]";
Gson gson = new Gson();
List<Person> list = gson.fromJson(json, new TypeToken<List<Person>>() {}.getType());
for (Person person : list) {
Log.e(TAG,person.toString());
}
//打印日志
//Person{name='yangChong', age=25, sex=true}
//Person{name='doubi', age=26, sex=false}
}
2.高级使用
2.1 序列化和反序列化
- Gson 也提供了 toJson() 和 fromJson() 两个方法用于转化 Model 与 Json,前者实现了序列化,后者实现了反序列化。
2.2 序列化
- 将model对象转变成json字符串
private void personModelToJson() {
//序列化
Person person = new Person("yangChong", 25, true);
Gson gson = new Gson();
String s = gson.toJson(person);
Log.e(TAG,s);
//打印日志
//{"age":25,"name":"yangChong","sex":true}
}
2.3 反序列化
- 将json字符串转变成model对象
private void jsonToPersonModel() {
//反序列化
String userJson = "{\"age\":25,\"name\":\"yangChong\",\"sex\":true}";
Gson gson = new Gson();
Person person = gson.fromJson(userJson, Person.class);
Log.e(TAG,person.toString());
//打印日志
//Person{name='yangChong', age=25, sex=true}
}
2.5 属性重命名
2.6 个性化设置
gson = new GsonBuilder() //builder构建者模式
.setLenient() //json宽松
.enableComplexMapKeySerialization() //支持Map的key为复杂对象的形式
.setPrettyPrinting() //格式化输出
.serializeNulls() //智能null
//.setDateFormat("yyyy-MM-dd HH:mm:ss:SSS") //格式化时间
.disableHtmlEscaping() //默认是GSON把HTML转义的
.registerTypeAdapter(int.class, new JsonDeserializer<Integer>() {
//根治服务端int 返回""空字符串
@Override
public Integer deserialize(JsonElement json, Type typeOfT,
JsonDeserializationContext context)
throws JsonParseException {
//try catch不影响效率
try {
return json.getAsInt();
} catch (NumberFormatException e) {
return 0;
}
}
})
.create();
2.7 TypeAdapter
TypeAdapter 是一个泛型抽象类,用于接管某种类型的序列化和反序列化过程,包含两个抽象方法,分别用于自定义序列化和反序列化过程
2.7.1 举个例子
- 定义 TypeAdapter 的子类 UserTypeAdapter 来接管 User 类的序列化和反序列化过程
这里设定当 User 类序列化时 Json 中的Key值都是大写字母开头,反序列化时支持“name”和“Name”两种不同的 Json 风格
public class UserTypeAdapter extends TypeAdapter<User> {
/**
* 序列化
*/
@Override
public void write(JsonWriter jsonWriter, User user) throws IOException {
//流式序列化成对象开始
jsonWriter.beginObject();
//将Json的Key值都指定为大写字母开头
jsonWriter.name("Name").value(user.getName());
jsonWriter.name("Age").value(user.getAge());
jsonWriter.name("Sex").value(user.isSex());
//流式序列化结束
jsonWriter.endObject();
}
/**
* 反序列化
*/
@Override
public User read(JsonReader jsonReader) throws IOException {
User user = new User();
//流式反序列化开始
jsonReader.beginObject();
while (jsonReader.hasNext()) {
switch (jsonReader.nextName()) {
//首字母大小写均合法
case "userName":
case "name":
case "Name":
user.setName(jsonReader.nextString());
break;
case "age":
user.setAge(jsonReader.nextInt());
break;
case "sex":
user.setSex(jsonReader.nextBoolean());
break;
}
}
//流式反序列化结束
jsonReader.endObject();
return user;
}
}
- 2.7.2 序列化和反序列化
```
#### 2.8 JsonSerializer序列化接口
/**
- 序列化过程
*/
@SuppressLint("LongLogTag")
private void toJsonSerializer() {
Gson gson = new GsonBuilder().registerTypeAdapter(User.class, new JsonSerializer() {
}).create();@Override public JsonElement serialize(User user, Type type, JsonSerializationContext jsonSerializationContext) { JsonObject jsonObject = new JsonObject(); jsonObject.addProperty("NameHi", user.getName()); jsonObject.addProperty("Sex", user.isSex()); jsonObject.addProperty("Age", user.getAge()); return jsonObject; }
User user = new User("leavesC", 24, true);
String s = gson.toJson(user);
Log.e(TAG,s);
}
```
2.9 JsonDeserializer反序列化接口
/**
* 反序列化过程
*/
private void toJsonDeserializer() {
Gson gson = new GsonBuilder().registerTypeAdapter(User.class, new JsonDeserializer<User>() {
@Override
public User deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException {
JsonObject jsonObject = jsonElement.getAsJsonObject();
String name = null;
//同时支持 userName 和 name 两种情况
if (jsonObject.has("userName")) {
name = jsonObject.get("userName").getAsString();
} else if (jsonObject.has("name")) {
name = jsonObject.get("name").getAsString();
}
int age = jsonObject.get("age").getAsInt();
boolean sex = jsonObject.get("sex").getAsBoolean();
return new User(name, age, sex);
}
}).create();
String json = "{\"userName\":\"leavesC\",\"sex\":true,\"age\":24}";
User user = gson.fromJson(json, User.class);
System.out.println();
System.out.println(user);
json = "{\"name\":\"leavesC\",\"sex\":true,\"age\":24}";
user = gson.fromJson(json, User.class);
System.out.println();
System.out.println(user);
}
3.0 将请求网络日志按照一定格式展示
private static final String LINE_SEPARATOR = System.getProperty("line.separator");
public static void printJson(String tag, String msg) {
String message;
try {
if (msg.startsWith("{")) {
JSONObject jsonObject = new JSONObject(msg);
//最重要的方法,就一行,返回格式化的json字符串,其中的数字4是缩进字符数
message = jsonObject.toString(4);
} else if (msg.startsWith("[")) {
JSONArray jsonArray = new JSONArray(msg);
message = jsonArray.toString(4);
} else {
message = msg;
}
} catch (JSONException e) {
message = msg;
}
if(isGoodJson(message)){
printLine(tag, true);
String[] lines = message.split(LINE_SEPARATOR);
for (String line : lines) {
Log.e(tag, "║ " + line);
}
printLine(tag, false);
}
}
private static void printLine(String tag, boolean isTop) {
if (isTop) {
Log.e(tag, "Http---------------------");
} else {
Log.e(tag, "Http---------------------");
}
}
private static boolean isGoodJson(String json) {
if (TextUtils.isEmpty(json)) {
return false;
}
try {
new JsonParser().parse(json);
return true;
} catch (JsonSyntaxException e) {
return false;
} catch (JsonParseException e) {
return false;
}
}
- 如图,日志格式如下所示:
关于我的博客
- 我的个人站点:www.yczbj.org,www.ycbjie.cn
- github:https://github.com/yangchong211
- 知乎:https://www.zhihu.com/people/yang-chong-69-24/pins/posts
- 简书:http://www.jianshu.com/u/b7b2c6ed9284
- csdn:http://my.csdn.net/m0_37700275
- 喜马拉雅听书:http://www.ximalaya.com/zhubo/71989305/
- 泡在网上的日子:http://www.jcodecraeer.com/member/content_list.php?channelid=1
- 邮箱:yangchong211@163.com
- 阿里云博客:https://yq.aliyun.com/users/article?spm=5176.100- 239.headeruserinfo.3.dT4bcV
- segmentfault头条:https://segmentfault.com/u/xiangjianyu/articles