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>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM