反射分装参数,获取注解值

                                                                反射分装参数,并根据类型赋值、获取方法上的注解

直接看下面代码:

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("插入失败,稍后再试"); } 
    
}}

猜你喜欢

转载自blog.csdn.net/qq_42112846/article/details/81432514
今日推荐