有时需要获取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 的 Web 应用程序接收到 http://localhost:8080/hello.do(事实上请求路径是 /hello.do) 的请求后, Spring 将这个请求交给一个名为 helloController 的程序进行处理, helloController 再调用 一个名为 ...
Spring MVC进行映射的依据 通过URL限定:URL表达式 通过URL限定:绑定{xxx}中的值 通过请求方法限定:请求方法 通过请求方法限定:代码示例 通过请求方法限定:模拟请求方法 通过请求/请求头参数限定:示例 通过请求/请求...
Spring MVC进行映射的依据 通过URL限定:URL表达式 通过URL限定:绑定{xxx}中的值 通过请求方法限定:请求方法 通过请求方法限定:代码示例 通过请求方法限定:模拟请求方法 通过请求/请求头参数限定:示例 通过...
任何一个WEB都需要解决URL与请求处理器之间的映射,spring MVC也是一样,但Spring MVC就像Spring所作的一切一样(灵活,可以配置各种东西,但是也造成了很多复杂性),肯定不会只有一种方法来映射URL和 Controller之间...
-- 启动Spring MVC的注解功能,完成请求和注解POJO的映射 --> 14. <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" /> 15. 16. <!-- 对模型视图名称的解析...
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...
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在...
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在...
使用@RequestMapping映射请求 13.12.4. 使用@RequestParam绑定请求参数到方法参数 13.12.5. 使用@ModelAttribute提供一个从模型到数据的链接 13.12.6. 使用@SessionAttributes指定存储在会话中的属性 13.12.7. ...
使用@RequestMapping映射请求 13.12.4. 使用@RequestParam绑定请求参数到方法参数 13.12.5. 使用@ModelAttribute提供一个从模型到数据的链接 13.12.6. 使用@SessionAttributes指定存储在会话中的属性 13.12.7. ...
下所有映射路径绑定处理方法上,假如在扫描包中定义下列类: import javax.imageio.ImageIO; import javax.servlet.ServletOutputStream; import javax.servlet.http.Cookie; import javax.servlet....
Servlet 自定义的 `Servlet` 继承 `HttpServlet` (Java 服务端组件,接收 HTTP 请求,调用业务逻辑,完成 HTTP 响应) Servlet 生命周期(容器...默认一个 Servlet 映射一个 URL 路径 /user–> UserSe
将错误页面映射到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,你可以定义处理器方法(Controller),并使用注解将这些方法映射到特定的URL路径。此外,SpringMVC还提供了与视图解析器一起使用的功能,用于将模型数据渲染为最终的响应。 Spring框架是一个全功能...
-(1)检索和用户请求匹配的ActionMapping实例,如果不存在,就返回请求路径无效信息; -(2)如果ActionForm实例不存在,就创建一个ActionForm对象,把客户提交的表单数据保存到ActionForm对象中; -(3)根据配置信息决定...
Charon Spring启动启动器 Charon是反向代理实现。...产品特点高度可配置和可扩展Spring 和支持多请求转发映射负载均衡灵活的路径重写支持基于指标异步请求转发认证方式Cookies改写“ X转发” HTTP标头支持转发过
Spring MVC 通过 @RequestMapping 注解将 URL 请求与业务方法进行进行映射。 在控制器的类定义处以及方法定义处都可添加 @RequestMapping,在类定义处添加 @RequestMapping 注解,相当于多了一层访问路径。
JSP+Servlet+Struts+Hibernate+Spring+Ajax》重点讲解了Struts 2、Speing和HIbernate框架的基础知识和高级技术,如Sruts 2中的*、类型转换、国际化和标签等,HIbe rna{e的会话、0/R映射和事务管理等,Spring中的...
JSP+Servlet+Struts+Hibernate+Spring+Ajax》重点讲解了Struts 2、Speing和HIbernate框架的基础知识和高级技术,如Sruts 2中的*、类型转换、国际化和标签等,HIbe rna{e的会话、0/R映射和事务管理等,Spring中的...
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 ...