常见的json解析有原生的JSONObject和JSONArray方法,谷歌的GSON库,阿里的fastjson,还有jackson,json-lib。

1、java方法解析

  • JSONObject解析json对象
  • JSONArray解析json数组

    例如json字符串为:
{
"personData": [
{
"age": 12,
"name": "nate",
"schoolInfo": [
{
"School_name": "清华"
},
{
"School_name": "北大"
}
],
"url": "http://pic.yesky.com/uploadImages/2014/345/36/E8C039MU0180.jpg"
},
{
"age": 24,
"name": "jack",
···
}
],
"result": 1
}

分析这段json数据,

  • 第一层是一个花括号括号,即jsonObect对象,然后这个对象里面有一个personData的JSONArray数组,以及一个result属性
  • 第二层personData的JSONArray数组,它里面除了属性之外,还有一个schoolInfo的JSONArray数组
  • 第三次是schoolInfo的JSONArray数组里面的JSONObject对象

解析:

public class Httpjson extends Thread {
private String url;
private Context context;
private ListView listView;
private JsonAdapter adapter;
private Handler handler; public Httpjson(String url, ListView listView, JsonAdapter adapter, Handler handler) {
super();
this.url = url;
this.listView = listView;
this.adapter = adapter;
this.handler = handler;
} @Override
public void run() {
URL httpUrl;
try {
httpUrl = new URL(url);
···
} /**
* 从网络中获取JSON字符串,然后解析
* @param json
* @return
*/
private List<Person> jsonParse(String json) {
try {
List<Person> personlist = new ArrayList<Person>();
JSONObject jsonObject = new JSONObject(json);
int result = jsonObject.getInt("result");
if (result == 1) {
JSONArray jsonArray = jsonObject.getJSONArray("personData");
for (int i = 0; i < jsonArray.length(); i++) {
Person person = new Person();
JSONObject personData = jsonArray.getJSONObject(i);
int age = personData.getInt("age");
String url = personData.getString("url");
String name = personData.getString("name");
···
JSONArray schoolInfoArray = personData.getJSONArray("schoolInfo");
for (int j = 0; j < schoolInfoArray.length(); j++) {
JSONObject schoolInfojson = schoolInfoArray.getJSONObject(j);
String schoolName = schoolInfojson.getString("School_name");
···
}
···
}
return personlist;
} else {
Toast.makeText(context, "erro", Toast.LENGTH_SHORT).show();
}
} catch (JSONException e) {
e.printStackTrace();
Log.e("JsonParseActivity", "json解析出现了问题");
} return null;
}
}

2、gson解析

(1)简介

GSON是Google提供的用来在Java对象和JSON数据之间进行映射的Java类库。可以将一个Json字符转成一个Java对象,或者将一个Java转化为Json字符串。

(2)特点

  • 快速、高效
  • 代码量少、简洁
  • 面向对象
  • 数据传递和解析方便

(3)编写bean类

要写出能让gson使用的bean类,其中的key也就是名字,如date、safe这些必须一一对应起来。其次就是在bean类中,遇到花括号就写一个class类,遇到方括号就写一个Arraylist数组。这些就是主要规则了!内部的class类写成内部内的形式。

  • 内部嵌套的类必须是static的,要不然解析会出错;
  • 类里面的属性名必须跟Json字段里面的Key是一模一样的;
  • 内部嵌套的用[]括起来的部分是一个List,所以定义为 public List b,而只用{}嵌套的就定义为 public C c,
{
"date": "2014-04-23",
···
"name": "蘑菇街",
"packageName": "com.mogujie",
"safe": [
{
"safeDes": "已通过安智市场官方认证,是正版软件",
···
},
{
"safeDes": "已通过安智市场安全检测,请放心使用",
···
},
{
"safeDes": "无任何形式的广告",
···
}
],
"screen": [
"app/com.mogujie/screen0.jpg",
···
],
"size": 6746678,
···
}
public class GsonParseMoGuBean {

