赞
踩
Java根据自定义注解对接口权限控制
一、前言
最近公司要求对项目的权限控制颗粒度到接口层面,原计划按照swagger注解扫描所有controller层url,并按层级维护树级结构资源,然后持久层到数据库表。
由于swagger会扫出所有接口切有一些无用url,最终决定自定义注解进行进行配置及扫描
下面将注解以及表结构放如下:
二、表结构与代码实例
create table res ( id bigint not null comment 'id' primary key, res_name varchar(255) null comment '资源名', res_url varchar(255) null comment '资源路径', res_type bigint null comment '1-控制层,0-url层', parent_url varchar(64) null comment '上级资源路径', parent_id bigint null comment '上级资源id', created_Iname varchar(32) null comment '创建用户登录名', created_name varchar(32) null comment '创建用户真名', updated_Iname varchar(32) null comment '更新用户登录名', updated_name varchar(32) null comment '更新用户真名', disp_or int null comment '插入时,默认赋值排序', tenant_id bigint null comment '租户id', up_ver int null comment '乐观锁', created_time datetime default CURRENT_TIMESTAMP null comment '创建时间', updated_time datetime default CURRENT_TIMESTAMP null comment '更新时间' ) comment '接口资源表'; /** 资源标记,该注解标记至class 和 method上 * @author zhouyou */ @Retention(RetentionPolicy.RUNTIME) @Target(value = {ElementType.METHOD, ElementType.TYPE}) public @interface TagResource { /** * tag use type : * @return */ String type() default ""; /** * if annotation effect on method */ String value() default ""; }
三、实现思路
1、获取类上注解
2、封装返回map与bimap
* 获取所有接口方法及注释 * * @param control * @param resultList */ private void getMethod(Map<String, String> control, List<Map<String, String>> resultList, BiMap<String, String> queryMap) { // 要扫描的包以此来获取类上注解 // TODO 常量最后取配置 String packageName = "com.xx.controller"; Reflections f = new Reflections(packageName); // 获取扫描到的标记注解的集合 Set<Class<?>> resources = f.getTypesAnnotatedWith(TagResource.class); for (Class<?> c : resources) { // 循环获取标记的注解 try { TagResource tag = c.getAnnotation(TagResource.class); // 两个注解的值未填写规范这里都会抛异常 RequestMapping mapping = c.getAnnotation(RequestMapping.class); // 获取类上注解及值 queryMap.put(c.getName(), tag.value()); control.put(mapping.value()[0], tag.value()); } catch (IllegalArgumentException e) { BusinessException.throwBiz("value already present"); } catch (NullPointerException e) { BusinessException.throwBiz("请检查@RequestMapping与@TagResource是否匹配"); } } // 获取所有请求接口并遍历 RequestMappingHandlerMapping mapping = (RequestMappingHandlerMapping) applicationContext.getBean("requestMappingHandlerMapping"); Map<RequestMappingInfo, HandlerMethod> map = mapping.getHandlerMethods(); for (Map.Entry<RequestMappingInfo, HandlerMethod> handlerMethodEntry : map.entrySet()) { RequestMappingInfo requestMappingInfo = handlerMethodEntry.getKey(); HandlerMethod handlerMethod = handlerMethodEntry.getValue(); // 取类名 如果当前接口类上没有注解跳过 String className = handlerMethod.getMethod().getDeclaringClass().getName(); if (ObjectUtil.isNull(queryMap.get(className))) { continue; } Map<String, String> resultMap = new LinkedHashMap<>(); // 得到方法上注解 Annotation[] annotations = handlerMethod.getMethod().getDeclaredAnnotations(); // 如果类上未加TagResource注解那么方法上无法管理 if (annotations != null) { // 处理具体的方法信息 for (Annotation annotation : annotations) { if (annotation instanceof TagResource) { TagResource methodDesc = (TagResource) annotation; //接口描述 resultMap.put("methodName", methodDesc.value()); resultMap.put("className", className); PatternsRequestCondition p = requestMappingInfo.getPatternsCondition(); for (String url : p.getPatterns()) { //将当前接口URL封装 resultMap.put("methodURL", url); } break; } } } if (resultMap.size() > 0) { resultList.add(resultMap); } } }
四、最终目标
最终按想要的数据结构将数据封装处理后存入数据结构,并将结构存入redis
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。