频道栏目
首页 > 程序开发 > 移动开发 > 其他 > 正文
打造JSON的ORM解析框架
2016-09-10 09:25:18         来源:ganyao939543405的博客  
收藏   我要投稿

最近为了加速开发速度,写了不少半成品的框架。包括在Android上实现了一个简单的SpringMVC,这个可以看我前面的文章,其中一个模块就是JSON的ORM解析。

实现如下的注解关系映射

@JsonOrm  
public class UserInfoModel implements IHandler{  

    @BindTextView(R.id.text1)  
    @JsonString  
    private String name;  
    @BindTextView(R.id.text3)  
    @JsonString  
    private String pass;  
    @BindRecycleView(R.id.list)  
    @BindObj  
    @JsonSet(clazz = ItemModel.class)  
    private List obj;  

    @Override  
    public void handler() {  
        name = name+"handled";  
    }  
}  

1.首先分析JSON的数据结构

毫无疑问,JSON是一个树形结构

简单的JSON树
JSON
那么,对于树形结构我们将使用递归去遍历。
很显然我们需要根据我们的数据模型类和其上的注解构建一个树形结构,然后根据这个树形结构解析每次过来的JSON数据实例。

2.构建JSON树形结构

单个叶子节点数据结构

public class JsonMem {

    //json中对应的key
    private String key;
    //json元素类型,普通元素,JSONObject,JSONArrary,或者根结点
    private JsonObjType jsontype;
    //对应数据模型model中的类型
    private Class type;
    //对应数据模型model中的field
    private Field field;
    //子节点列表
    private List childs;

    public String getKey() {
        return key;
    }

    public void setKey(String key) {
        this.key = key;
    }

    public Class getType() {
        return type;
    }

    public void setType(Class type) {
        this.type = type;
    }

    public Field getField() {
        return field;
    }

    public void setField(Field field) {
        this.field = field;
    }

    public List getChilds() {
        return childs;
    }

    public void setChilds(List childs) {
        this.childs = childs;
    }

    public JsonObjType getJsontype() {
        return jsontype;
    }

    public void setJsontype(JsonObjType jsontype) {
        this.jsontype = jsontype;
    }
}
public enum JsonObjType {
    HEAD,
    OBJECT,
    ARRAY,
    ELEMENT
}

开始通过解析Model类构建JSON树

public class JsonParse {
    public static JsonTree establish(Class clazz){
        JsonMem headmem = new JsonMem();
        headmem.setJsontype(JsonObjType.HEAD);
        headmem.setType(clazz);
        headmem.setKey(clazz.getName());
        //开始递归建立树
        establish(headmem);
        JsonTree jsonTree = new JsonTree();
        jsonTree.setTop(headmem);
        return jsonTree;
    }

