Android中JSON的4种解析方式使用和对比
作者:木水Code 发布时间:2023-05-03 11:32:10
1 Android SDK自带的org.json解析
解析原理: 基于文档驱动,需要把全部文件读入到内存中,然后遍历所有数据,根据需要检索想要的数据。
相关类:
JSONObject
JSONArray
JSONTokener
public Object nextValue() throws JSONException {
int c = nextCleanInternal();
switch (c) {
case -1:
throw syntaxError("End of input");
case '{':
return readObject();
case '[':
return readArray();
case ''':
case '"':
return nextString((char) c);
default:
pos--;
return readLiteral();
}
}
JSONStringer
JSONException
以下是Android SDK自带Json解析方式的示例代码:
/**
* @Description: SDK org.json下自带的Json解析方式
* @CreateDate: 2022/3/22 10:30 上午
*/
public class OrgJsonUtil {
/**
* 生成Json
*/
public static void createJson(Context context) {
try {
File file = new File(context.getFilesDir(), "orgjson.json");
//实例化一个JSONObject
JSONObject student = new JSONObject();
//向对象中添加数据
student.put("name", "Musk");
student.put("sex", "男");
student.put("age", 50);
JSONObject course1 = new JSONObject();
course1.put("name", "数学");
course1.put("score", 98.2f);
JSONObject course2 = new JSONObject();
course2.put("name", "语文");
course2.put("score", 99);
//实例化一个JSONArray
JSONArray courses = new JSONArray();
courses.put(0, course1);
courses.put(1, course2);
student.put("courses", courses);
//写数据
FileOutputStream fos = new FileOutputStream(file);
fos.write(student.toString().getBytes());
fos.close();
Log.d("TAG", "createJson: " + student);
Toast.makeText(context, "Json创建成功", Toast.LENGTH_SHORT).show();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 解析Json
*/
public static void parseJson(Context context) {
try {
//读数据
File file = new File(context.getFilesDir(), "orgjson.json");
FileInputStream fis = new FileInputStream(file);
InputStreamReader isr = new InputStreamReader(fis);
BufferedReader br = new BufferedReader(isr);
String line;
StringBuffer sb = new StringBuffer();
while (null != (line = br.readLine())) {
sb.append(line);
}
fis.close();
isr.close();
br.close();
Student student = new Student();
JSONObject studentJsonObject = new JSONObject(sb.toString());
//获取对象
//使用optString在获取不到对应值的时候会返回空字符串"",而使用getString会异常
String name = studentJsonObject.optString("name", "");
String sex = studentJsonObject.optString("sex", "女");
int age = studentJsonObject.optInt("age", 18);
student.setName(name);
student.setSex(sex);
student.setAge(age);
//获取数组
List<Course> courses = new ArrayList<>();
JSONArray coursesJsonArray = studentJsonObject.optJSONArray("courses");
if (coursesJsonArray != null && coursesJsonArray.length() > 0) {
for (int i = 0; i < coursesJsonArray.length(); i++) {
JSONObject courseJsonObject = coursesJsonArray.optJSONObject(i);
Course course = new Course();
String courseName = courseJsonObject.optString("name", "学科");
float score = (float) courseJsonObject.optDouble("score", 0);
course.setName(courseName);
course.setScore(score);
courses.add(course);
}
}
student.setCourses(courses);
Log.d("TAG", "parseJson: " + student);
Toast.makeText(context, "Json解析成功", Toast.LENGTH_SHORT).show();
} catch (Exception e) {
e.printStackTrace();
}
}
}
2 Gson解析
解析原理: 基于事件驱动。
优势:
快速,高效
代码量少
面向对象
数据传输解析方便
可按需解析
解析流程: 根据所需取的数据 建立1个对应于JSON数据的JavaBean类,即可通过简单操作解析出所需数据。
Gson 不要求JavaBean类里面的属性一定全部和JSON数据里的所有key相同,可以按需取数据。
使用:
JSON的大括号对应一个对象
对象里面有key,value
JavaBean的类属性名 = key
JSON的中括号对应一个数组
JavaBean里面对应的也是数组
对象里可以有值/对象
若对象里面只有值,没有key,则说明是纯数组,对应JavaBean里的数组类型
若对象里面有值和key,则说明是对象数组,对应JavaBean里的内部类
对象嵌套
建立内部类 该内部类对象的名字 = 父对象的key ,类似对象数组
{
"key":"value",
"simpleArray":[
1,
2,
3
],
"arrays":[
{
"arrInnerClsKey":"arrInnerClsValue",
"arrInnerClsKeyNub":1
}
],
"innerclass":{
"name":"Musk",
"age":50,
"sex":"男"
}
}
与之对应的JavaBean:
public class JsonJavaBean {
private String key;
private List<Integer> simpleArray;
private List<ArraysBean> arrays;
private InnerclassBean innerclass;
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public List<Integer> getSimpleArray() {
return simpleArray;
}
public void setSimpleArray(List<Integer> simpleArray) {
this.simpleArray = simpleArray;
}
public List<ArraysBean> getArrays() {
return arrays;
}
public void setArrays(List<ArraysBean> arrays) {
this.arrays = arrays;
}
public InnerclassBean getInnerclass() {
return innerclass;
}
public void setInnerclass(InnerclassBean innerclass) {
this.innerclass = innerclass;
}
private static class ArraysBean {
private String arrInnerClsKey;
private int arrInnerClsKeyNub;
public String getArrInnerClsKey() {
return arrInnerClsKey;
}
public void setArrInnerClsKey(String arrInnerClsKey) {
this.arrInnerClsKey = arrInnerClsKey;
}
public int getArrInnerClsKeyNub() {
return arrInnerClsKeyNub;
}
public void setArrInnerClsKeyNub(int arrInnerClsKeyNub) {
this.arrInnerClsKeyNub = arrInnerClsKeyNub;
}
}
private static class InnerclassBean {
private String name;
private int age;
private String sex;
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;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
}
}
Gson解析示例代码:
/**
* @Description: Gson使用示例
* @CreateDate: 2022/3/22 12:51 下午
*/
public class GsonUse {
public static void main(String[] args) throws Exception {
Student student = new Student();
student.setName("John");
student.setAge(20);
student.setSex("男");
List<Course> courses = new ArrayList<>();
courses.add(new Course("语文", 99));
courses.add(new Course("地理", 59));
student.setCourses(courses);
Gson gson = new Gson();
//在项目根目录下的json文件夹下生成Jgsonjson.json文件
File file = new File("json/gsonjson.json");
FileOutputStream fos = new FileOutputStream(file);
OutputStreamWriter osw = new OutputStreamWriter(fos, "utf-8");
JsonWriter jw = new JsonWriter(osw);
gson.toJson(student, new TypeToken<Student>() {
}.getType(), jw);
jw.flush();
jw.close();
//反序列化为JavaBean
FileInputStream fis = new FileInputStream(file);
InputStreamReader isr = new InputStreamReader(fis);
JsonReader jr = new JsonReader(isr);
Student student1 = gson.fromJson(jr, new TypeToken<Student>() {
}.getType());
System.out.println(student1);
}
}
3 Jackson解析
解析原理: 基于事件驱动。
优势: 解析效率最高;在数据量大的情况优势尤为明显、占存少。
缺点: Json数据里面的所有key都有所对应,也就是必须完全解析文档,如果要按需解析的话可以拆分Json来读取,操作和解析方法复杂。
适用场景: 适用于需要处理超大型JSON文档、不需要对JSON文档进行按需解析、性能要求较高的场合。
解析过程:
类似Gson,先创建1个对应于JSON数据的JavaBean类,再通过简单操作即可解析。
与Gson解析不同的是:Gson可按需解析,即创建的JavaBean类不一定完全涵盖所要解析的JSON数据,按需创建属性;但Jackson解析对应的JavaBean必须把Json数据里面的所有key都有所对应,即必须把JSON内的数据所有解析出来,无法按需解析。
使用:
引入依赖
//Jackson
implementation 'com.fasterxml.jackson.core:jackson-databind:2.13.1'
implementation 'com.fasterxml.jackson.core:jackson-core:2.13.1'
implementation 'com.fasterxml.jackson.core:jackson-annotations:2.13.1'
/**
* @Description: Jackson使用示例
* @CreateDate: 2022/3/22 1:47 下午
*/
public class JacksonUse {
public static void main(String[] args) throws Exception {
Student student = new Student();
student.setName("Lili");
student.setSex("女");
student.setAge(26);
List<Course> courses = new ArrayList<>();
courses.add(new Course("Art", 100));
courses.add(new Course("Love", 99));
student.setCourses(courses);
ObjectMapper objectMapper = new ObjectMapper();
//序列化 生成json文件
File file = new File("json/jacksonjson.json");
FileOutputStream fos = new FileOutputStream(file);
objectMapper.writeValue(fos, student);
//反序列化 json文件转为JavaBean
Student student1 = objectMapper.readValue(file, Student.class);
System.out.println(student1);
}
}
注意:json里的key必须和JavaBean中的字段全部对应。
如果没对应,比如json中多了一个"hobby"字段,JavaBean中没有,运行就会报错:
Exception in thread "main" com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "hobby" (class site.exciter.learn.json.Student), not marked as ignorable (4 known properties: "courses", "name", "sex", "age"])
at [Source: (File); line: 3, column: 13] (through reference chain: site.exciter.learn.json.Student["hobby"])
4 Fastjson解析
特点:
快速FAST(比任何一款都快)
面向对象
功能强大(支持普通JDK类任意java bean Class,Collection,Map,Date或者enum)
零依赖(只需要有JDK即可)
支持注解,全类型序列化
使用:
引入依赖
implementation 'com.alibaba:fastjson:1.2.76'
/**
* @Description: Fastjson使用示例
* @CreateDate: 2022/3/22 2:10 下午
*/
public class FastjsonUse {
public static void main(String[] args) throws Exception {
Student student = new Student();
student.setName("Lili");
student.setSex("女");
student.setAge(26);
List<Course> courses = new ArrayList<>();
courses.add(new Course("Art", 100));
courses.add(new Course("Love", 99));
student.setCourses(courses);
//序列化 生成json
File file = new File("json/fastjson.json");
FileOutputStream fos = new FileOutputStream(file);
JSONObject.writeJSONString(fos, student);
//反序列化 json转JavaBean
FileInputStream fis = new FileInputStream(file);
Student student1 = JSONObject.parseObject(fis, Student.class);
System.out.println(student1);
}
}
来源:https://juejin.cn/post/7106318250975166477


猜你喜欢
- 思想利用栈和队列都可以实现树的迭代遍历。递归的写法将这个遍历的过程交给系统的堆栈去实现了,所以思想都是一样的、无非就是插入值的时机不一样。利
- 需求:Android调用webView加载网页的时候,拦截某一个链接不执行此链接,执行指定跳转到其他activity页面。webview的s
- 1. 参数中直接加入%%param.setUsername("%CD%"); param.set
- 效果图:这种效果的实现这里是采用自定义ExpandableListView,给它设置一个指示布局,在滑动过程中监听当前是否应该悬浮显示分类来
- 0.简介GridView 和 ListView 有共同的父类:AbsListView,因此 GridView 和 ListView 具有一定
- 不小心将.idea文件提交后无法删除1、同步git最新代码,将.idea文件同步下来如果同步不下来,看看是不是在同步的时候与本地文件产生了冲
- 本文实例讲述了Android开发之删除项目缓存的方法。分享给大家供大家参考,具体如下:如何删除项目的缓存:getCacheDir()能够得到
- stopWatch是org.springframework.util包下的一个工具类,使用它可直观的输出代码执行耗时,以及执行时间百分比,瞬
- 1:查看是否有存储卡插入String status=Environment.getExternalStorageState();if(sta
- Kotlin 支持泛型, 语法和 Java 类似。例如,泛型类:class Hello<T>(val value: T)val
- 1、CountDownLatch:一个同步工具类,它允许一个或多个线程一直等待,直到其他线程的操作执行完后再执行。2、ThreadPoolE
- 如下所示:using System.Linq;List<string> ListA = new List<string&g
- Android中Toolbar随着ScrollView滑动透明度渐变效果实现一.思路:监听ScrollView的滑动事件 不断的修改Tool
- 一、创建字符串创建字符串的方式有三种:// 方式一String str = "Hello Bit";// 方式二Stri
- 前言ConcurrentHashMap是Java 5中支持高并发、高吞吐量的线程安全HashMap实现。我们知道,ConcurrentHas
- 又是兴趣系列网上有很多自动强红包的例子和代码,笔者也是做了一些优化。先说说自己的两个个优势1.可以在聊天界面自动强不依赖于通知栏推送 2.可
- 引言本文收集了我在看Lucene源码中遇到的所有的对单值(int,long,float,double)的压缩算法,可能一种类型针对不同的场景
- 添加方法:选择项目->引用->右击“添加引用”->选择COM 找到上面组件—>点击“确定”。实现代码如下: 
- 带返回值的方法练习需求: 设计一个方法可以获取两个数的较大值,数据来自于参数思路:1. 定义一个方法,用于获取两个数中的较大数public
- 本文实例讲述了Android编程实现拍照功能的2种方法。分享给大家供大家参考,具体如下:Android系统的照相功能,已实现2种方法,可供大