在我们android的日常开发中,经常会遇到,把一个数据类转成JSON,然后把JSON当作参数与网络进行通讯,还有就是从后台获取回来的数据是JSON,而使用数据时传递或者保存到手机本地数据库往往是数据类,这时为了以后容易维护,就需要把JSON转成数据类,这样以后即使需求变了,把数据类的成员变量修改了,也容易维护,不至于每个地方都需要修改,万一漏修改了某个地方,那么的话就会出错,所以本篇文章就是介绍数据类与JSON的互相转换。我找了很久,最后发现还是google牛逼,已经实现了这样需求,它的描述如下:A Java serialization library that can convert Java Objects into JSONand back.(这是一个把对象转成JSON又转回来的Java序列化库)
我自己也在使用,很好用,所以推荐给大家,它的源码地址:https://github.com/google/gson
可以去下载下来,可以把关键源码直接导入到自己的项目中,也可以打包后导入。
下面我就来讲讲它使用:
1. 数据类转成JSON
private JSONObject getJSONByOBj(UserInfo aUserInfo){
Gson gson = new Gson();
String jsnStr=gson.toJson(aUserInfo);
JSONObject jsonObject=null;
try {
jsonObject= new JSONObject(jsnStr);
}catch (Exception e){
e.printStackTrace();
}
return jsonObject;
}
呵呵,看到了吧,很简单!
2. JSON转成数据类
Gson gson = new Gson();
try {
UserInfouserInfo=gson.fromJson("JSON数据",UserInfo.class);
//做你想做的事情。。
}catch (Exception e){
e.printStackTrace();
}
关于json转成数据类,我在网上还找到一种办法,现在共享给大家:
/**
* 反序列化简单对象
* @param jo json对象
* @param clazz 实体类类型
* @return 反序列化后的实例
* @throws JSONException
*/
publicstatic <T> T parseObject(JSONObject jo, Class<T> clazz) throwsJSONException {
if(clazz == null || isNull(jo)) {
returnnull;
}
Tobj = newInstance(clazz);
if(obj == null) {
returnnull;
}
if(isMap(clazz)){
setField(obj,jo);
}else{
//取出bean里的所有方法
Method[]methods = clazz.getDeclaredMethods();
Field[]fields = clazz.getDeclaredFields();
for(Field f : fields) {
StringsetMetodName = parseMethodName(f.getName(),"set");
if(!haveMethod(methods, setMetodName)) {
continue;
}
try{
MethodfieldMethod = clazz.getMethod(setMetodName, f.getType());
setField(obj,fieldMethod,f,jo);
}catch (Exception e) {
e.printStackTrace();
}
}
}
returnobj;
}
下面我上面那个函数引用的函数:
/**
* 判断对象是否为空
* @param obj 实例
* @return
*/
privatestatic boolean isNull(Object obj) {
if(obj instanceof JSONObject) {
returnJSONObject.NULL.equals(obj);
}
returnobj == null;
}
/**
* 根据类型创建对象
* @param clazz 待创建实例的类型
* @return 实例对象
* @throws JSONException
*/
@SuppressWarnings({"unchecked", "rawtypes" })
privatestatic <T> T newInstance(Class<T> clazz) throws JSONException {
if(clazz == null)
returnnull;
Tobj = null;
if(clazz.isInterface()) {
if(clazz.equals(Map.class)) {
obj= (T) new HashMap();
}elseif (clazz.equals(List.class)) {
obj= (T) new ArrayList();
}elseif (clazz.equals(Set.class)) {
obj= (T) new HashSet();
}else{
thrownew JSONException("unknown interface: " + clazz);
}
}else{
try{
obj= clazz.newInstance();
}catch(Exception e) {
thrownew JSONException("unknown class type: " + clazz);
}
}
returnobj;
}
/**
* 设定Map的值
* @param obj 待赋值字段的对象
* @param jo json实例
*/
privatestatic void setField(Object obj, JSONObject jo) {
try{
@SuppressWarnings("unchecked")
Iterator<String>keyIter = jo.keys();
Stringkey;
Objectvalue;
@SuppressWarnings("unchecked")
Map<String,Object> valueMap = (Map<String, Object>) obj;
while(keyIter.hasNext()) {
key= (String) keyIter.next();
value= jo.get(key);
valueMap.put(key,value);
}
}catch (JSONException e) {
e.printStackTrace();
}
}
/**
* 拼接某属性的 get或者set方法
* @param fieldName 字段名称
* @param methodType 方法类型
* @return 方法名称
*/
publicstatic String parseMethodName(String fieldName,String methodType) {
if(null == fieldName || "".equals(fieldName)) {
return null;
}
returnmethodType + fieldName.substring(0, 1).toUpperCase() +fieldName.substring(1);
}
/**
* 判断是否存在某属性的 get方法
* @param methods 引用方法的数组
* @param fieldMethod 方法名称
* @return true或者false
*/
publicstatic boolean haveMethod(Method[] methods, String fieldMethod) {
for(Method met : methods) {
if(fieldMethod.equals(met.getName())) {
returntrue;
}
}
returnfalse;
}
/**
* 设定字段的值
* @param obj 待赋值字段的对象
* @param fieldSetMethod 字段方法名
* @param field 字段
* @param jo json实例
*/
privatestatic void setField(Object obj, Method fieldSetMethod,Field field, JSONObjectjo) {
Stringname = field.getName();
Class<?>clazz = field.getType();
try{
if(isArray(clazz)) { // 数组
Class<?>c = clazz.getComponentType();
JSONArrayja = jo.optJSONArray(name);
if(!isNull(ja)) {
Objectarray = parseArray(ja, c);
setFiedlValue(obj,fieldSetMethod, clazz.getSimpleName(), array);
}
}else if (isCollection(clazz)) { // 泛型集合
//获取定义的泛型类型
Class<?>c = null;
TypegType = field.getGenericType();
if(gType instanceof ParameterizedType) {
ParameterizedTypeptype = (ParameterizedType) gType;
Type[]targs = ptype.getActualTypeArguments();
if(targs != null && targs.length > 0) {
Typet = targs[0];
c= (Class<?>) t;
}
}
JSONArrayja = jo.optJSONArray(name);
if(!isNull(ja)) {
Objecto = parseCollection(ja, clazz, c);
setFiedlValue(obj,fieldSetMethod, clazz.getSimpleName(), o);
}
}else if (isSingle(clazz)) { // 值类型
Objecto = jo.opt(name);
if(o != null) {
setFiedlValue(obj,fieldSetMethod, clazz.getSimpleName(), o);
}
}else if (isObject(clazz)) { // 对象
JSONObjectj = jo.optJSONObject(name);
if(!isNull(j)) {
Objecto = parseObject(j, clazz);
setFiedlValue(obj,fieldSetMethod, clazz.getSimpleName(), o);
}
}else if (isList(clazz)) { // 列表
// JSONObjectj = jo.optJSONObject(name);
// if(!isNull(j)) {
// Objecto = parseObject(j, clazz);
// f.set(obj,o);
// }
}else {
thrownew Exception("unknow type!");
}
}catch (Exception e) {
e.printStackTrace();
}
}
/**
* 给对象的字段赋值
* @param obj 类实例
* @param fieldSetMethod 字段方法
* @param fieldType 字段类型
* @param value
*/
publicstatic void setFiedlValue(Object obj,Method fieldSetMethod,StringfieldType,Object value){
try{
if(null != value && !"".equals(value)) {
if("String".equals(fieldType)) {
fieldSetMethod.invoke(obj,value.toString());
}else if ("Date".equals(fieldType)) {
SimpleDateFormatsdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss",Locale.CHINA);
Datetemp = sdf.parse(value.toString());
fieldSetMethod.invoke(obj,temp);
}else if ("Integer".equals(fieldType)
||"int".equals(fieldType)) {
Integerintval = Integer.parseInt(value.toString());
fieldSetMethod.invoke(obj,intval);
}else if ("Long".equalsIgnoreCase(fieldType)) {
Longtemp = Long.parseLong(value.toString());
fieldSetMethod.invoke(obj,temp);
}else if ("Double".equalsIgnoreCase(fieldType)) {
Doubletemp = Double.parseDouble(value.toString());
fieldSetMethod.invoke(obj,temp);
}else if ("Boolean".equalsIgnoreCase(fieldType)) {
Booleantemp = Boolean.parseBoolean(value.toString());
fieldSetMethod.invoke(obj,temp);
}else {
fieldSetMethod.invoke(obj,value);
Log.e(TAG,TAG +">>>>setFiedlValue -> not supper type" + fieldType);
}
}
}catch (Exception e) {
// Log.e(TAG, TAG +">>>>>>>>>>set value error.",e);
e.printStackTrace();
}
}
/**
* 判断是否是Map
* @param clazz
* @return
*/
publicstatic boolean isMap(Class<?> clazz) {
returnclazz != null && Map.class.isAssignableFrom(clazz);
}
/**
* 判断是否是数组
* @param clazz
* @return
*/
publicstatic boolean isArray(Class<?> clazz) {
returnclazz != null && clazz.isArray();
}
/**
* 判断是否是集合
* @param clazz
* @return
*/
publicstatic boolean isCollection(Class<?> clazz) {
returnclazz != null && Collection.class.isAssignableFrom(clazz);
}
/**
* 判断是否是值类型
* @param clazz
* @return
*/
privatestatic boolean isSingle(Class<?> clazz) {
returnisBoolean(clazz) || isNumber(clazz) || isString(clazz);
}
/**
* 判断是否是对象
* @param clazz
* @return
*/
privatestatic boolean isObject(Class<?> clazz) {
returnclazz != null && !isSingle(clazz) && !isArray(clazz) &&!isCollection(clazz)&& !isMap(clazz);
}
/**
* 判断是否是列表
* @param clazz
* @return
*/
publicstatic boolean isList(Class<?> clazz) {
returnclazz != null && List.class.isAssignableFrom(clazz);
}
/**
* 是否布尔值
* @param clazz
* @return
*/
publicstatic boolean isBoolean(Class<?> clazz) {
return(clazz != null)
&&((Boolean.TYPE.isAssignableFrom(clazz)) || (Boolean.class
.isAssignableFrom(clazz)));
}
/**
* 是否数值
* @param clazz
* @return
*/
publicstatic boolean isNumber(Class<?> clazz) {
return(clazz != null)
&&((Byte.TYPE.isAssignableFrom(clazz)) || (Short.TYPE.isAssignableFrom(clazz))
||(Integer.TYPE.isAssignableFrom(clazz))
||(Long.TYPE.isAssignableFrom(clazz))
||(Float.TYPE.isAssignableFrom(clazz))
||(Double.TYPE.isAssignableFrom(clazz)) || (Number.class
.isAssignableFrom(clazz)));
}
/**
* 判断是否是字符串
* @param clazz
* @return
*/
publicstatic boolean isString(Class<?> clazz) {
return(clazz != null)
&&((String.class.isAssignableFrom(clazz))
||(Character.TYPE.isAssignableFrom(clazz)) || (Character.class
.isAssignableFrom(clazz)));
}
因为文章写的匆忙,可能有很多不足之处,请大家批评指正,如果有哥们,看了之后还有看不到的话,就在下面回复吧,要是比较多的人需要,我也可以多花点时间写个demo出来,这样就可以直接运行调试了,谢谢大家!