`
bewithme
  • 浏览: 423251 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

获取spring mvc映射的所有请求路径

阅读更多

      有时需要获取spring mvc映射的所有请求路径,比如在权限控制的功能模块中,而要配置某个资源与角色的对应关系,那么如果可以自动获取系统中所有的请求路径,那么可以在配置时方便许多。

 

第一步、获取指定包名下所有带@Controller注解的类。实现类代码如下

package com.ternnetwork.baseframework.util;

import java.io.IOException;  
import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.HashSet;  
import java.util.LinkedList;  
import java.util.List;  
import java.util.Set;  
  
import org.apache.commons.logging.Log;  
import org.apache.commons.logging.LogFactory;  
import org.springframework.core.io.Resource;  
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;  
import org.springframework.core.io.support.ResourcePatternResolver;  
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;  
import org.springframework.core.type.classreading.MetadataReader;  
import org.springframework.core.type.classreading.MetadataReaderFactory;  
import org.springframework.core.type.filter.AnnotationTypeFilter;  
import org.springframework.core.type.filter.TypeFilter;  
import org.springframework.util.ClassUtils;  
  
  
public class PackageClassesScaner {  
      
    protected final Log logger = LogFactory.getLog(getClass());  
      
    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 Set<Class<?>> classSet= new HashSet<Class<?>>();  
      
    /** 
     * 构造函数 
     * @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 Set<Class<?>> getClassSet() throws IOException, ClassNotFoundException {  
        this.classSet.clear();  
        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 className = reader.getClassMetadata().getClassName();  
                            if (matchesEntityTypeFilter(reader, readerFactory)) {  
                                this.classSet.add(Class.forName(className));  
                            }  
                        }  
                    }  
                }  
        }  
        //输出日志  
        if (logger.isInfoEnabled()){  
            for (Class<?> clazz : this.classSet) {  
                logger.info(String.format("Found class:%s", clazz.getName()));  
            }  
        }  
        return this.classSet;  
    }  
      
      
  
    /** 
     * 检查当前扫描到的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;  
    }  
    
    public List<String> getClassesNameList(){
    	 List<String> retVal=new ArrayList<String>();
	    
		try {
			Set<Class<?>> set= getClassSet();
			for(Class cls:set){
				retVal.add(cls.getName());
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		}
			return retVal;
			
    }
}

 

 

第二步、获取第一步得到所有类中带有@RequestMapping注解的path属性值并组装完成的请求路径

 

package com.ternnetwork.baseframework.util;

import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

public class MvcRequestMappingUtil {
	
	
	public static void main(String[] ags){
		//demo  填写你需要的包名
		String[] packagesToScan={"com.ternnetwork"};
		List<String> mvcRequestMappingList=MvcRequestMappingUtil.getMvcRequestMappingList(packagesToScan);
	}
	
	public static List<String> getMvcRequestMappingList(String[] packagesToScan){
		PackageClassesScaner packageClassesScaner=new PackageClassesScaner(packagesToScan,Controller.class);
		return getMvcRequestMappingList(packageClassesScaner.getClassesNameList());
	} 
	
	
	public static List<String> getMvcRequestMappingList(List<String> classNameList){
		
		List<String> retVal=new ArrayList<String>();
		for(String className:classNameList){
			getMvcRequestMappingListByClass(retVal, className);
		}
		return retVal;
		
	}


	private static void getMvcRequestMappingListByClass(List<String> retVal, String className) {
		try {
			
			Class<?> cls=Class.forName(className);
		
			Annotation[] classAnnotations=cls.getAnnotations();//得到类级别的所有注解

			int classRequestMappingCount=0;//类级别的RequestMapping统计
			
			for(Annotation classAnnotation:classAnnotations){
				
			    if(classAnnotation instanceof RequestMapping){
			    	
			    	classRequestMappingCount=classRequestMappingCount+1;
			    	
			    	Method annotationMethod = classAnnotation.getClass().getDeclaredMethod("value", null); 
			    	
		            String[] annotationValues = (String[])annotationMethod.invoke(classAnnotation, null);
		            
		            for (String classRequestMappingPath : annotationValues) {
		            	getMvcRequestMappingListByMethod(retVal, cls, classRequestMappingPath);  
		            }  
			    	
			    }
			}
			
		    if(classRequestMappingCount==0){//如果没有类级别的RequestMapping
		    	getMvcRequestMappingListByMethod(retVal, cls,""); 
		    }
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}


	private static void getMvcRequestMappingListByMethod(List<String> retVal, Class<?> cls, String classRequestMappingPath)throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
		Method[] methods =cls.getDeclaredMethods();
		for (Method method : methods) {  
		    if (method.isAnnotationPresent(RequestMapping.class)) {  
		        Annotation methodAnnotation = method.getAnnotation(RequestMapping.class);  
		        Method   methodAnnotationMethod=methodAnnotation.getClass().getDeclaredMethod("value", null);  
		        String[] values=(String[]) methodAnnotationMethod.invoke(methodAnnotation, null);  
		        for (String methodRequestMappingPath : values) {  
		        	methodRequestMappingPath=classRequestMappingPath.concat(methodRequestMappingPath).replace("*", "").replace("//", "/");
		        	retVal.add(methodRequestMappingPath.replaceFirst("/",""));
		        }  
		    }  
		}
	}
	

}

 

 

 

如果您觉得我的文章给了您帮助,请为我买一杯饮料吧!我将非常感激并坚持为大家提供更多帮助!

 

1
1
分享到:
评论

相关推荐

    Spring MVC 入门实例

    基于 Spring 的 Web 应用程序接收到 http://localhost:8080/hello.do(事实上请求路径是 /hello.do) 的请求后, Spring 将这个请求交给一个名为 helloController 的程序进行处理, helloController 再调用 一个名为 ...

    Spring MVC 3.0实战指南.ppt

    Spring MVC进行映射的依据 通过URL限定:URL表达式 通过URL限定:绑定{xxx}中的值 通过请求方法限定:请求方法 通过请求方法限定:代码示例 通过请求方法限定:模拟请求方法 通过请求/请求头参数限定:示例 通过请求/请求...

    Spring3MVC注解教程.ppt

    Spring MVC进行映射的依据 通过URL限定:URL表达式 通过URL限定:绑定{xxx}中的值 通过请求方法限定:请求方法 通过请求方法限定:代码示例 通过请求方法限定:模拟请求方法 通过请求/请求头参数限定:示例 通过...

    详解Spring mvc ant path的使用方法

    任何一个WEB都需要解决URL与请求处理器之间的映射,spring MVC也是一样,但Spring MVC就像Spring所作的一切一样(灵活,可以配置各种东西,但是也造成了很多复杂性),肯定不会只有一种方法来映射URL和 Controller之间...

    spring_MVC源码

    -- 启动Spring MVC的注解功能,完成请求和注解POJO的映射 --&gt; 14. &lt;bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" /&gt; 15. 16. &lt;!-- 对模型视图名称的解析...

    spring security 参考手册中文版

    5.1.3使用Spring MVC的AbstractSecurityWebApplicationInitializer 32 5.2 HttpSecurity 32 5.3 Java配置和表单登录 34 5.4授权请求 35 5.5处理注销 36 5.5.1 LogoutHandler 37 5.5.2 LogoutSuccessHandler 37 5.5.3...

    Spring in Action(第二版 中文高清版).part2

    B.2 单元测试Spring MVC控制器 B.2.1 模拟对象 B.2.2 断言ModelAndView的内容 B.3 使用Spring进行综合测试 B.3.1 测试装配后的对象 B.3.2 综合测试事务处理对象 B.3.3 测试数据库 B.3.4 使用Gienah Testing在...

    Spring in Action(第二版 中文高清版).part1

    B.2 单元测试Spring MVC控制器 B.2.1 模拟对象 B.2.2 断言ModelAndView的内容 B.3 使用Spring进行综合测试 B.3.1 测试装配后的对象 B.3.2 综合测试事务处理对象 B.3.3 测试数据库 B.3.4 使用Gienah Testing在...

    Spring中文帮助文档

    使用@RequestMapping映射请求 13.12.4. 使用@RequestParam绑定请求参数到方法参数 13.12.5. 使用@ModelAttribute提供一个从模型到数据的链接 13.12.6. 使用@SessionAttributes指定存储在会话中的属性 13.12.7. ...

    Spring API

    使用@RequestMapping映射请求 13.12.4. 使用@RequestParam绑定请求参数到方法参数 13.12.5. 使用@ModelAttribute提供一个从模型到数据的链接 13.12.6. 使用@SessionAttributes指定存储在会话中的属性 13.12.7. ...

    轻量级java web MVC框架

    下所有映射路径绑定处理方法上,假如在扫描包中定义下列类: import javax.imageio.ImageIO; import javax.servlet.ServletOutputStream; import javax.servlet.http.Cookie; import javax.servlet....

    Spring MVC中的DispatcherServlet的使用

    Servlet 自定义的 `Servlet` 继承 `HttpServlet` (Java 服务端组件,接收 HTTP 请求,调用业务逻辑,完成 HTTP 响应) Servlet 生命周期(容器...默认一个 Servlet 映射一个 URL 路径 /user–&gt; UserSe

    Spring Boot中文文档.rar

    将错误页面映射到Spring MVC之外 28.1.12.Spring HATEOAS 28.1.13.CORS支持 28.2.“Spring WebFlux框架” 28.2.1.Spring WebFlux自动配置 28.2.2.带有HttpMessageReaders和HttpMessageWriters的...

    整合SpringMVC、Spring、Mybatis开发信息管理系统

    使用SpringMVC,你可以定义处理器方法(Controller),并使用注解将这些方法映射到特定的URL路径。此外,SpringMVC还提供了与视图解析器一起使用的功能,用于将模型数据渲染为最终的响应。 Spring框架是一个全功能...

    Spring面试题

    -(1)检索和用户请求匹配的ActionMapping实例,如果不存在,就返回请求路径无效信息; -(2)如果ActionForm实例不存在,就创建一个ActionForm对象,把客户提交的表单数据保存到ActionForm对象中; -(3)根据配置信息决定...

    charon-spring-boot-starter:以Spring Boot启动器形式的反向代理实现

    Charon Spring启动启动器 Charon是反向代理实现。...产品特点高度可配置和可扩展Spring 和支持多请求转发映射负载均衡灵活的路径重写支持基于指标异步请求转发认证方式Cookies改写“ X转发” HTTP标头支持转发过

    手写springmvc

    Spring MVC 通过 @RequestMapping 注解将 URL 请求与业务方法进行进行映射。 在控制器的类定义处以及方法定义处都可添加 @RequestMapping,在类定义处添加 @RequestMapping 注解,相当于多了一层访问路径。

    java web技术开发大全(最全最新)

    JSP+Servlet+Struts+Hibernate+Spring+Ajax》重点讲解了Struts 2、Speing和HIbernate框架的基础知识和高级技术,如Sruts 2中的*、类型转换、国际化和标签等,HIbe rna{e的会话、0/R映射和事务管理等,Spring中的...

    java web开发技术大全

    JSP+Servlet+Struts+Hibernate+Spring+Ajax》重点讲解了Struts 2、Speing和HIbernate框架的基础知识和高级技术,如Sruts 2中的*、类型转换、国际化和标签等,HIbe rna{e的会话、0/R映射和事务管理等,Spring中的...

    JAVA程序开发大全---上半部分

    1.3 获取和阅读MyEclipse帮助文档 5 1.4 本章小结 5 第2章 MyEclipse集成开发环境的使用 6 2.1 MyEclipse集成开发工具界面 6 2.1.1 MyEclipse的菜单栏 7 2.1.2 MyEclipse的工具栏 13 2.1.3 MyEclipse的透视图 14 ...

Global site tag (gtag.js) - Google Analytics