阿里巴巴的FastJson数据解析介绍
本文简单介绍一下阿里巴巴的FastJson的json数据解析的简单用法。
FastJson据说是目前Json数据解析最快捷的工具,虽然传闻会有一些bug,但是基本功能还是比较完善的,没有bug。
本文介绍FastJson的基本使用方法,和几个简单的示例,还有一个非常复杂的内部类的解析示例。
如果我们使用Android原生的Json解析字符串,获取一个没有的属性就会报错,
使用FastJson来解析json字符串,把字符串标签的数据赋值给Bean对象,
即使json字符串没有Bean的某个属性,数据也不会报错,只是为”null”或0。
常识:
在json中,数据序列化,就是把数据(Bean对象)转化为json的字符串数据
如果说反序列化,就是把json数据转换成Bean对象或Json对象。
一.FastJson的基本介绍
关于FastJson的详细介绍:https://www.w3cschool.cn/fastjson/fastjson-quickstart.html
FastJson使用起来比Android原生的JsonObject方便很多,FastJson都是调用的静态方法。
1.FastJson反序列化
把json数据转换成Bean对象或Json对象
反序列化使用的方法是:
T t=JSON.parseObject(X,Y,...);
比如:
//转换为Json对象
JSONObject jsonObj = JSON.parseObject(jsonStr);
//转换为Bean对象
Model model = JSON.parseObject(jsonStr, Model.class);
2.FastJson序列化
就是根据对象,获取json字符串或者json的字节数据
使用的方法是:JSON.toJSONString(name.Class);
比如:
//根据类Model获取到对应的json字符串
Model model = ...;
String jsonStr = JSON.toJSONString(model);
//获取json字符串的字节数据
byte[] jsonBytes = JSON.toJSONBytes(model);
3.把Bean对象的数据放到输出流中
Model model = ...;
OutputStream os;
JSON.writeJSONString(os, model);
//另一种输出流
Writer writer = ...;
JSON.writeJSONString(writer, model);
当然还有很多其他的静态调用方法,可以直接进入类里面看,或者看文档的API
二.下面是FastJson的简单实用示例代码:
我是用Studio创建的Android项目,但是fastjson这个jar包在java工程中也是通用的。
注意json字符串转变为Bean对象,FastJson解析过程是支持内部类的,Gson支不支持我已经不记得了。
1.Uer类
class User{
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
2.Group类
class Group{
private int id;
private String name;
private List<User> list = new ArrayList<User>();
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<User> getList() {
return list;
}
public void setList(List<User> list) {
this.list = list;
}
}
3.weibo类
class Weibo {
private String id;
private String city;
public Weibo(String id, String city) {
this.id = id;
this.city = city;
}
public Weibo() {
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
}
4.FastJsonTest类
package com.liwenzhi.json.jsondemo;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 几个调用FastJson的方法使用
*/
public class FastJsonTest {
public static void doMain() {
json2JsonObjectM1();//将Json文本数据信息转换为JsonObject对象,然后利用键值对的方式获取信息
json2BeanM2(); //将Json文本数据转换为JavaBean数据!
json2JSONArrayM3(); //将json数据转化为JSONArray:
json2JavaBeanM4(); //将JSON文本转换为JavaBean的集合;转换为单纯的1个Object:parseObject(String text, Class<T> clazz);
bean2JsonM5(); //将JavaBean转换为Json格式的数据/Json文本 用户数据的传递:例如上传服务器
bean2JSONObjectM6();//将JavaBean转换为JSON对象
complexExampleM7(); //一个相对复杂的例子:
complex2JsonM8(); //一个复杂的Object到Json的Demo
complexMap2JsonM9();//将Map数据转换为JsonString的Demo;这个对RedBoy服务端不就直接破了嘛!
}
/**
* 将Json文本数据信息转换为JsonObject对象,然后利用键值对的方式获取信息
*/
private static void json2JsonObjectM1() {
//一个JsonObject文本数据
String s = "{\"name\":\"liuzhao\"}";//引号是需要转义的
//将JsonObject数据转换为Json
JSONObject object = JSON.parseObject(s);
//利用键值对的方式获取到值
System.out.println(object.get("name"));
/**
* 打印:
* liuzhao
*/
}
/**
* 将Json文本数据转换为JavaBean数据!
* 需要注意的是:这时候的Json文本信息中的键的名称必须和JavaBean中的字段名称一样!键中没有的在这个JavaBean中就显示为null!
*/
private static void json2BeanM2() {
String s = "{\"id\":\"0375\",\"city\":\"平顶山\"}";
//一个简单方便 的方法将Json文本信息转换为JsonObject对象的同时转换为JavaBean对象!
Weibo weibo = JSON.parseObject(s, Weibo.class);//Weibo类在下边定义
System.out.println(weibo.getId());
System.out.println(weibo.getCity());
//打印的结果 0375
// 平顶山
}
/**
* 将Map类型的数据转换为JsonString
*/
private static void complexMap2JsonM9() {
Group group = new Group();
group.setId(1);
group.setName("group");
User user1 = new User();
user1.setId(2);
user1.setName("user1");
User user2 = new User();
user2.setId(3);
user2.setName("user2");
group.getList().add(user1);
group.getList().add(user2);
Map<Integer, Object> map = new HashMap<Integer, Object>();
map.put(1, "No.1");
map.put(2, "No.2");
map.put(3, group.getList());
String jsonString = JSON.toJSONString(map);
System.out.println(jsonString);
/**
* 输出:{1:"No.1",2:"No.2",3:[{"id":2,"name":"user1"},{"id":3,"name":"user2"}]}
*/
}
/**
* 由一个复杂的Object到Json的Demo
*/
private static void complex2JsonM8() {
Group group = new Group();
group.setId(1);
group.setName("group");
User user1 = new User();
user1.setId(2);
user1.setName("user1");
User user2 = new User();
user2.setId(3);
user2.setName("user2");
group.getList().add(user1);
group.getList().add(user2);
String jsonString = JSON.toJSONString(group);
System.out.println(jsonString);
/**
* 输出:{"id":1,"list":[{"id":2,"name":"user1"},{"id":3,"name":"user2"}],"name":"group"}
*/
}
/**
* 一个相对复杂的例子:
* JSON文本数据:
* 首先是JSONObject,转换为JSONArray;
* 然后将JSONArray转换为JavaBean
*/
private static void complexExampleM7() {
String s = "{js:[{id:\"110000\",\"city\":\"北#001京市\"},{id:\"110000\",\"city\":\"北#002京市\"}"
+ ",{id:\"110000\",\"city\":\"北#002京市\"},{id:\"110000\",\"city\":\"北#002京市\"},"
+ "{id:\"110000\",\"city\":\"#006北#005京市\"},"
+ "{id:\"110000\",\"city\":\"北#002京市\"},"
+ "{id:\"110000\",\"city\":\"北#002京市\"},{id:\"120000\",\"city\":\"天#009津市\"}]}";
JSONObject object = JSON.parseObject(s);
Object jsonArray = object.get("js");
System.out.println(jsonArray);
List<Weibo> list = JSON.parseArray(jsonArray + "", Weibo.class);
for (Weibo weibo : list) {
System.out.println(weibo.getCity());
}
/**
* 打印:
* 北#001京市
* 北#002京市
* 北#002京市
* 北#002京市
* #006北#005京市
* 北#002京市
* 北#002京市
* 天#009津市
*/
}
/**
* 将JavaBean转换为JSON对象
*/
private static void bean2JSONObjectM6() {
Weibo weibo = new Weibo("0373", "洛阳");
JSONObject json = (JSONObject) JSON.toJSON(weibo);
System.out.println(json.get("id"));
/**
* 打印:
* 0373
*/
}
/**
* 将JSON文本转换为JavaBean的集合;
* 内部实现肯定是:首先转换为JSONArray,然后再转换为List集合
*/
private static void json2JavaBeanM4() {
String s = "[{\"id\":\"0375\",\"city\":\"平顶山\"},{\"id\":\"0377\",\"city\":\"南阳\"}]";
List<Weibo> list = JSON.parseArray(s, Weibo.class);
for (Weibo weibo : list) {
System.out.println(weibo.getCity());
}
/**
* 打印:
* 平顶山
* 南阳
*/
}
/**
* 将json数据转化为JSONArray:
* 注意:获取到JSONArray之后(我们这里只是获取到JSONArray而不是JavaBean的List集合)
* 获取JSONArray中的数据转换为String类型需要在外边加"";
*/
private static void json2JSONArrayM3() {
String s = "[{\"id\":\"0375\",\"city\":\"平顶山\"},{\"id\":\"0377\",\"city\":\"南阳\"}]";
//将JSON文本转换为JSONArray
JSONArray array = JSON.parseArray(s);
//这行必须写:必须加上+"";不然会报出类型强转异常!
String str = array.get(1) + "";
System.out.println(array.get(0));
JSONObject object = JSON.parseObject(str);
System.out.println(object.get("id"));
/**
* {"city":"平顶山","id":"0375"}
0377
*/
}
/**
* 将JavaBean转换为Json格式的数据/Json文本
* 用户数据的传递:例如上传服务器
*/
private static void bean2JsonM5() {
Weibo weibo = new Weibo("123456", "上海");
String string = JSON.toJSONString(weibo);
System.out.println(string);
/**
* 打印:
* {"city":"上海","id":"123456"}
*/
}
}
5.Cmd类
package com.liwenzhi.json.fastjsondemo;
import java.util.List;
/**
* 有内部类的Bean对象
*/
public class Cmd {
private String status;
private String originalText;
private String responseText;
private NlpResult nlpResult;
private String sessionState;
public String getOriginalText() {
return originalText;
}
public void setOriginalText(String originalText) {
this.originalText = originalText;
}
public NlpResult getNlpResult() {
return nlpResult;
}
public void setNlpResult(NlpResult nlpResult) {
this.nlpResult = nlpResult;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getSessionState() {
return sessionState;
}
public void setSessionState(String sessionState) {
this.sessionState = sessionState;
}
public String getResponseText() {
return responseText;
}
public void setResponseText(String responseText) {
this.responseText = responseText;
}
@Override
public String toString() {
return "Cmd{" +
"status='" + status + '\'' +
", originalText='" + originalText + '\'' +
", responseText='" + responseText + '\'' +
", nlpResult=" + nlpResult +
", sessionState='" + sessionState + '\'' +
'}';
}
class NlpResult {
private String domain;
private String state;
private Integer prefix;
private Integer suffix;
private Object object;
public String getDomain() {
return domain;
}
public void setDomain(String domain) {
this.domain = domain;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public Integer getPrefix() {
return prefix;
}
public void setPrefix(Integer prefix) {
this.prefix = prefix;
}
public Integer getSuffix() {
return suffix;
}
public void setSuffix(Integer suffix) {
this.suffix = suffix;
}
public Object getObject() {
return object;
}
public void setObject(Object object) {
this.object = object;
}
@Override
public String toString() {
return "NlpResult{" +
"domain='" + domain + '\'' +
", state='" + state + '\'' +
", prefix=" + prefix +
", suffix=" + suffix +
", object=" + object +
'}';
}
//涉及到内部类的集合
class Object {
private List<Stage> stage;
public List<Stage> getStage() {
return stage;
}
public void setStage(List<Stage> stage) {
this.stage = stage;
}
@Override
public String toString() {
return "Object{" +
"stage=" + stage +
'}';
}
class Stage {
private String message;
private String url;
private String image;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image;
}
@Override
public String toString() {
return "Stage{" +
"message='" + message + '\'' +
", url='" + url + '\'' +
", image='" + image + '\'' +
'}';
}
}
}
}
}
6.MainActivity类
package com.liwenzhi.json.fastjsondemo;
import android.content.Intent;
import android.net.Uri;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import com.alibaba.fastjson.JSONObject;
import java.util.List;
public class MainActivity extends AppCompatActivity {
String TAG = "Json MainActivity";
//双引号,需要转义
String text1 = "{\"status\":\"0\",\"originalText\":\"背首诗。\",
无家问死生,寄书长不避,况乃未休兵,\",\"sessionState\":\"01\",\"nlpResult\":{\"domain\":\"play_poem\",\"state\":\"0\",\"prefix\":0,\"suffix\":0,
\"object\":{\"stage\":[{\"message\":\"巴尼就念首《月夜忆舍弟》的古诗吧。\"},
{\"message\":\"戍鼓断人行,秋边一雁声,露从今夜白,月是故乡明,有弟皆分散,无家问死生,寄书长不避,况乃未休兵,\"},
{\"url\":\"http:\\/\\/resource.doudoubot.cn\\/download\\/audio\\/play\\/03-yueyeyishedi.mp3\",
\"image\":\"http:\\/\\/resource.doudoubot.cn\\/download\\/image\\/play\\/play_poem.jpg\"}]}}}";
String text2 = "{\"status\":\"0\",\"originalText\":\"今天天气怎么样?\",
最低气温26摄氏度,风向南风,最大风速4到5级。\",\"sessionState\":\"01\",
\"nlpResult\":{\"domain\":\"Weather-certain\",\"state\":\"0\",\"prefix\":0,\"suffix\":0,
\"object\":{\"stage\":[{\"message\":\"罗湖,2018年7月26日星期四,天气雷阵雨,当前气温28摄氏度,
最高气温32摄氏度,最低气温26摄氏度,风向南风,最大风速4到5级。\"}]}}}";
TextView tv_info;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv_info = findViewById(R.id.tv_info);
fastjson1();//非常复杂的json数据转换为Bean对象示例
}
private void fastjson1() {
StringBuffer buffer = new StringBuffer();
//把json字符串转变为Bean对象
Cmd cmd = JSONObject.parseObject(text1, Cmd.class);
buffer.append("originalText:" + cmd.getOriginalText() + "\n");
buffer.append("responseText:" + cmd.getResponseText() + "\n");
Cmd.NlpResult nlpResult = cmd.getNlpResult();
buffer.append("domain:" + nlpResult.getDomain() + "\n");
Cmd.NlpResult.Object object = nlpResult.getObject();
List<Cmd.NlpResult.Object.Stage> stages = object.getStage();
for (int i = 0; i < stages.size(); i++) {
Cmd.NlpResult.Object.Stage stage = stages.get(i);
String message = stage.getMessage();
String url = stage.getUrl();
String image = stage.getImage();
if (message != null && !message.equals("null")) {
buffer.append(i + " message:" + stage.getMessage() + "\n");
}
if (url != null && !url.equals("null")) {
buffer.append(i + " url:" + stage.getUrl() + "\n");
}
if (image != null && !image.equals("null")) {
buffer.append(i + " image:" + stage.getImage() + "\n");
}
}
tv_info.setText("cmd:\n" + buffer.toString());
Log.i("TAG","cmd:\n"+ buffer.toString());
}
}
上面如果对text1进行解析打印的数据信息是:
cmd:
originalText:背首诗。
responseText:戍鼓断人行,秋边一雁声,露从今夜白,月是故乡明,有弟皆分散,无家问死生,寄书长不避,况乃未休兵,
domain:play_poem
0 message:巴尼就念首《月夜忆舍弟》的古诗吧。
1 message:戍鼓断人行,秋边一雁声,露从今夜白,月是故乡明,有弟皆分散,无家问死生,寄书长不避,况乃未休兵,
2 url:http://resource.doudoubot.cn/download/audio/play/03-yueyeyishedi.mp3
2 image:http://resource.doudoubot.cn/download/image/play/play_poem.jpg
对text2进行解析打印的数据信息是:
cmd:
originalText:今天天气怎么样?
responseText:罗湖,2018年7月26日星期四,天气雷阵雨,当前气温28摄氏度,最高气温32摄氏度,最低气温26摄氏度,风向南风,最大风速4到5级。
domain:Weather-certain
0 message:罗湖,2018年7月26日星期四,天气雷阵雨,当前气温28摄氏度,最高气温32摄氏度,最低气温26摄氏度,风向南风,最大风速4到5级。
从这两个负责的json数据可以看出,FastJson是支持多个内部类的数据转换的。
有时候我们得到一个json字符串,但是如果比较复杂,会不知道怎么写成Bean,
这时可以使用一些软件工具,或者使用在线的转换网址:
http://www.bejson.com/json2javapojo/new/
对于复制的json字符串网址也不能做成内部类,它会帮你生成很多个类,需要自己把外部的类复制到内部就可以了。
FastJson就介绍到这里。