    private static void establish(JsonMem mem){
        Field[] fields = mem.getType().getDeclaredFields();
        List childs = new ArrayList<>();
        //遍历所有域
        for (Field field:fields){
            Annotation[] annotations = field.getAnnotations();
            if (annotations == null||annotations.length == 0)
                continue;
            field.setAccessible(true);
            //便利所有注解
            for (Annotation annotation:annotations){
                Class type = annotation.annotationType();
                //如果元素是JSONArray
                if (type == JsonSet.class){
                    JsonSet set = (JsonSet) annotation;
                    String key = set.name();
                    if (key.equals(""))
                        key = field.getName();
                    JsonMem jsonMem = new JsonMem();
                    jsonMem.setKey(key);
                    jsonMem.setJsontype(JsonObjType.ARRAY);
                    jsonMem.setField(field);
                    jsonMem.setType(set.clazz());
                    //判断JSONArray的item是否是普通元素还是JSONObject,这里普通元素暂时偷懒用String代替
                    //如果不是普通类型则需要递归解析
                    if (jsonMem.getType()!=String.class)
                        establish(jsonMem);
                    childs.add(jsonMem);
                    //如果元素是JsonObject
                }else if (type == JsonObject.class){
                    JsonObject jsonObject = (JsonObject) annotation;
                    String key = jsonObject.value();
                    if (key.equals(""))
                        key = field.getName();
                    JsonMem jsonMem = new JsonMem();
                    jsonMem.setKey(key);
                    jsonMem.setJsontype(JsonObjType.OBJECT);
                    jsonMem.setField(field);
                    jsonMem.setType(field.getType());
                    //递归解析
                    establish(jsonMem);
                    childs.add(jsonMem);
                }else{
                    //只是普通元素
                    JsonBase jbase = annotation.annotationType().getAnnotation(JsonBase.class);
                    if (jbase == null)
                        continue;
                    String key =  getItem(annotation);
                    if (key == null||key.equals(""))
                        key = field.getName();
                    Class valueType = jbase.value();
                    JsonMem jsonMem = new JsonMem();
                    jsonMem.setKey(key);
                    jsonMem.setJsontype(JsonObjType.ELEMENT);
                    jsonMem.setField(field);
                    jsonMem.setType(field.getType());
                    childs.add(jsonMem);
                }
            }
        }
        if (childs.size()!=0)
            mem.setChilds(childs);
    }

现在我们拿到了JsonTree对象。存储了JSON的结构和元素对应Model的关系,以及相关的反射类型。这样当json数据来的时候,我们只需要遍历这个JsonTree,然后对照其结构依次取出json里的内容即可。

3.解析json字符串实例

public static  T getValue(JsonTree tree,String json) throws Exception{
        Class clazz = tree.getTop().getType();
        T t = null;
        //反射生成一个Model对象
        t = (T) clazz.newInstance();
        //取出根结点开始遍历解析
        getValue(tree.getTop(),json,t);
        return t;
    }

    private static void getValue(JsonMem mem,String json,Object object) throws Exception {
        Field field = mem.getField();
        Class type = mem.getType();
        List childs = mem.getChilds();
        //依旧是判断元素类型
        switch (mem.getJsontype()){
            //如果是根节点
            case HEAD:
                JSONObject headobj = new JSONObject(json);
                if (childs!=null){
                    //遍历子元素
                    for (JsonMem child:childs){
                        String str = headobj.getString(child.getKey());
                        getValue(child,str,object);
                    }
                }
                break;
            case ELEMENT:
                //普通元素直接赋值
                field.set(object,json);
                break;
            //JSONObject需要递归其子元素
            case OBJECT:
                JSONObject jsonObject = new JSONObject(json);
                Object valueobj = type.newInstance();
                if (childs!=null){
                    for (JsonMem child:childs){
                        String str = jsonObject.getString(child.getKey());
                        getValue(child,str,valueobj);
                    }
                }
                field.set(object,valueobj);
                break;
            //如果是JSONArrary
            case ARRAY:
                JSONArray array = new JSONArray(json);
                if (array == null||array.length() == 0)
                    break;
                List list = new ArrayList();
                //如果item是普通元素则直接赋值
                if (type == String.class){
                    for (int i = 0;i < array.length();i++){
                        list.add(array.getString(i));
                    }
                }else {
                    //否则递归
                    for (int i = 0;i < array.length();i++){
                        Object arritem = type.newInstance();
                        JSONObject subobj = array.getJSONObject(i);
                        if (childs!=null){
                            for (JsonMem child:childs){
                                String str = subobj.getString(child.getKey());
                                getValue(child,str,arritem);
                            }
                        }
                        list.add(arritem);
                    }
                }
                field.set(object,list);
                break;
        }
    }

总的来说还是个半成品,但是基本结构已经实现,勉强也能用吧,现在还不支持json数组直接嵌套,个人比较懒。

点击复制链接 与好友分享!回本站首页
相关TAG标签 JSON ORM解析框架
上一篇:SlidingTabColors
下一篇:从零学React Native之13 持久化存储
相关文章
图文推荐
点击排行

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站