想写一个小软件,引入其他人的json工具类动不动就几百kb,太大了,比我自己的软件都大,所以自定义一个json工具类
罗嗦版本,带注释,真的一路坎坷写下来的,本来以为他没有这样的方法没想到他有。。。。
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class JSONObjectUtil {
/**
* 将一个json转化成一个对象
* @param jsonStr json字符串
* @param targetClass 需要转化的类型
* @param 类型的class类
* @return 返回的是T的实例化对象
*/
public static T parse2Object(String jsonStr, Class targetClass) {
try {
JSONObject jsonObject = new JSONObject(jsonStr);
Field[] targetClassFields = targetClass.getDeclaredFields();
Class c = Class.forName(targetClass.getName());
//将泛型类new出来
final T resultObject = (T) c.newInstance();
for (Field targetClassField : targetClassFields) {
//判断当前字段类型
Class> currentFieldType = targetClassField.getType();
//获取目标类中的所有方法,调用目标类中的所有set方法注入字段
Method[] targetClassMethods = targetClass.getDeclaredMethods();
//去json里面get("targetClassField"),然后去targetClass里面set+“targetClassField”
String targetClassFieldName = targetClassField.getName();
//现在里面就是具体的参数了, param好像是入参,value好像是出参用的
//Object jsonValue = jsonObject.get(targetClassFieldName);//如果直接getId获取到的是Integer,但是setId的时候需要Long类型
//所以这一行代码写在forEach里面,get+“bean里面的传入类型”
//??????为什么这里也获取出来的是他原本的类型???那他为什么要设置这么多getLong,getDouble来迷惑我?????,那我写这么多岂不是浪费了????????
//System.out.println("获取的数据类型-->"+jsonValue.getClass().getName());
//调用的方法是targetClass里面set+“targetClassField”
System.out.println("\n\n\n\n");
Arrays.stream(targetClassMethods)
.filter(targetClassMethod -> targetClassMethod.getName().equals("set" + toUpperFirstOne(targetClassField.getName())))
.forEach(targetClassMethod -> {
try {
//jsonObject.get(targetClassFieldName);把这个方法替换成下面的jsonObjectGetMethod这个,因为当主键Id是1、2、3时,JSONObject默认帮我们生成的是Integer,但是我们需要的是Long
//这个方法就是JSONObject中的getLong/getString/getDouble
Method jsonObjectGetMethod = Arrays.stream(jsonObject.getClass().getDeclaredMethods())
.filter(jsonObjectMethod -> {
//获取到的是java.lang.String
Class> parameterType = targetClassMethod.getParameterTypes()[0];
String methodName="get" + parameterType.getName()
.substring(parameterType.getName().lastIndexOf(".") + 1);
if (methodName.contains("Int"))
methodName="getInt";
return jsonObjectMethod.getName().equals(methodName);
}).collect(Collectors.toList()).get(0);//里面一定只有一个方法,因为这是过滤bean的方法,bean里面不可能出现重载方法
Object jsonValue = jsonObjectGetMethod.invoke(jsonObject, targetClassFieldName);
//System.out.println("jsonValue类型-->"+jsonValue.getClass().getName());
targetClassMethod.invoke(resultObject, jsonValue);
//System.out.println("当前对象-->" + resultObject);
} catch (Exception e) {
e.printStackTrace();
}
});
/* IntStream.range(0, targetClassDeclaredMethods.length)
.filter(i -> targetClassDeclaredMethods[i].getName().contains("set"))//剩下所有的set方法
.forEach(i -> {
String currentFieldAllTypeName=currentFieldType.getName();
//获取类型名字,类似于String、Integer这样的,上面的获取出来是java.lang.String这样的
String currentFieldTypeName = currentFieldAllTypeName.substring(currentFieldAllTypeName.lastIndexOf(".") + 1);
try {
Method[] jsonObjectMethod = jsonObject.getClass().getDeclaredMethods();
//里面全是jsonObject中的带有get的方法,好像没啥用,到下面invoke的时候好像还是会变成object
Method jsonObjectGetMethod = Arrays.stream(jsonObjectMethod)
.filter(jsonObjectMethodEle -> jsonObjectMethodEle.getName().equals("get"+currentFieldTypeName))//get加类型名字就是要执行的方法
.collect(Collectors.toList()).get(0);//里面只可能有一个方法,那就是"get"+currentFieldTypeName,但是不这样写返回的是个数组
//System.out.println("需要执行的方法-->"+jsonObjectGetMethod.getName());
//jsonObject中执行get方法,返回的参数是String或者Long之类的
Object jsonObjectGetResultParam = jsonObjectGetMethod.invoke(jsonObject, declaredField.getName());
*//**
* 我真的好无语,我以为反射return的类型肯定是Object,结果不是Objetc,是本该有的类型,是Long就是Long只是显示成Object,好气,这么多白写了,估计转化类型的过程是在这里完成的《.filter(jsonObjectMethodEle -> jsonObjectMethodEle.getName().equals("get"+currentFieldTypeName))》
//调用currentFieldTypeName的valueOf方法
//获取typeClass 他是String.class,或者是Integer.class,或者是Long.class
Class> typeClass=Class.forName(currentFieldAllTypeName);
//获取类中的所有方法
Method[] typeClassAllMethods = typeClass.getDeclaredMethods();
Method typeClassValueOfMethod = Arrays.stream(typeClassAllMethods)
.filter(typeClassAllMethod -> typeClassAllMethod.getName().equals("valueOf"))
.collect(Collectors.toList()).get(5);//这个时候里面有一堆valueOf的重载方法
//System.out.println("valueOF--->"+typeClassValueOfMethod.getName());
//Object o = jsonObject.get(declaredField.getName());//调用方法时传的参数
//调用的是String/Long/Integer的valueOf方法
//调用完成以后,哪怕是返回的是Object,但是调用getClass().getName()还是String/Integer,本质上就已经是String/Integer/Long了
//将json里面的参数转化成他应该是的类型,字符串转化成字符串,long转化成long
Object jsonParamConvertTypeClass = typeClassValueOfMethod.invoke(null, jsonObjectGetResultParam);
//System.out.println("Object类型本质---->"+jsonParamConvertTypeClass.getClass().getName());
//java反射的返回值一直是Object,很苦恼,自己写一个方法
*//*
System.out.println("当前方法-->"+targetClassDeclaredMethods[i]);
System.out.println("传入参数-->"+jsonObjectGetResultParam);
System.out.println("参数类型-->"+jsonObjectGetResultParam.getClass().getName());
System.out.println("对象实例-->"+resultObject);
//调用目标类中的所有set方法注入参数
targetClassDeclaredMethods[i].invoke(resultObject,jsonObjectGetResultParam);
System.out.println("没报错");
} catch (Exception e) {
e.printStackTrace();
}
});//调用所有的set方法setjson里面的值
//System.out.println("declaredField-->" + declaredField.getName());
*/
}
return resultObject;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 首字母转大写
*
* @param s
* @return
*/
public static String toUpperFirstOne(String s) {
if (Character.isUpperCase(s.charAt(0))) {
return s;
} else {
return (new StringBuilder())
.append(Character.toUpperCase(s.charAt(0)))
.append(s.substring(1))
.toString();
}
}
/**
* 将一个json数组转化成List对象
* @param jsonStr json数组的字符串
* @param targetClass 要转化list的类型
* @param list泛型类型
* @return list的对象
*/
public static List parse2Objects(String jsonStr, Class targetClass) {
List resultList=new ArrayList<>();
try {
JSONArray jsonArray = new JSONArray(jsonStr);
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = new JSONObject(jsonArray.getString(i));
T t = JSONObjectUtil.parse2Object(jsonObject.toString(), targetClass);
resultList.add(t);
}
} catch (JSONException e) {
e.printStackTrace();
}
return resultList;
}
}
正常开发使用只带基本注释版本,其实删删注释也没多少
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class JSONObjectUtil {
/**
* 将一个json转化成一个对象
* @param jsonStr json字符串
* @param targetClass 需要转化的类型
* @param 类型的class类
* @return 返回的是T的实例化对象
*/
public static T parse2Object(String jsonStr, Class targetClass) {
try {
JSONObject jsonObject = new JSONObject(jsonStr);
Field[] targetClassFields = targetClass.getDeclaredFields();
Class c = Class.forName(targetClass.getName());
//将泛型类new出来
final T resultObject = (T) c.newInstance();
for (Field targetClassField : targetClassFields) {
//判断当前字段类型
Class> currentFieldType = targetClassField.getType();
//获取目标类中的所有方法,调用目标类中的所有set方法注入字段
Method[] targetClassMethods = targetClass.getDeclaredMethods();
//去json里面get("targetClassField"),然后去targetClass里面set+“targetClassField”
String targetClassFieldName = targetClassField.getName();
//现在里面就是具体的参数了, param好像是入参,value好像是出参用的
//Object jsonValue = jsonObject.get(targetClassFieldName);//如果直接getId获取到的是Integer,但是setId的时候需要Long类型
//所以这一行代码写在forEach里面,get+“bean里面的传入类型”
//调用的方法是targetClass里面set+“targetClassField”
System.out.println("\n\n\n\n");
Arrays.stream(targetClassMethods)
.filter(targetClassMethod -> targetClassMethod.getName().equals("set" + toUpperFirstOne(targetClassField.getName())))
.forEach(targetClassMethod -> {
try {
//jsonObject.get(targetClassFieldName);把这个方法替换成下面的jsonObjectGetMethod这个,因为当主键Id是1、2、3时,JSONObject默认帮我们生成的是Integer,但是我们需要的是Long
//这个方法就是JSONObject中的getLong/getString/getDouble
Method jsonObjectGetMethod = Arrays.stream(jsonObject.getClass().getDeclaredMethods())
.filter(jsonObjectMethod -> {
//获取到的是java.lang.String
Class> parameterType = targetClassMethod.getParameterTypes()[0];
String methodName="get" + parameterType.getName()
.substring(parameterType.getName().lastIndexOf(".") + 1);
if (methodName.contains("Int"))
methodName="getInt";
return jsonObjectMethod.getName().equals(methodName);
}).collect(Collectors.toList()).get(0);//里面一定只有一个方法,因为这是过滤bean的方法,bean里面不可能出现重载方法
Object jsonValue = jsonObjectGetMethod.invoke(jsonObject, targetClassFieldName);
targetClassMethod.invoke(resultObject, jsonValue);
} catch (Exception e) {
e.printStackTrace();
}
});
}
return resultObject;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 首字母转大写
*
* @param s
* @return
*/
public static String toUpperFirstOne(String s) {
if (Character.isUpperCase(s.charAt(0))) {
return s;
} else {
return (new StringBuilder())
.append(Character.toUpperCase(s.charAt(0)))
.append(s.substring(1))
.toString();
}
}
/**
* 将一个json数组转化成List对象
* @param jsonStr json数组的字符串
* @param targetClass 要转化list的类型
* @param list泛型类型
* @return list的对象
*/
public static List parse2Objects(String jsonStr, Class targetClass) {
List resultList=new ArrayList<>();
try {
JSONArray jsonArray = new JSONArray(jsonStr);
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = new JSONObject(jsonArray.getString(i));
T t = JSONObjectUtil.parse2Object(jsonObject.toString(), targetClass);
resultList.add(t);
}
} catch (JSONException e) {
e.printStackTrace();
}
return resultList;
}
}
2022 08 13
@RequiresApi(api = Build.VERSION_CODES.N)
public static List jsonToList(String jsonStr, Class targetClass){
List targetList=new ArrayList<>();
try {
JSONArray jsonArray=new JSONArray(jsonStr);
//遍历jsonArray
for(int i=0;i aClass) {
for (Method targetClassMethod : aClass.getDeclaredMethods()) {
String name = targetClassMethod.getName();
if(name.contains(convertInitialUpper(filterStr))&&name.contains("set")){
//System.out.println("返回方法="+targetClassMethod);
return targetClassMethod;
}
}
return null;
}
public static String convertInitialUpper(String word) {
// 方式二:效率高
char[] chars = word.toCharArray();
// 首字母转大写(ASCII编码前移)
chars[0] -= 32;
return new String(chars);
}