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

Los*_*ind 6 java spring annotations spring-mvc documentation-generation

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

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

Sea*_*oyd 4

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

使用构建工具

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

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

使用注释处理

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

这是一个基本的实现:

public class RequestMappingProcessor extends AbstractProcessor{

    private final Map<String, String> map =
        new TreeMap<String, String>();

    private Filer filer;

    @Override
    public Set<String> 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<? extends TypeElement> 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("<body>\n");
            for(final Entry<String, String> entry : map.entrySet()){
                writer
                    .append("<a href=\"")
                    .append(entry.getKey())
                    .append("\">")
                    .append("Path: ")
                    .append(entry.getKey())
                    .append(", method: ")
                    .append(entry.getValue())
                    .append("</a>\n");
            }
            writer.append("</body>\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()
            );
        }
    }

}
Run Code Online (Sandbox Code Playgroud)