有时需要获取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("/","")); } } } } }
如果您觉得我的文章给了您帮助,请为我买一杯饮料吧!我将非常感激并坚持为大家提供更多帮助!
相关推荐
**注解驱动的映射**是Spring MVC最常用的方式,它通过在控制器类的方法上使用`@RequestMapping`注解来定义请求路径。例如: ```java @Controller public class MyController { @RequestMapping("/hello") public...
7. **参数绑定**: Spring MVC可以自动将请求参数绑定到Controller方法的参数上,无需手动获取。支持的参数类型包括基本类型、复杂对象、数组和集合。 8. **数据验证**: 通过集成JSR-303/JSR-349(Bean Validation)...
SPRING MVC 请求参数获取的几种方法 SPRING MVC 框架中,获取请求参数是非常重要的一步,下面将介绍 SPRING MVC 中获取请求参数的几种方法。 1. 使用 @PathVariable 注解获取路径中传递参数 在 SPRING MVC 中,...
总的来说,这个压缩包提供了学习和实践Spring MVC注解的全面示例,涵盖了核心的控制器定义、请求映射、数据绑定,以及异步处理和错误处理机制。通过这个例子,开发者能够更好地理解和掌握Spring MVC的使用,提升其在...
Spring MVC通过DispatcherServlet作为入口点,接收HTTP请求,然后根据请求映射信息分发到相应的处理器。 在Spring MVC 4.2.3中,主要包含了以下关键特性: 1. **类型安全的路径变量**:这个版本引入了类型安全的...
`@RequestParam`用于从请求参数中获取值,`@PathVariable`用于处理URL路径变量,`@ModelAttribute`则常用于绑定表单数据到模型对象。 此外,Spring MVC提供了ModelAndView类,它可以将处理结果(模型数据)和视图名...
4. **路径变量**:在@RequestMapping注解中,可以使用路径变量(path variables)来获取URL中的动态部分,增强了路由的灵活性。 5. **RESTful支持**:4.0版本增强了对RESTful Web服务的支持,通过@RequestMapping和...
- **使用@RequestMapping 注解映射请求路径**:此注解用于指定控制器处理的具体 URL 路径。 - **定义@RequestMapping 注解的处理方法**:控制器类中的方法可以使用 @RequestMapping 来映射特定的 HTTP 请求。 - *...
视图解析器是Spring MVC中用于确定视图名对应的实际资源路径的组件。例如,InternalResourceViewResolver可以将视图名转换为JSP页面的URL。 依赖注入(Dependency Injection, DI)是Spring框架的核心特性之一。在...
6. **注解驱动开发**:Spring MVC支持使用注解来简化配置,如@RequestMapping用于映射请求,@RequestParam用于获取请求参数,@PathVariable用于处理URL路径变量。 7. ** ModelAndView**:这个类是用来存储模型数据...
在 Spring MVC 中,可以通过配置 `<mvc:resources>` 标签来指定静态资源的映射路径。例如: ```xml <mvc:resources mapping="/static/**" location="/WEB-INF/static/" /> ``` 这样设置后,客户端可以通过 `/static/...
**Spring MVC 4.2.4.RELEASE 中文文档** Spring MVC是Spring框架的一个核心组件,专注于构建Web应用程序。它提供了模型-视图-控制器(MVC)架构,帮助开发者组织和分离应用的业务逻辑、数据处理以及用户界面。...
Spring MVC 支持使用注解进行开发,例如 `@RequestMapping` 用于映射 HTTP 请求,`@GetMapping` 和 `@PostMapping` 分别用于 GET 和 POST 请求,`@PathVariable` 用于获取 URL 路径变量,`@RequestParam` 用于获取...
- **配置**:通常通过Java配置或XML配置来设置Spring MVC的组件,如定义映射路径、拦截器等。 - **MVC模式**:Model代表业务数据,View负责渲染视图,Controller处理用户请求并协调Model和View。 2. **Spring ...
Spring MVC支持自动的数据绑定,将请求参数自动映射到Controller方法的参数上。同时,使用JSR-303/JSR-349提供的注解可以进行数据验证,如@NotNull、@Size等。 9. **上传下载** 使用MultipartFile处理文件上传,...
`@RequestMapping`支持通配符`*`,如`/users/*`,这意味着它将匹配所有以`/users/`开头的请求路径。 ### 8. 注解属性 `@RequestMapping`还有一些其他属性,如`produces`和`consumes`,用于指定响应内容类型和接受的...
Spring MVC 是一个强大的Java Web应用程序开发框架,是Spring框架的一部分,专注于处理Web请求和返回响应。它提供了模型-视图-控制器(MVC)架构,帮助开发者构建灵活、可维护的Web应用。在这个"spring mvc 整合包...
在Spring MVC中,控制器通常是一个Java类,通过`@Controller`注解标记,并使用`@RequestMapping`注解来映射URL请求。在这个实例中,`HelloWorldController`可能有一个方法,如`hello()`,用于处理请求并返回"Hello, ...
在 Spring MVC 中,`Controller` 负责接收HTTP请求并进行处理,通常通过注解如 `@RequestMapping` 来映射请求路径。`Model` 是业务对象或数据模型,用于封装和传递数据。`View` 则负责呈现数据,通常使用 JSP、...