反射分装参数,并根据类型赋值、获取方法上的注解
直接看下面代码:
package com.ww.utils;
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.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* . ____ _ __ _ _
* /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
* ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
* \\/ ___)| |_)| | | | | || (_| | ) ) ) )
* ' |____| .__|_| |_|_| |_\__, | / / / /
* =========|_|==============|___/=/_/_/_/
* :: Spring Boot :: (v2.0.2.RELEASE)
* <p>
* 信不信我名字起的越长你们越容易记得住
* 这么长的名字就是为了让你们记住我
* 我就是我颜色不一样的烟火
* ----阿拉蕾
**/
public class paramesUtils {
public static SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy/MM//dd");
public static Map<Class, Convert> convertMap=new HashMap<Class, Convert>();
public static void redist(Class clazz,Convert convert){
convertMap.put(clazz,convert);
}
//这个工具类的作用是将请求的参数分装到对象当
//首先获取所有的请求参数对象
//逐个遍历请求参数,将每个参数的值封装到对象上面与参数名一致的属性上面
//两个问题
//如何获取每个参数的name和value?
//如何根据参数name找到相应对象上的属性
//很简单 反射
public static <T> T fillDate(Map<String,String[]> params,Class<T> clazz) throws IllegalAccessException, InstantiationException, NoSuchFieldException, IntrospectionException, InvocationTargetException, ParseException {
//首先创建用于封装参数的对象
T instance = clazz.newInstance();
//获取每一个参数的键值对,键是表单的那么,相当于对象的属性名,而值就是给对象的这个属性赋的值
Set<Map.Entry<String, String[]>> entries = params.entrySet();
//对得到的集合遍历
for (Map.Entry<String, String[]> entry : entries) {
//获取每一个表单上的属性名
String key = entry.getKey();
//获取
String[] value = entry.getValue();
//根据key去找对应对象的属性,将value设置过去
Field field = clazz.getField(key);
if (field != null) {
//找到变量了
//给变量赋值
//这个变量可能是私有
field.setAccessible(true);//强制允许访问
field.set(instance,value);
}
//上面直接使用变量名的方式,会打破对象的封装性
//所以实际上应该使用的是get set方法去操所属性
//获取属性描述器,参数代表的是获取的是clazz当中的key属性
PropertyDescriptor propertyDescriptor=new PropertyDescriptor(key,clazz);
if (propertyDescriptor != null) {
//如果有属性,获取这个属性的set
Method writeMethod = propertyDescriptor.getWriteMethod();
//根据参数类型来赋值,用得到的方法;来获取其返回值的类型
Class<?>[] parameterTypes = writeMethod.getParameterTypes();
if(parameterTypes[0]==String.class){
writeMethod.invoke(instance,value);
}else if(parameterTypes[0]==int.class || parameterTypes[0]==InternalError.class){
//如果是进行数字转换,说明参数的长度应该有且只能是1
if (value.length!=1) {
//则证明是参数类型不合法
//参考具体的业务要求决定当前参数是只是去第一个还是抛出异常
throw new RuntimeException(key+"参数长度超出范围");
}
//转换
int i = Integer.parseInt(value[0]);
writeMethod.invoke(instance,i);
}else if(parameterTypes[0]==String[].class){
//如果此时直接设置或抛出rong number of arguments异常
//如果是一个引用类型的数组需要进行转换
//将字符数组转换为obj数组
Object[] object=new Object[]{value};
writeMethod.invoke(instance,object);
}else if(parameterTypes[0]==int[].class||parameterTypes[0]==Integer[].class){
//根据参数长度创建一个一样长度的数字数组
int[] ints=new int[value.length];
for(int i=0;i<value.length;i++){
String s=value[i];
ints[i] = Integer.parseInt(s);
}
writeMethod.invoke(instance,ints);
}else if(parameterTypes[0]==Date.class){
Convert convert = convertMap.get(Date.class);
Date date=null;
if (convert != null) {
date =(Date) convert.convert(value[0]);
}else{
date=simpleDateFormat.parse(value[0]);
}
writeMethod.invoke(instance,date);
}
}
}
return instance;
}
}
反射获取方法上面的注解:
package com.ww.utils;
import com.ww.annocation.PermissionInfo;
import com.ww.dto.PermissionDto;
import com.ww.dto.respDto;
import com.ww.service.DNSService;
import com.ww.service.DNSServiceImpl;
import com.ww.service.UserService;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngineConfiguration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import javax.annotation.PostConstruct;
import java.io.File;
import java.lang.reflect.Method;
import java.util.*;
@Controller
public class AnnotationUtils {
public static List<PermissionDto> process(Class clazz) {
//找方法
List<PermissionDto> list=new ArrayList<>();
Method[] methods = clazz.getMethods();
for (Method method : methods) {
PermissionInfo annotation = method.getAnnotation(PermissionInfo.class);//获取指定类型的注解
//动态代理对象,
if (annotation != null) {
//说明有注解,此为封装的注解对象,想获取那些值分装即可
PermissionDto dto=new PermissionDto();
String name = annotation.name();
String[] permissions = annotation.permissions();
String url = annotation.url();
// String[] roles = annotation.roles();
String name1 = method.getName();
String s = Arrays.toString(permissions);
String substring = s.substring(s.indexOf("[") + 1, s.lastIndexOf("]"));
// String s1 = Arrays.toString(roles);
dto.setUrl(url);
dto.setPerms(substring);
dto.setMenuname(name);
// dto.setRole(s1);
list.add(dto);
// System.out.println("方法名为:" + name1 + "上面的描述是:" + " 地址是 " + url + " 是否需要登录 " + authc
// + " 需要的权限是: " + Arrays.toString(permissions) + " 需要的角色是:" +
);
}
}
return list;
}
//测试注解的功能
//首先应该写一个注解
public static Map<String,List<PermissionDto>> sss(Object o) throws ClassNotFoundException {
PermissionDto dto=null;
List<PermissionDto> list=new ArrayList<>();
Map<String,List<PermissionDto>> map=new HashMap<>();
// TestController testController=new TestController();
// utils.process(testController);
//获取当前类的全限定名称,主要目的是为了获取其包名
String name = o.getClass().getName();
// System.out.println(name);
//对类名进行切割获取包名
String substring = name.substring(0, name.lastIndexOf("."));
// System.out.println(substring.replaceAll("\\.","/"));
// System.out.println(substring);
//获取当前类所在的绝对路径
String path = o.getClass().getClassLoader().getResource("").getPath();
//将包名当中的.替换为/,并以目录的绝对路径为包名作为最终的路径,创建file,为了获取下面所有的文件
File file = new File(path + substring.replaceAll("\\.", "/"));
String pagePath = substring.replaceAll("\\.", "/");
// System.out.println(file+"========="+file.listFiles()+"======="+path);
File[] files = file.listFiles();
if (files != null) {
//获取每一个class
//解析里面的注解
for (File file1 : files) {
String fileName = file1.getName();
String leiName=fileName.substring(0, fileName.lastIndexOf("."));
//重新拼接
String className = substring + "." + fileName.substring(0, fileName.lastIndexOf("."));
Class<?> aClass = Class.forName(className);//获取类对象
List<PermissionDto> process = AnnotationUtils.process(aClass);//解析文件
map.put(leiName,process);
}
}
return map;
}
}
获取返回的值:
public class aaa(){public static void main(String[] args) {try { Map<String, List<PermissionDto>> sss = AnnotationUtils.sss(this); for (String s : sss.keySet()) { List<PermissionDto> list = sss.get(s); PermissionDto dto=new PermissionDto(); dto.setMenuname(s); for (PermissionDto permissionDto : list) { dto.setPerms(permissionDto.getPerms()); dto.setUrl(permissionDto.getUrl()); dto.setMenuname(permissionDto.getMenuname()); userService.addPemission(dto); } } } catch (ClassNotFoundException e) { e.printStackTrace(); throw new YunException("插入失败,稍后再试"); }
}}