1、权限对象:
public class RightPath {
int id;
int fartherId;
String url;
String name;
public RightPath(int id,int fartherId,String url,String name){
this.id = id;
this.fartherId = fartherId;
this.url = url;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getFartherId() {
return fartherId;
}
public void setFartherId(int fartherId) {
this.fartherId = fartherId;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
2、自定义注解:
/**
* 控制器路径名注解
* Created by ly on 2017/1/12.
*/
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface PathDescription {
public String pathName() default "";
}
3、控制器使用:
@RequestMapping(value = "/getProvinceList",method = RequestMethod.POST)
@ResponseBody
@PathDescription(pathName = "省份管理")
public String GetProvinceList(HttpServletRequest request) throws IOException {
String s = HttpPost.submitPostData( "/province/list",null);
return s;
}
4、扫描:
public class PackageClassesScaner {
private static final String RESOURCE_PATTERN = "/**/*.class";
private ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
private List<String> packagesList = new LinkedList<String>();
private List<TypeFilter> typeFilters = new LinkedList<TypeFilter>();
private Map<String, String> classSet = new LinkedHashMap<>();
/**
* 构造函数
*
* @param packagesToScan 指定哪些包需要被扫描,支持多个包"package.a,package.b"并对每个包都会递归搜索
* @param annotationFilter 指定扫描包中含有特定注解标记的bean,支持多个注解
*/
public PackageClassesScaner(String[] packagesToScan, Class<? extends Annotation>... annotationFilter) {
if (packagesToScan != null) {
for (String packagePath : packagesToScan) {
this.packagesList.add(packagePath);
}
}
if (annotationFilter != null) {
for (Class<? extends Annotation> annotation : annotationFilter) {
typeFilters.add(new AnnotationTypeFilter(annotation, false));
}
}
}
/**
* 将符合条件的Bean以Class集合的形式返回
*
* @return
* @throws IOException
* @throws ClassNotFoundException
*/
public List<RightPath> getClassSet() throws IOException, ClassNotFoundException {
List<RightPath> list = new ArrayList<>();
int id = 0;
if (!this.packagesList.isEmpty()) {
for (String pkg : this.packagesList) {
String pattern = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
ClassUtils.convertClassNameToResourcePath(pkg) + RESOURCE_PATTERN;
Resource[] resources = this.resourcePatternResolver.getResources(pattern);
MetadataReaderFactory readerFactory = new CachingMetadataReaderFactory(this.resourcePatternResolver);
for (Resource resource : resources) {
if (resource.isReadable()) {
MetadataReader reader = readerFactory.getMetadataReader(resource);
String pathName = getPathName(reader);//获取注解名称,即路径的中文含义
String urlPath = getUrl(reader);
if (matchesEntityTypeFilter(reader, readerFactory)) {
if (!urlPath.isEmpty()) {
list.add(new RightPath(id, 0, urlPath, pathName));
int fartherId = id;
id++;
//获取控制器中的方法
Set<MethodMetadata> ss = reader.getAnnotationMetadata().getAnnotatedMethods(RequestMapping.class.getName());
for (MethodMetadata mdata :
ss) {
pathName = getPathName(mdata);
String mthPath = getUrl(mdata);
list.add(new RightPath(id, fartherId, urlPath + mthPath, pathName));
id++;
}
}
}
}
}
}
}
return list;
}
/**
* 获取控制器注解中的 pathName
*
* @param reader
* @return
*/
private String getPathName(MetadataReader reader) {
if (reader.getAnnotationMetadata().getAnnotationAttributes(com.jiapeng.util.PathDescription.class.getName()) != null) {
return reader.getAnnotationMetadata().getAnnotationAttributes(com.jiapeng.util.PathDescription.class.getName()).get("pathName").toString();
} else {
return "";
}
}
/**
* 获取方法注解中的 pathName
* @param mdata
* @return
*/
private String getPathName(MethodMetadata mdata){
if (mdata.getAnnotationAttributes(com.jiapeng.util.PathDescription.class.getName()) != null) {
return mdata.getAnnotationAttributes(com.jiapeng.util.PathDescription.class.getName()).get("pathName").toString();
}else{
return "";
}
}
/**
* 获取控制器映射的地址
* @param reader
* @return
*/
private String getUrl(MetadataReader reader){
AnnotationAttributes attributes = (AnnotationAttributes) reader.getAnnotationMetadata().getAnnotationAttributes(RequestMapping.class.getName());
String urlPath = "";
if (attributes != null) {
String[] values = attributes.getStringArray("value");
if (values.length > 0) {
urlPath = values[0];
}
}
return urlPath;
}
/**
* 获取方法映射的地址
* @param mdata
* @return
*/
private String getUrl(MethodMetadata mdata){
AnnotationAttributes att = (AnnotationAttributes) mdata.getAnnotationAttributes(RequestMapping.class.getName());
String mthPath = "";
if (att != null) {
String[] values = att.getStringArray("value");
if (values.length > 0) {
String tmp = values[0];
if (tmp.indexOf("{") != -1) {
tmp = tmp.substring(0, tmp.lastIndexOf("/"));
}
if (tmp.indexOf("/") > 0 || tmp.indexOf("/")==-1) {
tmp = "/" + tmp;
}
mthPath = tmp;
}
}
return mthPath;
}
/**
* 检查当前扫描到的Bean含有任何一个指定的注解标记
*
* @param reader
* @param readerFactory
* @return
* @throws IOException
*/
private boolean matchesEntityTypeFilter(MetadataReader reader, MetadataReaderFactory readerFactory) throws IOException {
if (!this.typeFilters.isEmpty()) {
for (TypeFilter filter : this.typeFilters) {
if (filter.match(reader, readerFactory)) {
return true;
}
}
}
return false;
}
}
5、结果:
@Test
public void testScanPackage() throws IOException, ClassNotFoundException {
String[] pack={"com.xfw.controller","com.exportStu.controller"};
PackageClassesScaner packageClassesScaner = new PackageClassesScaner(pack, Controller.class);
List<RightPath> list = packageClassesScaner.getClassSet();
System.out.println(list);
}