Json数据解析

蔡浛框架–json 数据解析

说明

JsonAnalysis是新框架封装的Json解析工具,采用双重锁单例模式设计,内部集成了Gson与FastJson两种解析方式,并使用工厂模式进行设计,默认使用Gson解析,这样设计是希望一个项目中统一使用一种解析方式,保证代码的统一性。

代码

1
2
3
4
5
libs/fastjson-1.2.4.jar
libs/gson-2.2.4.jar

//compile 'com.alibaba:fastjson:1.2.4.android'
//compile 'com.google.code.gson:gson:2.2.4'

JsonAnalysis.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
import android.support.annotation.IntRange;

import com.u1city.androidframe.utils.json.fastjson.FastJsonFactory;
import com.u1city.androidframe.utils.json.gson.GsonFactory;

import java.lang.reflect.Type;
import java.util.List;

/**
* Json解析工具双重锁单例模式
* <p>
* 工厂模式创建解析工具,内置Gson与FastJson两种
* <p>
* 默认Gson
* <p>
* 建议一个项目中统一用一种解析方式,这样能保证代码的统一性
*/
public final class JsonAnalysis implements IJson {
//单例模式->双重检查模式
private static final String TAG = "JsonAnalysis";
//volatile表示去掉虚拟机优化代码,但是会消耗少许性能,可忽略
private volatile static JsonAnalysis sInstance = null;

public static final int PARSER_TYPE_GSON = 0;
public static final int PARSER_TYPE_FAST_JSON = 1;
private int jsonType = PARSER_TYPE_GSON;

private IJson mJsonFactory = null;

/**
* 如果没设置{@link #jsonType}的话,默认使用GSON
*
* @return
*/
public static JsonAnalysis getInstance() {
if (sInstance == null) {
//同步代码块
synchronized (JsonAnalysis.class) {
if (sInstance == null) {
sInstance = new JsonAnalysis();
}
}
}
return sInstance;
}

private JsonAnalysis() {
}

/**
* 设置使用的json工具类型,mJsonFactory == null的时候有效
*
* @param jsonType PARSER_TYPE_GSON 使用gson
* PARSER_TYPE_FAST_JSON 使用fastJson
*/
public void setJsonType(@IntRange(from = 0, to = 1) int jsonType) {
this.jsonType = jsonType;
}

private IJson getJsonFactory() {
if (mJsonFactory == null) {
//说明没有设置JsonType
if (jsonType == PARSER_TYPE_GSON) {
return new GsonFactory().getJson();
} else if (jsonType == PARSER_TYPE_FAST_JSON) {
return new FastJsonFactory().getJson();
}
}
return mJsonFactory;
}

@Override
public <T> String toJson(T t) {
return getJsonFactory().toJson(t);
}

@Override
public <T> String toJson(T t, Type type) {
return getJsonFactory().toJson(t, type);
}

@Override
public String toJson(String json, String key) {
return getJsonFactory().toJsonString(json, key);
}

@Override
public <T> T fromJson(String json, Class<? extends T> clazz) {
return getJsonFactory().fromJson(json, clazz);
}

@Override
public <T> T fromJson(String json, Type type) {
return getJsonFactory().fromJson(json, type);
}

@Override
public <T> String listToJson(List<T> array) {
return getJsonFactory().listToJson(array);
}

@Override
public <T> List<T> listFromJson(String json, Class<? extends T> clazz) {
return getJsonFactory().listFromJson(json, clazz);
}
}

IJson.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
import java.lang.reflect.Type;
import java.util.List;

