JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。它基于ECMAScript的一个子集。 JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C、C++、C#、Java、JavaScript、Perl、Python等)。这些特性使JSON成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成(一般用于提升网络传输速率)。
Android开发基本遵从MVC模式。由于JSON的种种优良特性,使得大部分Model都从JSON转换而来。于是把 JSON转为对应的JavaModel 就成移动端开发工作很常规的一部分。
这个工作的输入输出很明确:
输入 是一个json的字符串
{
"type":"object",
"properties": {
"foo": {
"type": "string"
},
"bar": {
"type": "integer"
},
"baz": {
"type": "boolean"
}
}
}
输出 是对应的一系列java类:
public class DataModel extends BaseModel {
private String type;
private PropertiesBean properties;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public PropertiesBean getProperties() {
return properties;
}
public void setProperties(PropertiesBean properties) {
this.properties = properties;
}
}
public static class PropertiesBean {
private FooBean foo;
private BarBean bar;
private BazBean baz;
public FooBean getFoo() {
return foo;
}
public void setFoo(FooBean foo) {
this.foo = foo;
}
public BarBean getBar() {
return bar;
}
public void setBar(BarBean bar) {
this.bar = bar;
}
public BazBean getBaz() {
return baz;
}
public void setBaz(BazBean baz) {
this.baz = baz;
}
}
public static class FooBean {
private String type;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
public static class BarBean {
private String type;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
public static class BazBean {
private String type;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
怎么完成这个转化过程呢?
转化方式一:复制粘贴、手动修正(最原始!!)
对着原始的json串,把名字复制过来,手动设置每个json项的类型。这种方式的缺点非常明显:
- 耗时长
- 人工操作太多,容易出错,万一手误把名字复制错了,后期排除错误的过程也比较麻烦。
转化方式二:使用GsonFormat智能转JSON
GsonFormat应该是Android Studio上必备插件之一,先来看效果图
效果非常的赞,而且支持过滤父类已有属性,这样就不用在继承父类后还要删除相同的属性了。它的安装和使用方法也非常简单方便,具体方式参考其github主页:https://github.com/zzz40500/GsonFormat
类似插件还有一个,叫JsonModelGenerator,其支持将类型为 JSONObject 和 JSONArray 的子元素拆分为单独的实体类。不过它用起来比较繁琐,必须透过url获取原始json串,不推荐使用。
由于GsonFormat的使用方式仅限于单个java类内,所以它解析产生的子类都是内嵌类,所以还是会需要手动调整类的继承关系。另外每个JSON串都要先新建再转JSON的时候,当JSON串比较多的时候,就会觉得这一步也挺繁琐的(程序员就是懒啊~),有没有批量转json的方式呢?
转化方式三:使用JsonAnnotation批量转JSON
JsonAnnotation利用了java annotation的特性,在Android编译时将如下格式的代码
String simpleStr = "{\n"
+ " \"id\": 100,\n"
+ " \"body\": \"It is my post\",\n"
+ " \"number\": 0.13,\n"
+ " \"created_at\": \"2014-05-22 19:12:38\"\n"
+ "}";
// 简单格式
@Json2Model(modelName = "SimpleModel", jsonStr = simpleStr)
String TEST_SIMPLE = "test/simple"; // api url
转化为test.simple包下的一个类SimpleModel,代码如下:
package test.simple;
import com.google.gson.annotations.SerializedName;
public class SimpleModel {
@SerializedName("id")
private int id;
@SerializedName("body")
private String body;
@SerializedName("created_at")
private String createdAt;
@SerializedName("number")
private double number;
public void setId(int id) {
this.id = id;
}
public void setBody(String body) {
this.body = body;
}
public void setCreatedAt(String createdAt) {
this.createdAt = createdAt;
}
public void setNumber(double number) {
this.number = number;
}
public int getId() {
return id;
}
public String getBody() {
return body;
}
public String getCreatedAt() {
return createdAt;
}
public double getNumber() {
return number;
}
}
这样就可以批量将json转成Model了,而且由于其只在编译时起作用,所以并不影响程序运行时的性能(非常棒的~)。具体使用方法参考其github主页:https://github.com/tianzhijiexian/JsonAnnotation
不过这种方式还是有不便利的地方,主要体现在两个地方:
- 没有办法指定json对应类的父类,因此如果Model之间有继承关系,需要手动处理
- 不会智能判断不同json串之间的关联关系,因此如果Model之间有组合关系,需要手动处理。
转化方式四:脱离Android Studio环境转JSON
方式三和四都基于Android Studio这个开发环境,有没有脱离这个环境直接将JSON串转成Java Model的方式呢?
有。
点开http://www.jsonschema2pojo.org/网站,可以看到如下界面:
操作很直观清晰,可以直接将JSON转为Model,而且支持预览,其产物为一系列java文件(因为内嵌的json对象会被解析为独立java类)。
类似网站有JSON To Java
注意:这两个网站都不支持批量转JSON。
以上就是目前搜集到的所有可用资源了,它们都是GitHub上的开源项目,相关地址如下:
目前最佳实践清单
从目前来,最佳方式是综合JsonAnnotation
和GsonFormat
。
- 首先利用JsonAnnotation批量生成所有的java类。
- 然后根据其中的组合、继承关系进行人工修正。
- 当遇到参数增删较多的时候,用GsonFormat进行单个操作。
PS:JsonAnnotation 这个项目真不错,如果能把继承和组合关系也解决掉,它就完美了~~
拓展阅读:
Panda
2016-07-06