zoukankan      html  css  js  c++  java
  • json 转 javaBean

    前言:经常在网络上看见一些关于json自动转换成javaBean的jar包,项目组里的人也在用,稍稍研究了下,都是用的反射来做的。我细细想了下里面的逻辑,我觉得直接生成JavaBean代码岂不是更加直接,反射在移动端,怎么说都是消耗资源的。

    Java Bean 类的结构

    首先要梳理下,到底Bean类是一个什么样的文件,很简单的是有很多属性的class文件,属性有很多类别,但是从json的角度来看,类别又是有限的:基本类型和List。我们可以用python来模拟下:

    # encoding: utf-8
    '''
    Created on 2014.12.24
    
    @author: 13051041
    '''
    
    class JavaClass(object):
        '''
        class templete
        '''
        def __init__(self, name):
            '''
            Constructor
            '''
            self.mName = name;
            self.mIntegerList = []
            self.mStrList = []
            self.mBolList = []
            self.mListList = []
            self.mClassList = []
            self.mInClassTypeList = []
            self.mIsParcelable = True
            self.mPackageName = "package com.codegenerator;"
        
        def addIntAttribute(self, str1):
            '''
            add String attribute
            '''
            self.mIntegerList.append(str1)
        
        def addUnicodeAttribute(self, str1):
            '''
            add String attribute
            '''
            self.mStrList.append(str1)
             
        
        def addBooleanAttribute(self, bol):
            '''
            add Boolean attribute
            '''
            self.mBolList.append(bol)
             
        
        def addListAttribute(self, list1):
            '''
            add List attribute
            '''
            self.mListList.append(list1)
             
        
        def addClassAttribute(self, cls):
            '''
            add Class attribute
            '''
            self.mClassList.append(cls)
             
        
        def addInClassType(self, inClass):
            '''
            add Inner Class attribute
            '''
            self.mInClassTypeList.append(inClass)
             
    
        def test(self):
            print "-----this is JavaClass information start-----"
            print "class's name is %s" % self.mName
            print "class's integer is %s " % self.mIntegerList
            print "class's String is %s " % self.mStrList
            print "class's Boolean is %s " % self.mBolList
            print "class's List is %s " % self.mListList
            print "class's inner class is %s " % self.mClassList
            print "class's inner class type is %s " % self.mInClassTypeList
            print "-----this is JavaClass information end-----"
    
    classNum = 0   
    def autoGeneratorClassName():
        global classNum
        classNum = classNum + 1
        return "class%d" % classNum
    
    def buildJavaClassNode(jsonObject, className):
        javaclass = JavaClass(className)
        keys = jsonObject.keys()
        for key in keys:
            t = type(jsonObject[key])
            if t == int:
                javaclass.addIntAttribute(key)
            if t == unicode:
                javaclass.addUnicodeAttribute(key)
            if t == bool:
                javaclass.addBooleanAttribute(key)
            if t == dict:
                newClassName = autoGeneratorClassName() 
                javaclass.addClassAttribute((newClassName, key))
                javaclass.addInClassType(buildJavaClassNode(jsonObject[key], newClassName))
            if t == list:
                t2 = type(jsonObject[key][0])
                if t2 == dict:
                    newClassName = autoGeneratorClassName() 
                    javaclass.addListAttribute((newClassName, key))
                    javaclass.addInClassType(buildJavaClassNode(jsonObject[key][0], newClassName))
                else:
                    javaclass.addListAttribute((t2, key))
                
    
        return javaclass
    

      

    生成java文件,递归才是王道

    我们一个叫javaclass的python类了,用python读取json,直接生成实例。现在的任务是把这个实例,写到文件里面。想想class的嵌套关系,生成最好的方法就是递归:

    # encoding: utf-8
    '''
    Created on 2014.12.26
    
    @author: 13051041
    '''
    
    Class_import = '''
    %s
    
    import java.util.ArrayList;
    import java.util.List;
    import org.json.JSONArray;
    import org.json.JSONObject;
    import org.json.JSONException;
    '''
    
    Class_import_parcelable = '''
    import android.os.Parcel;
    import android.os.Parcelable;
    '''
    
    Class_HEAD = '''
    public %s class %s { 
    '''
    
    Class_HEAD_parcelable = '''
    public %s class %s implements Parcelable{
        public %s() {
          }
           
        public  %s(Parcel in) {
        readFromParcel(in);
        }  
    '''
    
    Class_Method_END = "}
    "
    
    Attribute_TEMP = "public %s %s;
    "
    
    Method_Analyzer = '''
        public void analyzerJson(JSONObject jsonObject) throws JSONException {
            if(jsonObject == null){
                return;
            }
    '''
    
    
    Method_TEMP = "public %s %s(%s)throws JSONException {
    "
    Method_GET_INT = '''%s = GetJsonAttributeUtil.getInt(jsonObject, "%s");'''
    Method_GET_String = '''%s = GetJsonAttributeUtil.getString(jsonObject,"%s");'''
    Method_GET_Boolean = '''%s = GetJsonAttributeUtil.getBoolean(jsonObject,"%s");'''
    Method_GET_CLASS = '''%s = new %s();
                          %s.analyzerJson(GetJsonAttributeUtil.getJSONObject(jsonObject,"%s"));'''
    Method_GET_List = '''
        %s= new ArrayList<%s>();
        JSONArray array%s = GetJsonAttributeUtil.getJSONArray(jsonObject,"%s");
        int %sLen = array%s.length();
        for(int i = 0;i<%sLen;i++){
             %s item = new %s();
             item.analyzerJson(array%s.getJSONObject(i));
             %s.add(item);
        }
    '''
    
    Method_Parcelable_Write = '''public void writeToParcel(Parcel dest, int flags) {
     '''
    Mehtod_Parcelable_Value_Write = "dest.write%s(%s);
    "
    Method_Parcelable_Read = '''public void readFromParcel(Parcel in) {
     '''
    Mehtod_Parcelable_Value_Read = "%s= in.readString();  "
    
    
    IS_PARCELABLE = True
    FILE_NAME = "Bean"
    
    def writeParcelabelMethod(f, jcls):
        # writeToParcel method
        f.write(Method_Parcelable_Write)
        for attribute in jcls.mIntegerList:
            f.write("dest.writeInt(%s);
    " % (attribute))
        for attribute in jcls.mStrList:
            f.write("dest.writeString(%s);
    " % (attribute))
        for attribute in jcls.mBolList:
            f.write("dest.writeByte((byte) (%s ? 1 : 0));
    " % (attribute))
                
        for attribute in jcls.mListList:
            f.write("dest.writeTypedList(%s);" % (attribute[1]))
                
        for attribute in jcls.mClassList:
            f.write("dest.writeParcelable(%s, PARCELABLE_WRITE_RETURN_VALUE);" % attribute[1])
                
        f.write(Class_Method_END)
            
        # readFromParcel method
        f.write(Method_Parcelable_Read)
        for attribute in jcls.mIntegerList:
            f.write("%s= in.readInt();
    " % (attribute))
        for attribute in jcls.mStrList:
            f.write("%s= in.readString();
    " % (attribute))
        for attribute in jcls.mBolList:
            f.write("%s = in.readByte() != 0;
    " % (attribute))
        
        for attribute in jcls.mListList:
            f.write("%s = new ArrayList<%s>();" % (attribute[1], attribute[0]))
            f.write("in.readTypedList(%s, %s.CREATOR);" % (attribute[1], attribute[0]))
                
        for attribute in jcls.mClassList:
            f.write("%s = in.readParcelable(%s.class.getClassLoader());" % (attribute[1], attribute[0]))
                
        f.write(Class_Method_END)
        # describeContents method   
        f.write("public int describeContents() {return 0;}")
        
        f.write('''
              public static final Parcelable.Creator<%s> CREATOR = 
                    new Parcelable.Creator<%s>() {
                public %s createFromParcel(Parcel in) {
                    return new %s(in);
                }
        
                public %s[] newArray(int size) {
                    return new %s[size];
                }
            };
            ''' % (jcls.mName, jcls.mName, jcls.mName, jcls.mName, jcls.mName, jcls.mName))
        
        pass
    
    
    def writeCls2File(jcls, f):
        f.seek(0, 2)
        # write class header
        if IS_PARCELABLE:  # if need implement parcelable
            if jcls.mName == FILE_NAME:
                f.write(Class_HEAD_parcelable % ("", jcls.mName, jcls.mName, jcls.mName))
            else:
                f.write(Class_HEAD_parcelable % ("static", jcls.mName, jcls.mName, jcls.mName))
        else:
            f.write(Class_HEAD % ("", jcls.mName))
        
        
        # write class's attribute
        for attribute in jcls.mIntegerList:
            f.write(Attribute_TEMP % ('int', attribute))
        for attribute in jcls.mStrList:
            f.write(Attribute_TEMP % ('String', attribute))
        for attribute in jcls.mBolList:
            f.write(Attribute_TEMP % ('Boolean', attribute))
        for attribute in jcls.mListList:
            f.write(Attribute_TEMP % ('List<' + attribute[0] + '>', attribute[1]))
        for attribute in jcls.mClassList:
            f.write(Attribute_TEMP % (attribute[0], attribute[1]))
            
        # write class's method analyzerJson
        f.write(Method_Analyzer)
        for attribute in jcls.mIntegerList:
            f.write(Method_GET_INT % (attribute, attribute))
        for attribute in jcls.mStrList:
            f.write(Method_GET_String % (attribute, attribute))
        for attribute in jcls.mBolList:
            f.write(Method_GET_Boolean % (attribute, attribute))
        for attribute in jcls.mClassList:
            f.write(Method_GET_CLASS % (attribute[1], attribute[0], attribute[1], attribute[1]))
        for attribute in jcls.mListList:
            f.write(Method_GET_List % (attribute[1], attribute[0], attribute[1], attribute[1], attribute[1], attribute[1], attribute[1], attribute[0], attribute[0], attribute[1], attribute[1]))
        f.write(Class_Method_END)
        
        # write parcelable method
        if IS_PARCELABLE:
            writeParcelabelMethod(f, jcls)
            
        # the method toString
        f.write("public String toString(){")
        f.write("String allInfo = ")
        for attribute in jcls.mIntegerList:
            f.write(''' " %s="+%s +  ''' % (attribute, attribute))
        for attribute in jcls.mStrList:
            f.write(''' " %s="+%s +  ''' % (attribute, attribute))
        for attribute in jcls.mBolList:
            f.write(''' " %s="+%s +  ''' % (attribute, attribute))
    
        for attribute in jcls.mListList:
            f.write(''' " %s="+%s.toString() +  ''' % (attribute[1], attribute[1]))
        
        for attribute in jcls.mClassList:
            f.write(''' " %s="+%s.toString() +  ''' % (attribute[1], attribute[1]))
            
        f.write('''" ";''')
        f.write("return allInfo;")
        f.write(Class_Method_END)
        
        # write class's class
        for innerClass in jcls.mInClassTypeList:
            writeCls2File(innerClass, f)
            pass
        f.write(Class_Method_END)
        pass
    
    def generatorClsFile(jcls):
        global IS_PARCELABLE
        global FILE_NAME
        IS_PARCELABLE = jcls.mIsParcelable
        FILE_NAME = jcls.mName
        f = open(FILE_NAME + ".java", 'w')
        f.write(Class_import % jcls.mPackageName)
        if IS_PARCELABLE:
            f.write(Class_import_parcelable)
        writeCls2File(jcls, f)
    

      完整项目:http://files.cnblogs.com/files/chenjie0949/CodeGenerator1.3.zip

  • 相关阅读:
    JavaScript 深入之从原型到原型链
    js重写内置的call、apply、bind
    js中flat方法的实现原理
    【我的物联网成长记6】由浅入深了解NB-IoT【华为云技术分享】
    GO富集分析示例【华为云技术分享】
    华为“方舟编译器”到底是啥?一文看懂TA如何让手机性能再突破【华为云技术分享】
    无码系列-7-代码的语文修养_上篇【华为云技术分享】
    机器学习笔记(一)----基本概念【华为云技术分享】
    性能达到原生 MySQL 七倍,华为云 Taurus 技术解读【华为云技术分享】
    【立即报名】人脸情绪识别案例分享【华为云技术分享】
  • 原文地址:https://www.cnblogs.com/chenjie0949/p/4815640.html
Copyright © 2011-2022 走看看