将Spring @RequestMapping注释自动记录到一个位置?

Javadoc非常适合扫描所有源文件并创建HTML页面来查看它。 我想知道是否有一个类似的工具可以通过所有的Spring控制器并收集所有已经使用@RequestMapping注释的方法,并生成一个列出它们的HTML页面。 类似于伪站点地图,供开发人员确保控制器的唯一性和标准化。

如果已经在别处问过这个问题,我道歉。 我无法想出一套适当的搜索条件来提供有用的结果。

这是一个非常好的问题,我经常会错过(并实现)这样的function。

使用构建工具

我要做的是运行Maven(或ant)并在编译后执行任务

  • 读取所有类(可能具有可配置的包列表)
  • 迭代这些类的所有方法
  • 读取注释
  • 并将输出写入HTML

使用注释处理

但我想这是一个场景, 注释处理也可能是一种方法。 通常,您必须使用一些内部API来完成API中的操作,但是使用Filer.createResource(...)它实际上应该可以开箱即用。

这是一个基本的实现:

 public class RequestMappingProcessor extends AbstractProcessor{ private final Map map = new TreeMap(); private Filer filer; @Override public Set getSupportedAnnotationTypes(){ return Collections.singleton(RequestMapping.class.getName()); } @Override public synchronized void init( final ProcessingEnvironment processingEnv){ super.init(processingEnv); filer = processingEnv.getFiler(); } @Override public boolean process( final Set annotations, final RoundEnvironment roundEnv){ for(final TypeElement annotatedElement : annotations){ final RequestMapping mapping = annotatedElement.getAnnotation( RequestMapping.class ); if(mapping != null){ addMapping(mapping, annotatedElement, roundEnv); } } assembleSiteMap(); return false; } private void assembleSiteMap(){ Writer writer = null; boolean threw = false; try{ final FileObject fileObject = filer.createResource( StandardLocation.CLASS_OUTPUT, "html", "siteMap.html" ); writer = fileObject.openWriter(); writer.append("\n"); for(final Entry entry : map.entrySet()){ writer .append("") .append("Path: ") .append(entry.getKey()) .append(", method: ") .append(entry.getValue()) .append("\n"); } writer.append("\n"); } catch(final IOException e){ threw = true; throw new IllegalStateException(e); } finally{ // with commons/io: IOUtils.closeQuietly(writer) // with Guava: Closeables.close(writer, rethrow) // with plain Java this monstrosity: try{ if(writer != null){ writer.close(); } } catch(final IOException e){ if(!threw){ throw new IllegalStateException(e); } } finally{ } } } private void addMapping(final RequestMapping mapping, final TypeElement annotatedElement, final RoundEnvironment roundEnv){ final String[] values = mapping.value(); for(final String value : values){ map.put( value, annotatedElement.getQualifiedName().toString() ); } } } 

我所知道的没有什么可以做到的。 在创建导航之前,我已经通过应用程序上下文检索了控制器和映射,但是为了获得微小的收益,我做了很多工作:

 @Component public class SiteMap implements ApplicationContextAware, InitializingBean { private ApplicationContext context; private List pages = new ArrayList(); public List getPages() { return pages; } public void setApplicationContext(ApplicationContext applicationContext) { this.context = applicationContext; } public void afterPropertiesSet() throws Exception { Assert.notNull(context, "applicationContext not set"); Map controllers = ctx.getBeansWithAnnotation(Controller.class); for(Map.Entry entry : controllers.entrySet()) { Page page = new Page(); Class controllerClass = entry.getValue(); String controllerRoot = null; RequestMapping classMapping = controllerClass.getAnnotation(RequestMapping.class); if(classMapping != null) controllerRoot = classMapping.value(); if(controllerRoot = null) controllerRoot = // get and parse controller name page.setPath(controllerRoot); for(Method m : controllerClass.getDeclaredMethods()) { RequestMapping rm = m.getAnnotation(RequestMapping.class); if(rm == null) continue; Page child = new Page(); child.setPath(rm.value()); page.getChildren().add(child); } pages.add(page); } } public static class Page { private String path; private List children = new ArrayList(); // other junk } } 

然后访问站点地图页面JSP中的${pages} 。 如果你做类似的事情,我可能需要使用那些代码,我在这个编辑器中对它进行了解决。