/**
* Json转换接口
*/
public interface IJson {

/**
* 将对象转换成json字符串
*
* @param t 转化对象
* @return json字符串
*/
<T> String toJson(T t);

/**
* 将对象转换成json字符串
*
* @param t 转化对象
* @return json字符串
*/
<T> String toJson(T t, Type type);

/**
* 取出json内的某个key下的内容
* @param json 字符串
* @param key 关键字
* @return
*/
String toJson(String json, String key);

/**
* 将json字符串转换成对象
*
* @param json 字符串
* @param clazz 类
* @return 转换得到的对象
*/
<T> T fromJson(String json, Class<? extends T> clazz);

/**
* 将json字符串转换成对象
*
* @param json 字符串
* @return 转换得到的对象
*/
<T> T fromJson(String json, Type type);

/**
* 将对象列表转换成json字符串
*
* @param array 对象列表
* @return json字符串
*/
<T> String listToJson(List<T> array);

/**
* 将json字符串转换成对象列表
*
* @param json 字符串
* @param clazz 类
* @return 对象列表
*/
<T> List<T> listFromJson(String json, Class<? extends T> clazz);
}

IJsonFactory.java

1
2
3
4
5
6
7
/**
* Json解析工厂接口
*/
public interface IJsonFactory {

IJson getJson();
}

fastjson/FastJsonFactory.java

1
2
3
4
5
6
7
8
9
/**
* FastJson解析工厂
*/
public class FastJsonFactory implements IJsonFactory {
@Override
public IJson getJson() {
return new FastJsonUtils();
}
}

fastjson/FastJsonUtils.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

import java.lang.reflect.Type;
import java.util.List;

/**
* FastJson解析实例
*
* @author caihan
* @date 2018/1/18
* @e-mail 2730045482@qq.com
* 维护者
*/
public class FastJsonUtils implements IJson {
@Override
public <T> String toJson(T t) {
return JSONObject.toJSONString(t);
}

@Override
public <T> String toJson(T t, Type type) {
return JSONObject.toJSONString(t);
}

@Override
public String toJson(String json, String key){
return JSON.parseObject(json).getString(key);
}

@Override
public <T> T fromJson(String json, Class<? extends T> clazz) {
return JSONObject.parseObject(json, clazz);
}

@Override
public <T> T fromJson(String json, Type type) {
return JSONObject.parseObject(json, type);
}

@Override
public <T> String listToJson(List<T> array) {
return JSONObject.toJSONString(array);
}

@Override
public <T> List<T> listFromJson(String json, Class<? extends T> clazz) {
return (List<T>) JSONArray.parseArray(json, clazz);
}
}

gson/GsonConvertUtils.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
import com.google.gson.FieldNamingPolicy;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.google.gson.JsonIOException;
import com.google.gson.JsonParser;
import com.google.gson.JsonSyntaxException;
import com.google.gson.internal.bind.DateTypeAdapter;
import com.google.gson.stream.JsonReader;

import java.io.Reader;
import java.lang.reflect.Type;
import java.util.Date;

/**
* OkGo中需要用到的Json解析
*/
public class GsonConvertUtils {

private static Gson create() {
return GsonConvertUtils.GsonHolder.gson;
}

private static class GsonHolder {
private static Gson gson = new Gson();
}

public static <T> T fromJson(String json, Class<T> type) throws JsonIOException, JsonSyntaxException {
return create().fromJson(json, type);
}

public static <T> T fromJson(String json, Type type) {
return create().fromJson(json, type);
}

public static <T> T fromJson(JsonReader reader, Type typeOfT) throws JsonIOException, JsonSyntaxException {
return create().fromJson(reader, typeOfT);
}

public static <T> T fromJson(Reader json, Class<T> classOfT) throws JsonSyntaxException, JsonIOException {
return create().fromJson(json, classOfT);
}

public static <T> T fromJson(Reader json, Type typeOfT) throws JsonIOException, JsonSyntaxException {
return create().fromJson(json, typeOfT);
}

public static String toJson(Object src) {
return create().toJson(src);
}

public static String toJson(Object src, Type typeOfSrc) {
return create().toJson(src, typeOfSrc);
}

public static String formatJson(String json) {
try {
JsonParser jp = new JsonParser();
JsonElement je = jp.parse(json);
return new GsonBuilder()
.setPrettyPrinting()
.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
.registerTypeAdapter(Date.class, new DateTypeAdapter())
.create().toJson(je);
} catch (Exception e) {
return json;
}
}

public static String formatJson(Object src) {
try {
JsonParser jp = new JsonParser();
JsonElement je = jp.parse(toJson(src));
return new GsonBuilder()
.setPrettyPrinting()
.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
.registerTypeAdapter(Date.class, new DateTypeAdapter())
.create().toJson(je);
} catch (Exception e) {
return e.getMessage();
}
}
}

