由于业务要求,通过openfeign调用别人的http接口后,返回的值是一个jsonObject和jsonArray的组合格式比较复杂,那么它的字段与实体的字段名字是不对应,只需获取到它的value的key的值到各个字段里,那么问题来了,这个值是属于哪个字段的值呢,好在这些值的顺序就是字段顺序,那么我只需要通过反射遍历实体类的属性的set方法去赋值即可
package com.zhaohy.app.utils;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import com.zhaohy.app.entity.User;
/**
* 反射工具类
* @author zhaohy
*
*/
public class ReflectUtil {
/**
* 根据属性,获取get方法
*
* @param ob 对象
* @param name 属性名
* @return
* @throws Exception
*/
public static Object getGetMethod(Object ob, String name) throws Exception {
Method[] m = ob.getClass().getMethods();
for (int i = 0; i < m.length; i++) {
if (("get" + name).toLowerCase().equals(m[i].getName().toLowerCase())) {
return m[i].invoke(ob);
}
}
return null;
}
/**
* 根据属性,拿到set方法,并把值set到对象中
*
* @param obj 对象
* @param clazz 对象的class
* @param typeClass
* @param value
* 示例: DataReq req=new DataReq();
* String field2 = "start"; 属性名
* ReflectUtil.setValue(req,DataReq.class,field2,DataReq.class.getDeclaredField(field2).getType(),"汪汪");
*
*
*/
public static void setValue(Object obj, Class<?> clazz, String filedName, Class<?> typeClass, Object value) {
filedName = removeLine(filedName);
String methodName = "set" + filedName.substring(0, 1).toUpperCase() + filedName.substring(1);
try {
Method method = clazz.getDeclaredMethod(methodName, new Class[] { typeClass });
method.invoke(obj, new Object[] { getClassTypeValue(typeClass, value) });
} catch (Exception ex) {
ex.printStackTrace();
}
}
/**
* 通过class类型获取获取对应类型的值
*
* @param typeClass class类型
* @param value 值
* @return Object
*/
private static Object getClassTypeValue(Class<?> typeClass, Object value) {
if (typeClass == int.class || value instanceof Integer) {
if (null == value) {
return 0;
}
return value;
} else if (typeClass == short.class) {
if (null == value) {
return 0;
}
return value;
} else if (typeClass == byte.class) {
if (null == value) {
return 0;
}
return value;
} else if (typeClass == double.class) {
if (null == value) {
return 0;
}
return value;
} else if (typeClass == long.class) {
if (null == value) {
return 0;
}
return value;
} else if (typeClass == String.class) {
if (null == value) {
return "";
}
return value;
} else if (typeClass == boolean.class) {
if (null == value) {
return true;
}
return value;
} else if (typeClass == BigDecimal.class) {
if (null == value) {
return new BigDecimal(0);
}
return new BigDecimal(value + "");
} else {
return typeClass.cast(value);
}
}
/**
* 处理字符串 如: abc_dex ---> abcDex
*
* @param str
* @return
*/
public static String removeLine(String str) {
if (null != str && str.contains("_")) {
int i = str.indexOf("_");
char ch = str.charAt(i + 1);
char newCh = (ch + "").substring(0, 1).toUpperCase().toCharArray()[0];
String newStr = str.replace(str.charAt(i + 1), newCh);
String newStr2 = newStr.replace("_", "");
return newStr2;
}
return str;
}
public static void main(String[] args) {
User user = new User();
user.setUserId(1);
user.setUserName("zhaohy");
user.setSex(1);
user.setJob("programmer");
user.setEmail("[email protected]");
System.out.println("通过反射遍历实体类属性,和值");
//通过反射遍历实体类属性,和值
Field[] fields = User.class.getDeclaredFields();
for(Field field: fields) {
//反射时让私有变量变成可访问
field.setAccessible(true);
try {
System.out.println("实体类的属性名称:" + field.getName() + " 类型:" + field.getType() + " 属性的值:" + field.get(user));
} catch (Exception e) {
e.printStackTrace();
}
}
System.out.println("遍历实体类的方法名");
//遍历实体类的方法名
Method[] methods = User.class.getMethods();
for(Method method:methods) {
System.out.println("实体类的方法名:" + method.getName());
}
System.out.println("获取值方法二:通过拼接get方法来获取值打印get方法的值,注意如果是boolean类型需要做特殊处理");
//获取值方法二:通过拼接get方法来获取值打印get方法的值,注意如果是boolean类型需要做特殊处理
for(Field field: fields) {
try {
System.out.println("实体类的属性名称:" + field.getName() + " 类型:" + field.getType() + " 属性的值:" + getGetMethod(user, field.getName()));
} catch (Exception e) {
e.printStackTrace();
}
}
System.out.println("通过反射来给属性赋值方法一");
//通过反射来给属性赋值方法一
for(Field field: fields) {
//反射时让私有变量变成可访问
field.setAccessible(true);
try {
if(field.getName().equals("userName")) {
field.set(user, "zhaohyTest");
}
System.out.println("实体类的属性名称:" + field.getName() + " 类型:" + field.getType() + " 属性的值:" + field.get(user));
} catch (Exception e) {
e.printStackTrace();
}
}
System.out.println("通过反射来给属性赋值方法二,拼接setget方法的方式,注意如果是boolean类型需要做特殊处理");
//通过反射来给属性赋值方法二,拼接setget方法的方式,注意如果是boolean类型需要做特殊处理
for(Field field: fields) {
try {
if(field.getName().equals("userName")) {
setValue(user, User.class, field.getName(), field.getType(), "zhaohyTest2");
}
System.out.println("实体类的属性名称:" + field.getName() + " 类型:" + field.getType() + " 属性的值:" + getGetMethod(user, field.getName()));
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
通过反射遍历实体类属性,和值
实体类的属性名称:userId 类型:class java.lang.Integer 属性的值:1
实体类的属性名称:userName 类型:class java.lang.String 属性的值:zhaohy
实体类的属性名称:sex 类型:class java.lang.Integer 属性的值:1
实体类的属性名称:job 类型:class java.lang.String 属性的值:programmer
实体类的属性名称:email 类型:class java.lang.String 属性的值:[email protected]
遍历实体类的方法名
实体类的方法名:getUserId
实体类的方法名:getUserName
实体类的方法名:getSex
实体类的方法名:getJob
实体类的方法名:getEmail
实体类的方法名:setUserId
实体类的方法名:setUserName
实体类的方法名:setSex
实体类的方法名:setJob
实体类的方法名:setEmail
实体类的方法名:wait
实体类的方法名:wait
实体类的方法名:wait
实体类的方法名:equals
实体类的方法名:toString
实体类的方法名:hashCode
实体类的方法名:getClass
实体类的方法名:notify
实体类的方法名:notifyAll
获取值方法二:通过拼接get方法来获取值打印get方法的值,注意如果是boolean类型需要做特殊处理
实体类的属性名称:userId 类型:class java.lang.Integer 属性的值:1
实体类的属性名称:userName 类型:class java.lang.String 属性的值:zhaohy
实体类的属性名称:sex 类型:class java.lang.Integer 属性的值:1
实体类的属性名称:job 类型:class java.lang.String 属性的值:programmer
实体类的属性名称:email 类型:class java.lang.String 属性的值:[email protected]
通过反射来给属性赋值方法一
实体类的属性名称:userId 类型:class java.lang.Integer 属性的值:1
实体类的属性名称:userName 类型:class java.lang.String 属性的值:zhaohyTest
实体类的属性名称:sex 类型:class java.lang.Integer 属性的值:1
实体类的属性名称:job 类型:class java.lang.String 属性的值:programmer
实体类的属性名称:email 类型:class java.lang.String 属性的值:[email protected]
通过反射来给属性赋值方法二,拼接setget方法的方式,注意如果是boolean类型需要做特殊处理
实体类的属性名称:userId 类型:class java.lang.Integer 属性的值:1
实体类的属性名称:userName 类型:class java.lang.String 属性的值:zhaohyTest2
实体类的属性名称:sex 类型:class java.lang.Integer 属性的值:1
实体类的属性名称:job 类型:class java.lang.String 属性的值:programmer
实体类的属性名称:email 类型:class java.lang.String 属性的值:[email protected]
//所有get方法和set方法
public void getMethod(Object obj){
Class<...> clazz=obj.getClass();//获得实体类名
Field[] fields = obj.getDeclaredFields();//获得属性
//获得Object对象中的所有方法
for(Field field:fields){
PropertyDescriptor pd = new PropertyDescriptor(field.getName(), clazz);
Method getMethod = pd.getReadMethod();//获得get方法
//getMethod.invoke(obj);//此处为执行该Object对象的get方法
Method setMethod = pd.getWriteMethod();//获得set方法
//setMethod.invoke(obj,"参数");//此处为执行该Object对象的set方法
}
}
//读取某个类下所有变量的名称
public void getMethod(Class clz) {
// 获取f对象对应类中的所有属性域
Field[] fields = clz.getDeclaredFields();
for (int i = 0, len = fields.length; i < len; i++) {
// 对于每个属性,获取属性名
String varName = fields[i].getName();
System.out.println("变量名称为:"+varName);
}
}
@SneakyThrows
public static void main(String[] args) {
Class<PvTelemeterStatus> pv = PvTelemeterStatus.class;
Field[] fields = pv.getDeclaredFields();
// System.out.println(fields.length);
PvTelemeterStatus p = new PvTelemeterStatus();
for (int i=0 ; i<fields.length ; i++){
System.out.println(fields[i].getName());
PropertyDescriptor pd = new PropertyDescriptor(fields[i].getName(), pv);
Method readMethod = pd.getReadMethod();
Method writeMethod = pd.getWriteMethod();
Class<?> type = fields[i].getType();
if(type == Float.class){
writeMethod.invoke(p,5.23f);//此处为执行该Object对象的set方法
}else if (type == Integer.class){
writeMethod.invoke(p,1);//此处为执行该Object对象的set方法
}else {
writeMethod.invoke(p,"11");//此处为执行该Object对象的set方法
}
}
System.out.println(p);
}
获取class -> 获取Field[] -> PropertyDescriptor传入字段名和class -> pd.getWriteMethod()获取写入方法 -> writeMethod.invoke触发写入方法
Class<PvTelemeterStatus> telemeterClass = PvTelemeterStatus.class;
Field[] telemeterFields = telemeterClass.getDeclaredFields();
PvTelemeterStatus pvTelemeterStatus = new PvTelemeterStatus();
pvTelemeterStatus.setDeviceId((String) guid);
for (int j =0 ; j < telemeterFields.length - 3 ; j++){
PropertyDescriptor pd = new PropertyDescriptor(telemeterFields[j+3].getName(), telemeterClass);
Method writeMethod = pd.getWriteMethod();
Class<?> type = telemeterFields[j+3].getType();
Object value = points.getJSONObject(j).get("value");
Object timestamp = points.getJSONObject(j).get("timestamp");
if ("invStatus".equals(telemeterFields[j+3].getName())){
LocalDateTime localDateTime = LocalDateTime.ofEpochSecond(Long.valueOf(timestamp.toString()), 0, ZoneOffset.ofHours(8));
pvTelemeterStatus.setAcquisitionTime(localDateTime);
writeMethod.invoke(pvTelemeterStatus, ReflectUtil.getClassTypeValue(type,value));//此处为执行该Object对象的set方法
}else{
writeMethod.invoke(pvTelemeterStatus, ReflectUtil.getClassTypeValue(type,value));//此处为执行该Object对象的set方法
}
}
pvTelemeterService.save(pvTelemeterStatus);
/**
* 通过class类型获取获取对应类型的值
*
* @param typeClass class类型
* @param value 值
* @return Object
*/
public static Object getClassTypeValue(Class<?> typeClass, Object value) {
if (typeClass == Integer.class || value instanceof Integer) {
if (null == value) {
return 0;
}
return Integer.valueOf((String) value);
} else if (typeClass == Short.class) {
if (null == value) {
return 0;
}
return Short.parseShort((String) value);
} else if (typeClass == Double.class) {
if (null == value) {
return 0;
}
return Double.parseDouble((String) value);
} else if (typeClass == Float.class) {
if (null == value) {
return 0;
}
return Float.parseFloat((String) value);
} else if (typeClass == Long.class) {
if (null == value) {
return 0;
}
return Long.parseLong((String) value);
} else if (typeClass == String.class) {
if (null == value) {
return "";
}
return String.valueOf(value);
} else if (typeClass == Boolean.class) {
if (null == value) {
return true;
}
return Boolean.parseBoolean((String) value);
} else if (typeClass == BigDecimal.class) {
if (null == value) {
return new BigDecimal(0);
}
return new BigDecimal(value + "");
} else {
return typeClass.cast(value);
}
}
这里说下为什么要telemeterFields[j+3].getName() ,因为这个类的前三个字段返回的数据没有这个三个字段的值,所以把他们跳过