因项目模块化开发的需要,网络协议层被剥离出来,成为一个单独的sdk模块,对Json解析使用的比较多。网络通讯的数据多以Json字串(json字串转字节数组,json字串加密转字节数组等),总之网络通讯数据的解析围绕着Json字串进行。如何正确高效解析Json字串是本文重点讨论的内容。
Fastjson是阿里巴巴团队开发的一款JSON解析框架(开源地址:https://github.com/alibaba/fastjson),目前最新版本jar为fastjson-1.2.61.jar,可以方便的实现json对象与JavaBean对象的转换,实现JavaBean对象与json字符串的转换,实现json对象与json字符串的转换。
JavaBean如下:
public class User {
/**
* 姓名
*/
private String mUserName;
/**
* 性别
*/
private String mSex;
public String getUserName() {
return mUserName;
}
public void setUserName(String userName) {
mUserName = userName;
}
public String getSex() {
return mSex;
}
public void setSex(String sex) {
this.mSex = sex;
}
}
Json字串与JavaBean之间的相互转换demo:
public static void main(String[] args) {
User user = new User();
user.setUserName("张三");
user.setSex("男");
//JavaBean-->JSONString 注意:JavaBean中public属性才能转换到Json字串
String jsonStr = JSON.toJSONString(user);
System.out.println("jsonStr:" + jsonStr);
//JSONString-->JavaBean 注意:如果jsonStr是一个非法的Json格式,那么下面的操作会抛出JSONException
User userBean = JSON.parseObject("{\"gender\":\"男\",\"user_name\":\"张三\"}", new TypeReference<User>() {
});
System.out.println(
"userBean:userName=" + userBean.getUserName() + " ,sex=" + userBean.getSex());
//JSONString-->JSONObject
JSONObject json = JSONObject.parseObject(jsonStr);
// 取JSONString中某个字段的值
Object obj = json.get("sex");
System.out.println("obj:" + obj);
}
运行如下:
jsonStr:{"sex":"男","userName":"张三"}
userBean:userName=张三 ,sex=男
obj:男
然而,我们项目网络sdk封装,JavaBean属性命名规范:全局属性变量以m开头的小驼峰命名格式,如Demo中代码JavaBean中姓名属性字段:mUserName,性别字段:mSex,而服务器平台不遵守该规范,使用的是另外一种规范,平台下发姓名字段:user_name,性别字段:gender。这个问题如何解决呢?
在Fastjson框架中提供注解映射功能。我们只需在我们的JavaBean做如下修改:
import com.alibaba.fastjson.annotation.JSONField;
public class User {
/**
* 姓名
*/
private String mUserName;
/**
* 性别
*/
private String mSex;
@JSONField(name = "user_name")
public String getUserName() {
return mUserName;
}
@JSONField(name = "user_name")
public void setUserName(String userName) {
mUserName = userName;
}
@JSONField(name = "gender")
public String getSex() {
return mSex;
}
@JSONField(name = "gender")
public void setSex(String sex) {
this.mSex = sex;
}
}
将上述JavaBean中属性的get set方法通过@JSONField(name = "")注解到平台协议约定的字段即可,如demo中 @JSONField(name = "user_name"), @JSONField(name = "gender")。
修改后运行结果:
jsonStr:{"gender":"男","user_name":"张三"}
userBean:userName=张三 ,sex=男
obj:null
因为服务端下发字段为gender,JsonStr中无sex字段,所以以sex取值为null。
最后,利用Fastjson需要注意的地方:
-
JavaBean-->JSONString时,只有JavaBean的属性的get方法是public修饰时,属性才会出现在JSONString中。
-
JSONString-->JavaBean时,如果JsonString是非Json格式的时候,JSON.parseObject会报JSONException;JavaBean的属性的set方法是public修饰时,转换得到的JavaBean属性才能进行赋值。
总之:在生成JavaBean的时候注意属性的get set方法必须使用public修饰,注解映射的字段是否和平台协议约定的字段是否一致。