`
bewithme
  • 浏览: 431579 次
  • 性别: 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 MVC最常用的方式,它通过在控制器类的方法上使用`@RequestMapping`注解来定义请求路径。例如: ```java @Controller public class MyController { @RequestMapping("/hello") public...

    Spring mvc5.0.3 所有jar包

    7. **参数绑定**: Spring MVC可以自动将请求参数绑定到Controller方法的参数上,无需手动获取。支持的参数类型包括基本类型、复杂对象、数组和集合。 8. **数据验证**: 通过集成JSR-303/JSR-349(Bean Validation)...

    SPRING MVC 的请求参数获取的几种方法

    SPRING MVC 请求参数获取的几种方法 SPRING MVC 框架中,获取请求参数是非常重要的一步,下面将介绍 SPRING MVC 中获取请求参数的几种方法。 1. 使用 @PathVariable 注解获取路径中传递参数 在 SPRING MVC 中,...

    最全的Spring MVC注解例子,异步请求,错误处理

    总的来说,这个压缩包提供了学习和实践Spring MVC注解的全面示例,涵盖了核心的控制器定义、请求映射、数据绑定,以及异步处理和错误处理机制。通过这个例子,开发者能够更好地理解和掌握Spring MVC的使用,提升其在...

    Spring MVC 4.2.3

    Spring MVC通过DispatcherServlet作为入口点,接收HTTP请求,然后根据请求映射信息分发到相应的处理器。 在Spring MVC 4.2.3中,主要包含了以下关键特性: 1. **类型安全的路径变量**:这个版本引入了类型安全的...

    Spring MVC使用Demo

    `@RequestParam`用于从请求参数中获取值,`@PathVariable`用于处理URL路径变量,`@ModelAttribute`则常用于绑定表单数据到模型对象。 此外,Spring MVC提供了ModelAndView类,它可以将处理结果(模型数据)和视图名...

    spring mvc 4.0

    4. **路径变量**:在@RequestMapping注解中,可以使用路径变量(path variables)来获取URL中的动态部分,增强了路由的灵活性。 5. **RESTful支持**:4.0版本增强了对RESTful Web服务的支持,通过@RequestMapping和...

    Spring mvc 教程

    - **使用@RequestMapping 注解映射请求路径**:此注解用于指定控制器处理的具体 URL 路径。 - **定义@RequestMapping 注解的处理方法**:控制器类中的方法可以使用 @RequestMapping 来映射特定的 HTTP 请求。 - *...

    Mastering Spring MVC 4(2015.09)源码

    视图解析器是Spring MVC中用于确定视图名对应的实际资源路径的组件。例如,InternalResourceViewResolver可以将视图名转换为JSP页面的URL。 依赖注入(Dependency Injection, DI)是Spring框架的核心特性之一。在...

    spring-MVC.zip_Java spring mvc_spring mvc_spring mvc

    6. **注解驱动开发**:Spring MVC支持使用注解来简化配置,如@RequestMapping用于映射请求,@RequestParam用于获取请求参数,@PathVariable用于处理URL路径变量。 7. ** ModelAndView**:这个类是用来存储模型数据...

    spring mvc

    在 Spring MVC 中,可以通过配置 `&lt;mvc:resources&gt;` 标签来指定静态资源的映射路径。例如: ```xml &lt;mvc:resources mapping="/static/**" location="/WEB-INF/static/" /&gt; ``` 这样设置后,客户端可以通过 `/static/...

    Spring MVC 4.2.4.RELEASE 中文文档

    **Spring MVC 4.2.4.RELEASE 中文文档** Spring MVC是Spring框架的一个核心组件,专注于构建Web应用程序。它提供了模型-视图-控制器(MVC)架构,帮助开发者组织和分离应用的业务逻辑、数据处理以及用户界面。...

    spring mvc经典入门案例

    Spring MVC 支持使用注解进行开发,例如 `@RequestMapping` 用于映射 HTTP 请求,`@GetMapping` 和 `@PostMapping` 分别用于 GET 和 POST 请求,`@PathVariable` 用于获取 URL 路径变量,`@RequestParam` 用于获取...

    基本的spring mvc + spring security实现的登录(无数据库)

    - **配置**:通常通过Java配置或XML配置来设置Spring MVC的组件,如定义映射路径、拦截器等。 - **MVC模式**:Model代表业务数据,View负责渲染视图,Controller处理用户请求并协调Model和View。 2. **Spring ...

    精通Spring MVC4

    Spring MVC支持自动的数据绑定,将请求参数自动映射到Controller方法的参数上。同时,使用JSR-303/JSR-349提供的注解可以进行数据验证,如@NotNull、@Size等。 9. **上传下载** 使用MultipartFile处理文件上传,...

    Spring MVC--2.@RequestMapping 映射请求

    `@RequestMapping`支持通配符`*`,如`/users/*`,这意味着它将匹配所有以`/users/`开头的请求路径。 ### 8. 注解属性 `@RequestMapping`还有一些其他属性,如`produces`和`consumes`,用于指定响应内容类型和接受的...

    spring mvc 整合包

    Spring MVC 是一个强大的Java Web应用程序开发框架,是Spring框架的一部分,专注于处理Web请求和返回响应。它提供了模型-视图-控制器(MVC)架构,帮助开发者构建灵活、可维护的Web应用。在这个"spring mvc 整合包...

    spring MVC的HelloWorld完整实例

    在Spring MVC中,控制器通常是一个Java类,通过`@Controller`注解标记,并使用`@RequestMapping`注解来映射URL请求。在这个实例中,`HelloWorldController`可能有一个方法,如`hello()`,用于处理请求并返回"Hello, ...

    spring mvc架包

    在 Spring MVC 中,`Controller` 负责接收HTTP请求并进行处理,通常通过注解如 `@RequestMapping` 来映射请求路径。`Model` 是业务对象或数据模型,用于封装和传递数据。`View` 则负责呈现数据,通常使用 JSP、...

Global site tag (gtag.js) - Google Analytics