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 = "}\n" Attribute_TEMP = "public %s %s;\n" Method_Analyzer = '''
public void analyzerJson(JSONObject jsonObject) throws JSONException {
if(jsonObject == null){
return;
}
''' Method_TEMP = "public %s %s(%s)throws JSONException {\n"
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) {\n '''
Mehtod_Parcelable_Value_Write = "dest.write%s(%s);\n"
Method_Parcelable_Read = '''public void readFromParcel(Parcel in) {\n '''
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);\n" % (attribute))
for attribute in jcls.mStrList:
f.write("dest.writeString(%s);\n" % (attribute))
for attribute in jcls.mBolList:
f.write("dest.writeByte((byte) (%s ? 1 : 0));\n" % (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();\n" % (attribute))
for attribute in jcls.mStrList:
f.write("%s= in.readString();\n" % (attribute))
for attribute in jcls.mBolList:
f.write("%s = in.readByte() != 0;\n" % (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
json 转 javaBean的更多相关文章
- json、javaBean、xml互转的几种工具介绍
json.javaBean.xml互转的几种工具介绍 转载至:http://blog.csdn.net/sdyy321/article/details/7024236 工作中经常要用到Json.Jav ...
- Json与javaBean之间的转换工具类
/** * Json与javaBean之间的转换工具类 * * {@code 现使用json-lib组件实现 * 需要 * json-lib-2.4-jdk15.jar * ...
- json、javaBean、xml互转的几种工具介绍 (转载)
工作中经常要用到Json.JavaBean.Xml之间的相互转换,用到了很多种方式,这里做下总结,以供参考. 现在主流的转换工具有json-lib.jackson.fastjson等,我为大家一一做简 ...
- 关于flexjson将json转为javabean的使用
关于flexjson将json转为javabean的使用 import java.sql.Timestamp; import java.util.Date; import flexjson.JSOND ...
- Json、JavaBean、String等互转
Json.JavaBean.String等互转 本文介绍简单的Json.JavaBean.String互换(下文JavaBean简称Object对象,这里不是很严谨) 转换关系如下: 其中String ...
- IDEA使用GsonFormat完成JSON和JavaBean之间的转换
原文地址:https://www.leshalv.net/posts/12625/ 前言: 之前处理接口传来的一堆数据,用jsonObject很难受,后面就用gosn来弄,配合这个工具体验很好. 转: ...
- JSON 转javabean 利器
别再对着json来手写javabean啦.这个工作完全不要脑子,而且耗时. 这里给大家提供三种方式: android studio版: 万能的插件:GsonFormat 如何安装? Preferenc ...
- JSON转javabean(pojo)利器
别再对着json来手写javabean啦.这个工作完全不要脑子,而且耗时. 这里给大家提供三种方式: android studio版: 万能的插件:GsonFormat 如何安装? Preferenc ...
- Json、JavaBean、Map、XML之间的互转
思路是JavaBean.Map.XML都可以用工具类很简单的转换为Json,进而实现互相转换 1.Map.XML与Json互转 mvn依赖 <dependency> <groupId ...
随机推荐
- 谈谈分布式事务之三: System.Transactions事务详解[下篇]
在前面一篇给出的Transaction的定义中,信息的读者应该看到了一个叫做DepedentClone的方法.该方法对用于创建基于现有Transaction对 象的“依赖事务(DependentTra ...
- 通过DeveloperApi获取spark程序执行进度及异常
在应用spark时,经常要获取任务的执行进度,可以参照jobProgressListener的设计来完成该功能. 以下代码仅供参考,欢迎交流. 效果显示: 代码: package org.apache ...
- aix 系统运行级别
运行级别 在操作系统上运行维护之前,或者修改系统运行级别之前,需检查各种不同的运行级别.运行级别是一个软件配置,只允许一组选定的进程存在. 识别系统运行级别 本节描述如何识别系统正运行在什么样的运行级 ...
- java中String、StringBuilder、StringBuffer三者的区别
在Java项目开发中,字符串是最长使用的数据类型,而有关字符串的String.StringBuilder.StringBuffer三者又常常让人分不清楚什么时候该使用哪个. 特此整理一下. Strin ...
- EGit插件安装(附Eclipse版本对应表)
最近eclipse添加egit插件,通过网上的方法下载安装后不显示git选项.通过官网了解到egit的版本对应相应的eclipse版本. 如果你安装了最新版本,需要先卸载重启eclipse后重新安装兼 ...
- HDOJ-ACM1071(JAVA) 定积分
这道题做起来有点无奈,定积分已经忘得差不多了~还可恶的去搜索了抛物线的解析式的求法~哈哈 不过求出来的结果不对...等有时间再去研究这个数学问题吧 - - 以下是JAVA实现: import java ...
- Centos System Info
系统 # uname -a # 查看内核/操作系统/CPU信息 # head -n 1 /etc/issue # 查看操作系统版本 # cat /proc/cpuinfo # 查看CPU信息 # ho ...
- 问题-[delphi2007、2010]无法二次启动,报EditorLineEnds.ttr被占用,进程一直有bds.exe?
问题现象:delphi2007.2010无法二次启动,报EditorLineEnds.ttr被占用,而且进程中一直有bds.exe的进程? 问题原因:问题处理:方法一:可能是系统更新的东东造在的.KB ...
- Maintainable JavaScript(编写可维护的JavaScript) PART I Style Guidelines
“Programs are meant to be read by humans and only incidentally( 顺便:偶然地:附带地) for computers to execute ...
- hdoj 5522 Numbers
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5522 水题:暴力过 #include<stdio.h> #include<strin ...