gson/GsonFactory.java

1
2
3
4
5
6
7
8
9
/**
* Gson解析工厂
*/
public class GsonFactory implements IJsonFactory {
@Override
public IJson getJson() {
return new GsonUtils();
}
}

gson/GsonUtils.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import com.google.gson.reflect.TypeToken;

import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;

/**
* Gson解析实例
*/
public class GsonUtils implements IJson {

private static Gson create() {
return GsonUtils.GsonHolder.gson;
}

private static class GsonHolder {
private static Gson gson = new Gson();
}

@Override
public <T> String toJson(T t) {
return create().toJson(t);
}

@Override
public <T> String toJson(T t, Type type) {
return create().toJson(t, type);
}

@Override
public String toJson(String json, String key) {
return JsonParser.parseString(json).getAsJsonObject().get(key).toString();
}

@Override
public <T> T fromJson(String json, Class<? extends T> clazz) {
return create().fromJson(json, clazz);
}

@Override
public <T> T fromJson(String json, Type type) {
return create().fromJson(json, type);
}

@Override
public <T> String listToJson(List<T> array) {
return create().toJson(array, new TypeToken<List<T>>() {
}.getType());
}

@Override
public <T> List<T> listFromJson(String json, Class<? extends T> clazz) {
//FIXME 以下三种方式不知道哪种好,待测
List<T> lst = new ArrayList<T>();
JsonArray array = JsonParser.parseString(json).getAsJsonArray();
for (final JsonElement elem : array) {
lst.add(create().fromJson(elem, clazz));
}
return lst;
/*return create().fromJson(json, new TypeToken<List<T>>(){}.getType());*/

/*ParameterizedTypeImpl<T> type = new ParameterizedTypeImpl<T>(clazz);
Gson gson = new GsonBuilder().create();
return gson.fromJson(json, type);*/
}

private static class ParameterizedTypeImpl<T> implements ParameterizedType {

private final Class<T> clazz;

ParameterizedTypeImpl(Class<T> clazz) {
this.clazz = clazz;
}

@NotNull
@Override
public Type[] getActualTypeArguments() {
return new Type[]{clazz};
}

@NotNull
@Override
public Type getRawType() {
return List.class;
}

@Override
public Type getOwnerType() {
return null;
}
}
}

使用

fastjson 数据解析

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
import android.util.Log;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializeConfig;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.serializer.SimpleDateFormatSerializer;
import com.alibaba.fastjson.util.TypeUtils;
import com.blankj.utilcode.util.StringUtils;
import com.bumptech.glide.load.HttpException;

import java.util.Date;
import java.util.List;
import java.util.Map;

