zoukankan      html  css  js  c++  java
  • SpringMVC项目中获取所有URL到Controller Method的映射

    Spring是一个很好很强大的开源框架,它就像是一个容器,为我们提供了各种Bean组件和服务。对于MVC这部分而言,它里面实现了从Url请求映射控制器方法的逻辑处理,在我们平时的开发工作中并不需要太多的理会这个Url是怎么和控制器中的方法建立映射的,一切都由Spring MVC帮我们搞定了。

    但是我今天在做SDK工程的时候,突然产生一个想法:能否把我项目中的所有Url和Method的映射信息打印出来?以便我一眼就看出我已经完成了那些API接口开发,这些方法需要什么参数。就像下图所示:

    image_thumb5

    有了想法就要用行动,第一步肯定是要去看看别人是否已经解决了这个问题啦。查了半天的资料,倒是发现有几个相似的问题,但都没有满意的答案,只好自己调试Spring,跟踪它的处理步骤,终于让我发现了一个可行的办法,不多说,直接贴代码:

    1、首先建立一个类来保存我想要的东东

    private class RequestToMethodItem
        {
            public String controllerName;
            public String methodName;
            public String requestType;
            public String requestUrl;
            public Class<?>[] methodParmaTypes;
    
            public RequestToMethodItem(String requestUrl, String requestType, String controllerName, String requestMethodName, 
    Class<?>[] methodParmaTypes)
            {
                this.requestUrl = requestUrl;
                this.requestType = requestType;
                this.controllerName = controllerName;
                this.methodName = requestMethodName;
                this.methodParmaTypes = methodParmaTypes;
    
            }
        }

    2、然后就是收集信息创建对象啦

    @RequestMapping(value = "/index", method = RequestMethod.GET)
        public ModelAndView index(HttpServletRequest request)
        {
            ServletContext servletContext = request.getSession().getServletContext();
            if (servletContext == null)
            {
                return null;
            }
            WebApplicationContext appContext = WebApplicationContextUtils.getWebApplicationContext(servletContext);
    
            //请求url和处理方法的映射
            List<RequestToMethodItem> requestToMethodItemList = new ArrayList<RequestToMethodItem>();
            //获取所有的RequestMapping
            Map<String, HandlerMapping> allRequestMappings = BeanFactoryUtils.beansOfTypeIncludingAncestors(appContext, 
    HandlerMapping.class, true, false);
    
            for (HandlerMapping handlerMapping : allRequestMappings.values())
            {
                //本项目只需要RequestMappingHandlerMapping中的URL映射
                if (handlerMapping instanceof RequestMappingHandlerMapping)
                {
                    RequestMappingHandlerMapping requestMappingHandlerMapping = (RequestMappingHandlerMapping) handlerMapping;
                    Map<RequestMappingInfo, HandlerMethod> handlerMethods = requestMappingHandlerMapping.getHandlerMethods();
                    for (Map.Entry<RequestMappingInfo, HandlerMethod> requestMappingInfoHandlerMethodEntry : handlerMethods.entrySet())
                    {
                        RequestMappingInfo requestMappingInfo = requestMappingInfoHandlerMethodEntry.getKey();
                        HandlerMethod mappingInfoValue = requestMappingInfoHandlerMethodEntry.getValue();
    
                        RequestMethodsRequestCondition methodCondition = requestMappingInfo.getMethodsCondition();
                        String requestType = SetUtils.first(methodCondition.getMethods()).name();
    
                        PatternsRequestCondition patternsCondition = requestMappingInfo.getPatternsCondition();
                        String requestUrl = SetUtils.first(patternsCondition.getPatterns());
    
                        String controllerName = mappingInfoValue.getBeanType().toString();
                        String requestMethodName = mappingInfoValue.getMethod().getName();
                        Class<?>[] methodParamTypes = mappingInfoValue.getMethod().getParameterTypes();
                        RequestToMethodItem item = new RequestToMethodItem(requestUrl, requestType, controllerName, requestMethodName, 
    methodParamTypes);
    
                        requestToMethodItemList.add(item);
                    }
                    break;
                }
            }
            return new ModelAndView("index").addObject("MethodList", requestToMethodItemList);
        }

    这一步我需要说明一下,我这里只用了“RequestMappingHandlerMapping”中的映射信息,其实还有另外三个HandlerMapping,如果想要获取项目中所有的映射信息,肯定是一个都不能放过了。调试的 信息如下:

    image_thumb7

    3、取到数据后就展示呗,借助Thymeleaf,很容易就实现了展示,效果就是第一张图。

    <!DOCTYPE html>
    
    <html xmlns:th="http://www.thymeleaf.org">
    
    <head>
        <title>Spring Thyme Seed Starter Manager</title>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
        <link rel="stylesheet" type="text/css" media="all" href="../../css/stsm.css" th:href="@{/css/stsm.css}"/>
        <title>请求方法列表</title>
    </head>
    
    <body>
    <div style="margin: 0;padding: 0;text-align: center"><h1>请求方法列表</h1></div>
    <div>
        <ul>
            <li th:each="method:${MethodList}">
                <h3 th:text="${method.methodName}"></h3>
    
                <p th:text="'所属控制器:'+${method.controllerName}"></p>
    
                <p th:text="'请求URL:'+${method.requestUrl}"></p>
    
                <p th:text="'请求方式:'+${method.requestType}"></p>
    
                <div>
                    <p>方法参数列表:</p>
                    <ul>
                        <li th:each="param:${method.methodParmaTypes}">
                            <p th:text="${param}"></p>
                        </li>
                    </ul>
                </div>
    
            </li>
        </ul>
    </div>
    
    
    </body>
    </html>
  • 相关阅读:
    JS中的事件&对象
    WSL使用小结:从ArchLinux到Manjaro
    WSL学习:安装ArchLinux和Root/Cling以及注意事项
    Qt5网络请求使用及WebRequest函数
    有道词典中的OCR功能:第三方库的变化
    C++学习(二):学会使用stringstream
    C语言集锦(三)Direct3D和GDI+的例子
    网络那些事:浏览器、网络协议以及常见软件
    C++学习(一):现代C++尝试
    PostScript学习:另一种缩写为PS的技术
  • 原文地址:https://www.cnblogs.com/yuananyun/p/3934371.html
Copyright © 2011-2022 走看看