这里我们依旧用上文中的 json 字符串 , 由于转换为 map 依旧需要 javaBean , 所有我们的实体对象也不发生改变
这里我们需要活用 java 反射和类型对比实现需求
先看代码
package com.jacx.test.test01.jsonutil;
import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
/**
* @author 刘合炎
* @description json对象转java对象
* 此方法使用方法较为驳杂,请结合例子参考 -- JSONTest
*/
public class TestJsonUtil {
/**
* 获得对象的属性和集合中的属性
* @param clazz
* @return
*/
private static List findFiledsAttr(Class clazz){
Field[] fields = null;
List fieldList = new ArrayList();
while(true){
if(clazz == null){
break;
}
fields = clazz.getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
fieldList.add(fields[i]);
System.out.println("fields:" +fields[i]);
Class fieldType = fields[i].getType();
//判断是否为基本类型
if(fieldType.isPrimitive() || fieldType.toString().equals("class java.lang.String")){
continue;
}else{
//是用户想要的类型?
//if(fieldType.isAssignableFrom(List.class)){
Type type = fields[i].getGenericType();
if(type == null){
continue;
}
if(type instanceof ParameterizedType){//如果是泛型参数的类型
ParameterizedType pt = (ParameterizedType) type;
Class genericClass = (Class)pt.getActualTypeArguments()[0];//得到泛型的class对象
//System.out.println("genericClass:"+genericClass);
//递归直到获得所有属性
findFiledsAttr(genericClass);
}
//}
}
}
clazz = clazz.getSuperclass();
}
return fieldList;
}
public static void main(String[] args) {
List fields= findFiledsAttr(TestGsonUnSer.class);
for (int i = 0; i < fields.size(); i++) {
System.out.println(fields.get(i));
}
}
/**
* 转换操作
* @param obj 基本对象
* @param obj2 对象中的对象
* @param ignores 是否摒弃
* @return
*/
public static Map convertBean2Map(Object obj,String[] ignores){
Map map = new LinkedHashMap();
Class clazz = obj.getClass();
List fields = findFiledsAttr(clazz);
Field field = null;
List taskList = null;
for (int i = 0; i < fields.size(); i++) {
field = fields.get(i);
boolean flag = false;
if(ignores != null && ignores.length > 0){
flag = isExistOfIgnores(field.getName(), ignores);
}
if(!flag){
Object value = getProperty(obj, field.getName());
if(null != value/* && !StringUtils.EMPTY.equals(value.toString())*/){
//判断是否为基本类型
if(field.getType().isPrimitive() || field.getType().toString().equals("class java.lang.String")){
//基本类型直接设值即可
map.put(field.getName(), getProperty(obj, field.getName()));
}else if(field.getType().isAssignableFrom(List.class)){
PropertyDescriptor pd = getPropertyDescriptor(obj.getClass(), field.getName());
Method getMethod = pd.getReadMethod();
Object objValue = null;
try {
objValue = getMethod.invoke(obj, new Object[]{});
System.out.println("finalValue:"+objValue);
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(objValue instanceof List>){
System.out.println("===========================");
taskList = (List)objValue;
}
System.out.println("pd.getReadMethod():"+pd.getReadMethod());
/*//获取class类型中的propertyName属性
PropertyDescriptor pd = getPropertyDescriptor(obj.getClass(), field.getName());
//从属性描述器中获取get方法
Method getMethod = pd.getReadMethod();
System.out.println("field.getClass():"+getMethod);*/
//遍历嵌套对象中的元素
//System.out.println("obj2:"+obj2);
ParameterizedType pt = (ParameterizedType) field.getGenericType();
Class genericClass = (Class)pt.getActualTypeArguments()[0];//得到泛型的class对象
/*if (obj2 instanceof List>){
taskList = (List)obj2;
}*/
List> sonMap = new ArrayList>();
for (int j = 0; j < taskList.size(); j++) {
List sonFields = findFiledsAttr(taskList.get(j).getClass());
LinkedHashMap son2Map = new LinkedHashMap();
for (int k = 0; k < sonFields.size(); k++) {
System.out.println("sonFields.get(k).getName():"+sonFields.get(k).getName());
if(sonFields.get(k).getType().isPrimitive() || sonFields.get(k).getType().toString().equals("class java.lang.String")){
son2Map.put(sonFields.get(k).getName(), getProperty(taskList.get(j), sonFields.get(k).getName()));
System.out.println("子对象中的数据:"+son2Map);
}else{
//递归至基本类型或String
convertBean2Map(getProperty(taskList.get(j), sonFields.get(k).getName()));
}
}
sonMap.add(son2Map);
map.put(field.getName(), sonMap);
}
}else{
PropertyDescriptor pd = getPropertyDescriptor(obj.getClass(), field.getName());
Method getMethod = pd.getReadMethod();
Object objValue2 = null;
try {
objValue2 = getMethod.invoke(obj, new Object[]{});
System.out.println("finalValue:"+objValue2);
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
e.printStackTrace();
}
List sonFields = findFiledsAttr(objValue2.getClass());
Map sonMap = new LinkedHashMap();
for (int j = 0; j < sonFields.size(); j++) {
if(sonFields.get(j).getType().isPrimitive() || sonFields.get(j).getType().toString().equals("class java.lang.String")){
System.out.println("sonFields.get(j).getName():"+sonFields.get(j).getName());
sonMap.put(sonFields.get(j).getName(), getProperty(objValue2, sonFields.get(j).getName()));
System.out.println("子对象中的数据:"+sonMap);
}else{
//递归至基本类型或String
convertBean2Map(getProperty(objValue2, sonFields.get(j).getName()));
}
}
map.put(field.getName(), sonMap);
}
}
}
}
return map;
}
/**
* 重载
* @param obj
* @param obj2
* @return
*/
public static Map convertBean2Map(Object obj){
return convertBean2Map(obj,null);
}
public static Map convertBean2MapForIngoreserialVersionUID(Object obj) {
return convertBean2Map(obj, new String[] { "serialVersionUID" });
}
private static boolean isExistOfIgnores(String fieldName,String[] ignores){
boolean flag = false;
for(String str : ignores){
if(str.equals(fieldName)){
flag = true;
break;
}
}
return flag;
}
/**
* 通过set方法设值
* @param obj
* @param propertyName
* @param value
*/
@SuppressWarnings("unchecked")
private static void setProperty(Object obj, String propertyName,Object value) {
Class clazz = obj.getClass();// 获取对象的类型
PropertyDescriptor pd = getPropertyDescriptor(clazz, propertyName);// 获取 clazz类型中的propertyName的属性描述器
Method setMethod = pd.getWriteMethod();// 从属性描述器中获取 set 方法
try {
setMethod.invoke(obj, new Object[] {value});// 调用 set 方法将传入的value值保存属性中去
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 通过get方法获取对象属性值对应的值
* @param obj
* @param propertyName
* @return
*/
private static Object getProperty(Object obj,String propertyName){
Class clazz = obj.getClass();
//获取class类型中的propertyName属性
PropertyDescriptor pd = getPropertyDescriptor(clazz, propertyName);
//从属性描述器中获取get方法
Method getMethod = pd.getReadMethod();
Object value = null;
try {
//调用value方法将传入的value值保存至属性中
value = getMethod.invoke(obj, new Object[]{});
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return value;
}
/**
* get和set方法取值
* @param clazz
* @param propertyName
* @return
*/
private static PropertyDescriptor getPropertyDescriptor(Class clazz,String propertyName){
StringBuffer sb = new StringBuffer();//存储方法名称
Method setMethod = null;
Method getMethod = null;
PropertyDescriptor pd = null;
try {
//根据字段名获取字段
Field f = clazz.getDeclaredField(propertyName);
if(f != null){
String methodEnd = propertyName.substring(0,1).toUpperCase() + propertyName.substring(1);
//构建set方法
sb.append("set" + methodEnd);
setMethod = clazz.getDeclaredMethod(sb.toString(), new Class[]{f.getType()});
//构建get方法
sb.delete(0, sb.length());//清空
sb.append("get"+methodEnd);
getMethod = clazz.getDeclaredMethod(sb.toString(), new Class[]{});
System.out.println("getMethod:"+getMethod);
pd = new PropertyDescriptor(propertyName, getMethod,setMethod);
}
} catch (NoSuchFieldException e) {
System.out.println("实体对象中没有此属性==="+e.getMessage());
} catch (SecurityException e) {
System.out.println("此方法为私有的或访问权限不足==="+e.getMessage());
} catch (NoSuchMethodException e) {
System.out.println("实体对象中的属性必须有get/set方法==="+e.getMessage());
} catch (IntrospectionException e) {
e.printStackTrace();
}
return pd;
}
}
可以看到 , 在此工具类中通过反射机制拿到所有的属性和属性类型 , 将基本数据类型+String和对象类型分开做不同操作 , 通过方法反射拼接get和set方法取值/设值
这里重中之重依旧是分析 json 应该转换为何种类型
public static void main(String[] args) {
String str = "[{\"users\":[{\"name\":\"系统001\",\"code\":\"sys01\"},{\"name\":\"系统003\",\"code\":\"sys03\"}],\"travel_theme\":\"测试002\",\"travel_start_time\":\"2017-08-08 10:07\",\"travel_end_time\":\"2017-08-22 10:07\",\"process_start_time\":\"2017-08-07 10:09:06\",\"process_end_time\":\"2017-08-07 10:28:46\"},{\"users\":[{\"name\":\"系统002\",\"code\":\"sys002\"}],\"travel_theme\":\"测试004\",\"travel_start_time\":\"2017-08-07 10:11\",\"travel_end_time\":\"2017-08-08 10:11\",\"process_start_time\":\"2017-08-07 10:12:34\",\"process_end_time\":\"2017-08-07 10:28:51\"}]";
Gson gson = new Gson();
List list = gson.fromJson(str, new TypeToken>(){}.getType());
System.out.println("list:"+list);
System.out.println(list.get(0).getUsers().get(0).getName());
List
最后 maps 输出
maps:[{users=[{name=系统001, code=sys01}, {name=系统003, code=sys03}], travel_theme=测试002, travel_start_time=2017-08-08 10:07, travel_end_time=2017-08-22 10:07, process_start_time=2017-08-07 10:09:06, process_end_time=2017-08-07 10:28:46}, {users=[{name=系统002, code=sys002}], travel_theme=测试004, travel_start_time=2017-08-07 10:11, travel_end_time=2017-08-08 10:11, process_start_time=2017-08-07 10:12:34, process_end_time=2017-08-07 10:28:51}]
和我们想要的结果一致