    public String data;
public String name;
public String packageName;
··· public ArrayList<SafeInfo> safe; public class SafeInfo {
public String safeDes;
···
} public ArrayList<String> screen; }

(4)将json格式的字符串{}解析为java对象

Java对象

/**
* //将json格式的字符窜{}转换为java对象
*/
private void jsonToJavaObjectByGson() { //1获取或创建json数据
String json ="{\n" +
"\t\"id\":2, \"name\":\"大虾\", \n" +
"\t\"price\":12.3, \n" +
"\t\"imagePath\":\"http://192.168.10.165:8080/L05_Server/images/f1.jpg\"\n" +
"}\n"; //2解析json数据
Gson gson =new Gson(); //第一个参数是要解析的数据,第二个参数是解析生成的java对象的类
ShopInfo shopInfo = gson.fromJson(json, ShopInfo.class); }

(5)将json格式的字符串{}解析为java对象的list

private void jsonToJavaListByGson() {

        //1获取或创建json数据
String json = "[\n" +
" {\n" +
" \"id\": 1,\n" +
" \"imagePath\": \"http://192.168.10.165:8080/f1.jpg\",\n" +
" \"name\": \"大虾 1\",\n" +
" \"price\": 12.3\n" + " },\n" + " {\n" +
" \"id\": 2,\n" +
" \"imagePath\": \"http://192.168.10.165:8080/f2.jpg\",\n" +
" \"name\": \"大虾 2\",\n" +
" \"price\": 12.5\n" + " }\n" +
"]"; //2解析json数据
Gson gson =new Gson(); //List<ShopInfo>:是要返回数据的集合
List<ShopInfo> shops = gson.fromJson(json,new TypeToken<List<ShopInfo>>(){}.getType()); //3显示数据
tv_gson_orignal.setText(json); tv_gson_last.setText(shops.toString()); }

(6)将java对象转换为json字符串

private void javaToJSONByGson() {

        //1获取或创建java数据
ShopInfo shopInfo = new ShopInfo(1,"鲍鱼",250.0,"baoyu"); //2生成json数据
Gson gson = new Gson(); String json = gson.toJson(shopInfo); //3显示数据
tv_gson_orignal.setText(shopInfo.toString()); tv_gson_last.setText(json); }

(7)将java对象的list转换为json字符串[]

/**
* //将java对象的list转换为json字符窜
*/
private void javaToJSONArrayByGson() { //1获取或创建java数据
List<ShopInfo> shops =new ArrayList<ShopInfo>(); ShopInfo baoyu = new ShopInfo(1,"鲍鱼",250.0,"baoyu"); ShopInfo longxia = new ShopInfo(1,"龙虾",250.0,"longxia"); shops.add(baoyu); shops.add(longxia); //2生成json数据
Gson gson = new Gson(); String json = gson.toJson(shops); //3显示数据
tv_gson_orignal.setText(shops.toString()); tv_gson_last.setText(json);
}

3、fastjson

(1)简介

在日常的java项目开发中,JSON的使用越来越频繁,对于Json的处理工具也有很多。接下来就介绍一下阿里开源的一个高性能的JSON框架FastJson,功能完善,完全支持标准JSON库,现在已经越来越受到开发者的青睐。

(2)特点

Fastjson 是一个 Java 语言编写的高性能功能完善的 JSON 库。它采用一种“假定有序快速匹配”的算法,把JSONParse的性能提升到极致,是目前Java语言中最快的JSON库。

(4)将 json 格式的字符串{}转换为 Java 对象

private void jsonToJavaObjectByFastJson() {

// 1 获取或创建 JSON 数据
String json = "{\n" +
"\t\"id\":2, \"name\":\"大虾\", \n" +
"\t\"price\":12.3, \n" +
"\t\"imagePath\":\"http://192.168.10.165:8080/L05_Server/images/f1.jpg\ "\n" +
"}\n"; // 2 解析 JSON 数据
ShopInfo shopInfo = JSON.parseObject(json, ShopInfo.class); }

(4)将 json 格式的字符串[]转换为 Java 对象的 List

private void jsonToJavaListByFastJson() {

// 1 获取或创建 JSON 数据
String json = "[\n" +
" {\n"+
" \"id\": 1,\n" +
" \"imagePath\":
\"http://192.168.10.165:8080/f1.jpg\",\n" +
" " " " " "
\"name\": \"大虾 1\",\n" +
\"price\": 12.3\n" + },\n" +
{\n"+
\"id\": 2,\n" + \"imagePath\":
\"http://192.168.10.165:8080/f2.jpg\",\n" +
" \"name\": \"大虾 2\",\n" +
" \"price\": 12.5\n" + " }\n"+
"]"; // 2 解析 JSON 数据
List<ShopInfo> shopInfos = JSON.parseArray(json, ShopInfo.class);
}

(5)将 Java 对象转换为 json 字符串

private void javaToJsonObjectByFastJson() {
// 1 获取 Java 对象
ShopInfo shopInfo = new ShopInfo(1, "鲍鱼", 250.0, "baoyu");
// 2 生成 JSON 数据
String json = JSON.toJSONString(shopInfo);
// 3 数据显示 tv_fastjson_orignal.setText(shopInfo.toString()); tv_fastjson_last.setText(json);
}

(7)将 Java 对象的 List 转换为 json 字符串[]

private void javaToJsonArrayByFastJson() {
// 1 获取 Java 集合
List<ShopInfo> shops = new ArrayList<>();
ShopInfo baoyu = new ShopInfo(1, "鲍鱼", 250.0, "baoyu");
ShopInfo longxia = new ShopInfo(2, "龙虾", 251.0, "longxia"); shops.add(baoyu);
shops.add(longxia);
// 2 生成 JSON 数据
String json = JSON.toJSONString(shops);
// 3 数据显示 tv_fastjson_orignal.setText(shops.toString()); tv_fastjson_last.setText(json);
}

4、性能对比

选择一个合适的JSON库要从多个方面进行考虑:

