用于获取spring所有支持的请求url,也就是{@link RequestMapping}的url

来源:互联网 发布:java 公章识别 编辑:程序博客网 时间:2024/05/19 17:10

反正从网上没搜索出来,只好自己来。

用于获取spring所有支持的请求,也就是{@link RequestMapping}的url

想测试一下服务器是否所有接口均正确无误,需要对所有的接口都请求一次,但是无奈接口太多,一个个写是不可能的。文档虽然都有,但是也很分散。

寻找过程:
1. 启动服务器,观察日志,日志开启debug模式,可以看到。

[03-17 16:02:05,959] DEBUG [tartStop-1][] o.s.w.s.m.m.a.RequestMappingHandlerMapping[100] - Looking for request mappings in application context: Root WebApplicationContext: startup date [Thu Mar 17 16:02:03 CST 2016]; root of context hierarchy[03-17 16:02:05,975] INFO  [tartStop-1][] o.s.w.s.m.m.a.RequestMappingHandlerMapping[181] - Mapped 这里是接口信息。必需隐去[03-17 16:02:05,976] INFO  [tartStop-1][] o.s.w.s.m.m.a.RequestMappingHandlerMapping[181] - Mapped 这里是接口信息。必需隐去[03-17 16:02:05,976] INFO  [tartStop-1][] o.s.w.s.m.m.a.RequestMappingHandlerMapping[181] - Mapped 这里是接口信息。必需隐去[
  1. 那么在此类RequestMappingHandlerMapping中寻找该日志输出,包括寻找其父类。即可在类AbstractHandlerMethodMapping看到源码。
    protected void initHandlerMethods() {        if (logger.isDebugEnabled()) {            logger.debug("Looking for request mappings in application context: " + getApplicationContext());        }        String[] beanNames = (this.detectHandlerMethodsInAncestorContexts ?                BeanFactoryUtils.beanNamesForTypeIncludingAncestors(getApplicationContext(), Object.class) :                getApplicationContext().getBeanNamesForType(Object.class));        for (String beanName : beanNames) {            if (isHandler(getApplicationContext().getType(beanName))){                detectHandlerMethods(beanName);//在这里            }        }        handlerMethodsInitialized(getHandlerMethods());    }

其中detectHandlerMethods(beanName);会调用registerHandlerMethod(handler, method, mapping);,registerHandlerMethod 函数是关键。

    protected void registerHandlerMethod(Object handler, Method method, T mapping) {        HandlerMethod newHandlerMethod = createHandlerMethod(handler, method);        HandlerMethod oldHandlerMethod = handlerMethods.get(mapping);        if (oldHandlerMethod != null && !oldHandlerMethod.equals(newHandlerMethod)) {            throw new IllegalStateException("Ambiguous mapping found. Cannot map '" + newHandlerMethod.getBean()                    + "' bean method \n" + newHandlerMethod + "\nto " + mapping + ": There is already '"                    + oldHandlerMethod.getBean() + "' bean method\n" + oldHandlerMethod + " mapped.");        }        this.handlerMethods.put(mapping, newHandlerMethod);//这就是存储的变量,url映射到处理函数        if (logger.isInfoEnabled()) {            logger.info("Mapped \"" + mapping + "\" onto " + newHandlerMethod);        }        Set<String> patterns = getMappingPathPatterns(mapping);        for (String pattern : patterns) {            if (!getPathMatcher().isPattern(pattern)) {                this.urlMap.add(pattern, mapping);//这就是存储的变量,url字符串到urlMapping对象的            }        }    }

可以看到,它就存储在handlerMethods变量中,而且这个变量提供了get方法,所以,spring是提供了获取所有url的接口的。但是urlMap对象没有get函数,需要通过反射去获取。
3. 那么直接获取就可以了。
我们创建一个接口用于返回所有的接口信息。记得加上过滤器进行验证权限,或者只能在本机使用,避免被其他人获取到。

    /**     * 用于获取spring所有支持的请求,也就是{@link RequestMapping}的url     *     * @return     */    @RequestMapping("getAllService")    public Result getAllService() {        RequestMappingHandlerMapping requestMappingHandlerMapping = SpringIocUtil.getBean(RequestMappingHandlerMapping.class);//        Map<RequestMappingInfo, HandlerMethod> handlerMethodMap = requestMappingHandlerMapping.getHandlerMethods();        try {            Field field = AbstractHandlerMethodMapping.class.getDeclaredField("urlMap");            MultiValueMap<String, RequestMappingInfo> urlMap = (MultiValueMap<String, RequestMappingInfo>) field.get(requestMappingHandlerMapping);            return ResultUtils.result(urlMap);        } catch (Exception e) {            e.printStackTrace();        }        return ResultUtils.result(null);    }
0 0
原创粉丝点击