/**
* 说明:Json封装工具类
*
* @author shenbh
* time 2021/2/23 14:26
*/
public class JsonUtil {
private static final String tag = JsonUtil.class.getSimpleName();
private static SerializeConfig config;

static {
TypeUtils.compatibleWithJavaBean = true;
config = new SerializeConfig();
config.put(Date.class, new SimpleDateFormatSerializer("yyyy-MM-dd HH:mm:ss"));
}

private static final SerializerFeature[] features = {
// 输出空置字段
SerializerFeature.WriteMapNullValue,
// list字段如果为null,输出为[],而不是null
SerializerFeature.WriteNullListAsEmpty,
// 数值字段如果为null,输出为0,而不是null
SerializerFeature.WriteNullNumberAsZero,
// Boolean字段如果为null,输出为false,而不是null
SerializerFeature.WriteNullBooleanAsFalse,
// 字符类型字段如果为null,输出为"",而不是null
SerializerFeature.WriteNullStringAsEmpty
};

/**
* 将bean对象转化成json字符串
*
* @param obj
* @return
* @throws HttpException
*/
public static String toJson(Object obj) {
try {
return JSON.toJSONString(obj);
} catch (Exception e) {
Log.e(tag,"JsonUtil | method=toJson() | 对象转为Json字符串 Error!" + e.getMessage(), e);
}
return null;
}

/** Object TO Json String Json-lib兼容的日期输出格式 */
public static String toJSONLib(Object object) {
try {
return JSON.toJSONString(object, config, features);
} catch (Exception e) {
Log.e(tag,"JsonUtil | method=toJSONLib() | 对象转为Json字符串 Json-lib兼容的日期输出格式 Error!" + e.getMessage(), e);
}
return null;
}

/** 转换为数组 Object */
public static Object[] toArray(String text) {
try {
return toArray(text, null);
} catch (Exception e) {
Log.e(tag,"JsonUtil | method=toArray() | 将json格式的数据转换为数组 Object Error!" + e.getMessage(), e);
}
return null;
}

/** 转换为数组 (可指定类型) */
public static <T> Object[] toArray(String text, Class<T> clazz) {
try {
return JSON.parseArray(text, clazz).toArray();
} catch (Exception e) {
Log.e(tag,"JsonUtil | method=toArray() | 将json格式的数据转换为数组 (可指定类型) Error!" + e.getMessage(), e);
}
return null;
}

/** Json 转为 Jave Bean */
public static <T> T toBean(String text, Class<T> clazz) {
try {
return JSON.parseObject(text, clazz);
} catch (Exception e) {
Log.e(tag,"JsonUtil | method=toBean() | Json 转为 Jave Bean Error!" + e.getMessage(), e);
}
return null;
}

/** Json 转为 Map */
public static Map<?, ?> toMap(String json) {
try {
return JSON.parseObject(json);
} catch (Exception e) {
Log.e(tag,"JsonUtil | method=toMap() | Json 转为 Map {},{}" + e.getMessage(), e);
}
return null;
}

/** Json 转 List,Class 集合中泛型的类型,非集合本身,可json-lib兼容的日期格式 */
public static <T> List<T> toList(String text, Class<T> clazz) {
try {
return JSON.parseArray(text, clazz);
} catch (Exception e) {
Log.e(tag,"JsonUtil | method=toList() | Json 转为 List {},{}" + e.getMessage(), e);
}
return null;
}

/** 从json字符串获取指定key的字符串 */
public static Object getValueFromJson(final String json, final String key) {
try {
if (StringUtils.isEmpty(json) || StringUtils.isEmpty(key)) {
return null;
}
return JSON.parseObject(json).getString(key);
} catch (Exception e) {
Log.e(tag,"JsonUtil | method=getStringFromJson() | 从json获取指定key的字符串 Error!" + e.getMessage(), e);
}
return null;
}
}

使用

gson

自定义解析规则

背景:接口返回的字段为空的时候是String类型,不为空的时候是数组类型。使用框架自己解析会报错。

解决:使用自定义解析规则

在实体类中给字段添加

1
2
@SerializeName("接口定义的字段名称")
@JsonAdapter(RawStringJsonAdapter.class)

其中RawStringJsonAdapter是自定义解析规则

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import com.google.gson.JsonParser;
import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
import java.io.IOException;
public class RawStringJsonAdapter extends TypeAdapter<String> {

@Override
public void write(JsonWriter out, String value) throws IOException {
out.jsonValue(value);
}

@Override
public String read(JsonReader in) {
return JsonParser.parseReader(in).toString();
}
}

例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class ComRow implements Serializable {
//...
@SerializedName("companyPic")
@JsonAdapter(RawStringJsonAdapter.class)
private String companyPic;

public ArrayList<CompanyPicBean> getCompanyPic() {
if (TextUtils.isEmpty(companyPic)) {
return new ArrayList<>();
}
try {
if (companyPic.startsWith("[") && companyPic.endsWith("]")) {
return JsonAnalysis.getInstance().parseJson(companyPic, new TypeToken<ArrayList<CompanyPicBean>>() {}.getType());
} else {
return new ArrayList<>();
}
} catch (Exception e) {
e.printStackTrace();
return new ArrayList<>();
}
}
//set/get
}