  • 字符串解析成JSON性能
  • 字符串解析成JavaBean性能
  • JavaBean构造JSON性能
  • 集合构造JSON性能
  • 易用性

    编写性能测试

    接下来开始编写这四个库的性能测试代码。

(1)添加maven依赖

当然首先是添加四个库的maven依赖,公平起见,我全部使用它们最新的版本:

<!-- Json libs-->
<dependency>
<groupId>net.sf.json-lib</groupId>
<artifactId>json-lib</artifactId>
<version>2.4</version>
<classifier>jdk15</classifier>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.2</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.46</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.4</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.9.4</version>
</dependency>

(2)四个库的工具类

java FastJsonUtil.java

public class FastJsonUtil { public static String bean2Json(Object obj) { return JSON.toJSONString(obj); }

public static <T> T json2Bean(String jsonStr, Class<T> objClass) {
return JSON.parseObject(jsonStr, objClass);
}
}

java GsonUtil.java

public class GsonUtil {
private static Gson gson = new GsonBuilder().create(); public static String bean2Json(Object obj) {
return gson.toJson(obj);
} public static <T> T json2Bean(String jsonStr, Class<T> objClass) {
return gson.fromJson(jsonStr, objClass);
} public static String jsonFormatter(String uglyJsonStr) {
Gson gson = new GsonBuilder().setPrettyPrinting().create();
JsonParser jp = new JsonParser();
JsonElement je = jp.parse(uglyJsonStr);
return gson.toJson(je);
}
}

java JacksonUtil.java

public class JacksonUtil { private static ObjectMapper mapper = new ObjectMapper();

public static String bean2Json(Object obj) {
try {
return mapper.writeValueAsString(obj);
} catch (JsonProcessingException e) {
e.printStackTrace();
return null;
}
} public static <T> T json2Bean(String jsonStr, Class<T> objClass) {
try {
return mapper.readValue(jsonStr, objClass);
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
}

java JsonLibUtil.java

public class JsonLibUtil {

    public static String bean2Json(Object obj) {
JSONObject jsonObject = JSONObject.fromObject(obj);
return jsonObject.toString();
} @SuppressWarnings("unchecked")
public static <T> T json2Bean(String jsonStr, Class<T> objClass) {
return (T) JSONObject.toBean(JSONObject.fromObject(jsonStr), objClass);
}
}

(3)准备Model类

这里我写一个简单的Person类,同时属性有Date、List、Map和自定义的类FullName,最大程度模拟真实场景。

public class Person {
private String name;
private FullName fullName;
private int age;
private Date birthday;
private List<String> hobbies;
private Map<String, String> clothes;
private List<Person> friends; // getter/setter省略 @Override
public String toString() {
StringBuilder str = new StringBuilder("Person [name=" + name + ", fullName=" + fullName + ", age="
+ age + ", birthday=" + birthday + ", hobbies=" + hobbies
+ ", clothes=" + clothes + "]\n");
if (friends != null) {
str.append("Friends:\n");
for (Person f : friends) {
str.append("\t").append(f);
}
}
return str.toString();
} }
public class FullName {
private String firstName;
private String middleName;
private String lastName; public FullName() {
} public FullName(String firstName, String middleName, String lastName) {
this.firstName = firstName;
this.middleName = middleName;
this.lastName = lastName;
} // 省略getter和setter @Override
public String toString() {
return "[firstName=" + firstName + ", middleName="
+ middleName + ", lastName=" + lastName + "]";
}
}

(4)JSON序列化性能基准测试

@BenchmarkMode(Mode.SingleShotTime)
@OutputTimeUnit(TimeUnit.SECONDS)
@State(Scope.Benchmark)
public class JsonSerializeBenchmark {
/**
* 序列化次数参数
*/
@Param({"1000", "10000", "100000"})
private int count; private Person p; public static void main(String[] args) throws Exception {
Options opt = new OptionsBuilder()
.include(JsonSerializeBenchmark.class.getSimpleName())
.forks(1)
.warmupIterations(0)
.build();
Collection<RunResult> results = new Runner(opt).run();
ResultExporter.exportResult("JSON序列化性能", results, "count", "秒");
} @Benchmark
public void JsonLib() {
for (int i = 0; i < count; i++) {
JsonLibUtil.bean2Json(p);
}
} @Benchmark
public void Gson() {
for (int i = 0; i < count; i++) {
GsonUtil.bean2Json(p);
}
} @Benchmark
public void FastJson() {
for (int i = 0; i < count; i++) {
FastJsonUtil.bean2Json(p);
}
} @Benchmark
public void Jackson() {
for (int i = 0; i < count; i++) {
JacksonUtil.bean2Json(p);
}
} @Setup
public void prepare() {
List<Person> friends=new ArrayList<Person>();
friends.add(createAPerson("小明",null));
friends.add(createAPerson("Tony",null));
friends.add(createAPerson("陈小二",null));
p=createAPerson("邵同学",friends);
} @TearDown
public void shutdown() {
} private Person createAPerson(String name,List<Person> friends) {
Person newPerson=new Person();
newPerson.setName(name);
newPerson.setFullName(new FullName("zjj_first", "zjj_middle", "zjj_last"));
newPerson.setAge(24);
List<String> hobbies=new ArrayList<String>();
hobbies.add("篮球");
hobbies.add("游泳");
hobbies.add("coding");
newPerson.setHobbies(hobbies);
Map<String,String> clothes=new HashMap<String, String>();
clothes.put("coat", "Nike");
clothes.put("trousers", "adidas");
clothes.put("shoes", "安踏");
newPerson.setClothes(clothes);
newPerson.setFriends(friends);
return newPerson;
}
}

说明一下,上面的代码中

ResultExporter.exportResult("JSON序列化性能", results, "count", "秒");

这个是我自己编写的将性能测试报告数据填充至Echarts图,然后导出png图片的方法,具体代码我就不贴了,参考我的github源码。

执行后的结果图:

从上面的测试结果可以看出,序列化次数比较小的时候,Gson性能最好,当不断增加的时候到了100000,Gson明细弱于Jackson和FastJson, 这时候FastJson性能是真的牛,另外还可以看到不管数量少还是多,Jackson一直表现优异。而那个Json-lib简直就是来搞笑的。_

(5)JSON反序列化性能基准测试

@BenchmarkMode(Mode.SingleShotTime)
@OutputTimeUnit(TimeUnit.SECONDS)
@State(Scope.Benchmark)
public class JsonDeserializeBenchmark {
/**
* 反序列化次数参数
*/
@Param({"1000", "10000", "100000"})
private int count; private String jsonStr; public static void main(String[] args) throws Exception {
Options opt = new OptionsBuilder()
.include(JsonDeserializeBenchmark.class.getSimpleName())
.forks(1)
.warmupIterations(0)
.build();
Collection<RunResult> results = new Runner(opt).run();
ResultExporter.exportResult("JSON反序列化性能", results, "count", "秒");
} @Benchmark
public void JsonLib() {
for (int i = 0; i < count; i++) {
JsonLibUtil.json2Bean(jsonStr, Person.class);
}
} @Benchmark
public void Gson() {
for (int i = 0; i < count; i++) {
GsonUtil.json2Bean(jsonStr, Person.class);
}
} @Benchmark
public void FastJson() {
for (int i = 0; i < count; i++) {
FastJsonUtil.json2Bean(jsonStr, Person.class);
}
} @Benchmark
public void Jackson() {
for (int i = 0; i < count; i++) {
JacksonUtil.json2Bean(jsonStr, Person.class);
}
} @Setup
public void prepare() {
jsonStr="{\"name\":\"邵同学\",\"fullName\":{\"firstName\":\"zjj_first\",\"middleName\":\"zjj_middle\",\"lastName\":\"zjj_last\"},\"age\":24,\"birthday\":null,\"hobbies\":[\"篮球\",\"游泳\",\"coding\"],\"clothes\":{\"shoes\":\"安踏\",\"trousers\":\"adidas\",\"coat\":\"Nike\"},\"friends\":[{\"name\":\"小明\",\"fullName\":{\"firstName\":\"xxx_first\",\"middleName\":\"xxx_middle\",\"lastName\":\"xxx_last\"},\"age\":24,\"birthday\":null,\"hobbies\":[\"篮球\",\"游泳\",\"coding\"],\"clothes\":{\"shoes\":\"安踏\",\"trousers\":\"adidas\",\"coat\":\"Nike\"},\"friends\":null},{\"name\":\"Tony\",\"fullName\":{\"firstName\":\"xxx_first\",\"middleName\":\"xxx_middle\",\"lastName\":\"xxx_last\"},\"age\":24,\"birthday\":null,\"hobbies\":[\"篮球\",\"游泳\",\"coding\"],\"clothes\":{\"shoes\":\"安踏\",\"trousers\":\"adidas\",\"coat\":\"Nike\"},\"friends\":null},{\"name\":\"陈小二\",\"fullName\":{\"firstName\":\"xxx_first\",\"middleName\":\"xxx_middle\",\"lastName\":\"xxx_last\"},\"age\":24,\"birthday\":null,\"hobbies\":[\"篮球\",\"游泳\",\"coding\"],\"clothes\":{\"shoes\":\"安踏\",\"trousers\":\"adidas\",\"coat\":\"Nike\"},\"friends\":null}]}";
} @TearDown
public void shutdown() {
}
}

执行后的结果图:

从上面的测试结果可以看出,反序列化的时候,Gson、Jackson和FastJson区别不大,性能都很优异,而那个Json-lib还是来继续搞笑的。

转载声明:性能比较部分由客由熊能创作 © 飞污熊博客。

java中常见的json解析方法、库以及性能对比的更多相关文章

  1. Java中常见的json序列化类库 - Jackson

    Jackson 介绍 Jackson框架是基于Java平台的一套数据处理工具,被称为"最好的Java Json解析器". Jackson框架包含了3个核心库:streaming,d ...

  2. Java中常见几种数据库连接方法

    1:引入java.sql数据包;   import java.sql.*; 2:加载JDBC驱动程序   Class.forName(JDBC驱动包的名字).newInstance(); 3:产生Co ...

  3. Java中的static关键字解析(转自海子)__为什么main方法必须是static的,因为程序在执行main方法的时候没有创建任何对象,因此只有通过类名来访问。

    Java中的static关键字解析 static关键字是很多朋友在编写代码和阅读代码时碰到的比较难以理解的一个关键字,也是各大公司的面试官喜欢在面试时问到的知识点之一.下面就先讲述一下static关键 ...

  4. iOS中JSON解析三方库的比较

    网络数据解析框架 1.  JsonModel 一个 JSON 模型转换库,有着比较简洁的接口.Model 需要继承自 JSONModel. 2.  yyModel yyModel比较轻量(算上.h 只 ...

  5. Java中的static关键字解析

    Java中的static关键字解析 static关键字是很多朋友在编写代码和阅读代码时碰到的比较难以理解的一个关键字,也是各大公司的面试官喜欢在面试时问到的知识点之一.下面就先讲述一下static关键 ...

  6. Java中的static关键字解析 转载

    原文链接:http://www.cnblogs.com/dolphin0520/p/3799052.html Java中的static关键字解析 static关键字是很多朋友在编写代码和阅读代码时碰到 ...

  7. 【Java学习笔记之十五】Java中的static关键字解析

    Java中的static关键字解析 static关键字是很多朋友在编写代码和阅读代码时碰到的比较难以理解的一个关键字,也是各大公司的面试官喜欢在面试时问到的知识点之一.下面就先讲述一下static关键 ...

  8. 【转】Java中的static关键字解析

    一.static关键字的用途 在<Java编程思想>P86页有这样一段话: “static方法就是没有this的方法.在static方法内部不能调用非静态方法,反过来是可以的.而且可以在没 ...

  9. Java中常见的5种WEB服务器介绍

    这篇文章主要介绍了Java中常见的5种WEB服务器介绍,它们分别是Tomcat.Resin.JBoss.WebSphere.WebLogic,需要的朋友可以参考下 Web服务器是运行及发布Web应用的 ...

随机推荐

  1. case...when...和decode——oracle

    1.decode函数: 用法:decode(条件,值1,翻译1,值2,翻译2,......,缺省值): 例子: ','失败','未知') from table t1;--改变字段的显示值 ,变量1,变 ...

  2. 【数据库】Function&Procedure&Package

    Function/Procedure都是可独立编译并存储在数据库中的,区别是Function有返回值. Package则是数据和过程.函数的集合体. CREATE PROCEDURE dorepeat ...

  3. git仓库管理

    删除本地仓库当前关联的无效远程地址,再为本地仓库添加新的远程仓库地址 git remote -v //查看git对应的远程仓库地址 git remote rm origin //删除关联对应的远程仓库 ...

  4. 使用模拟器调试react-native步骤(安卓机)

    1.在cmd界面搭建react-native 环境: 可参考https://reactnative.cn/docs/0.51/getting-started.html#content (1)npm i ...

  5. android:padding和android:margin的区别 android:gravity和 android:layout_gravity 区别

    Android的Margin和Padding跟Html的是一样的.如下图所示:橙色边框(一个RelativeLayout或者LinearLayout)为例,最外层灰色为屏幕边框,黄色部分为Paddin ...

  6. [题解] LuoguP4381 [IOI2008]Island

    LuoguP4381 [IOI2008]Island Description 一句话题意:给一个基环树森林,求每棵基环树的直径长度的和(基环树的直径定义与树类似,即基环树上一条最长的简单路径),节点总 ...

  7. Spring框架之一 读取配置文件

    以下代码都是来源于官方源码(Spring-4.3.18.RELEASE),此处只是为自己以后深啃先布局出大概流程,请各看官不要浪费时间看 说明: .. 表示省略代码, // 后的如果不是源码自带则为当 ...

  8. Tensorflow学习教程------代价函数

    Tensorflow学习教程------代价函数   二次代价函数(quadratic cost): 其中,C表示代价函数,x表示样本,y表示实际值,a表示输出值,n表示样本的总数.为简单起见,使用一 ...

  9. caffe中运行mnist

    mnist样本字库嘚图片转换:# coding=utf-8import numpy as npimport struct import matplotlib.pyplot as plt from PI ...

  10. 18 12 24 html 表单学习

    html表单 表单用于搜集不同类型的用户输入,表单由不同类型的标签组成,相关标签及属性用法如下: 1.<form>标签 定义整体的表单区域 action属性 定义表单数据提交地址 meth ...