likes
comments
collection
share

SpringMVC-Ambiguous mapping 问题实践

作者站长头像
站长
· 阅读数 39

思君令人老,努力加餐饭

1 前言

今天在项目开发中遇到了一个 Ambiguous mapping 问题,错误信息展示为 Ambiguous mapping. Cannot map 'xxxController' method 。起因是项目(项目是微服务架构,需要引入其他项目的 api)开发中使用了其它项目的 api jar 包,在控制器层声明的 RequestMapping 和 jar 包中的 RequestMapping 一致造成的,项目启动时,会扫描所有的包并创建 RequestMappingHandler ,在 doCreateBeaninitializeBean 阶段发生异常。

2 问题分析

遇到的报错信息如下图所示,当看到这样的信息时,真是一头雾水。原因就是在 MemberOrderController 中的方法和引入 jar 包中的 MemberOrderApi 中的方法使用的路径是一样的。那么在两者路径都不变动的情况下,怎么去修改这个问题呢? SpringMVC-Ambiguous mapping 问题实践

这里需要介绍一下 RequestMappingInfo, 可以从下图看到在控制器层写的每一个 Mapping 都可以在 RequestMappingInfo 中找到对应的属性,其包含了所有的映射信息。

SpringMVC-Ambiguous mapping 问题实践

异常出现在 Spring 的 refresh 阶段,RequestMappingHandlerMapping 实现了 Bean 初始化的接口 InitializingBean,在 bean 加载完成后会自动调用 afterPropertiesSet 方法进行后置处理,在此方法中调用了 initHandlerMethods,异常的触发是在以下链路中。

RequestMappingHandlerMapping.registerHandlerMethod
AbstractHandlerMethodMapping.registerHandlerMethod
AbstractHandlerMethodMapping.validateMethodMapping

在调用 validateMethodMapping是传进来的 mapping 的类型即 RequestMappingInfo, 会从 mappingLookup 中查找对应的 HandlerMethod 来判断是否存在。 SpringMVC-Ambiguous mapping 问题实践

通过上面的分析,我们知道要想解决这样的报错,在请求路径不变的情况下,能修改的只有 RequestMappingInfo 中的属性,包括请求头,参数,名称、consumesproduces 等。任意修改一项即可实现项目中存在同样的请求路径,不过在客户端发起请求时,需要严格按照 mapping 的参数要求来请求,才能执行对应的方法。这里最常用的就是同一个请求路径,采用不同的方法(postget )也可以实现。

3 RequestMappingHandlerMapping

在上述问题分析中,我们知道了 RequestMappingHandlerMapping 在处理 Controller 中的重要性,在本节中将分享如何利用其在项目启动时打印应用的所有接口。在项目中创建配置文件 AppHandlerMapping 实现集成,重写 registerHandlerMethod 方法即可获取到对应的 requestmapping 信息。通过以上的操作,既可以打印项目中所有的接口信息。

SpringMVC-Ambiguous mapping 问题实践

除了打印项目接口列表外,还可以通过自定义 RestMapping 来处理请求,主要是为了了解 RequestMappingHandlerMapping 的作用,方便深入理解其原理和逻辑思想,可以更好的解决实际开发过程中遇到的问题,在遇到棘手的问题时,可以利用其特点找到巧妙的解决方案。

如下图所示,通过重写 getMappingForMethod 方法,可以实现自定义注解的解析,通过获取其特定的属性,重新构建 RequestMappingInfo 对象,即可实现特定接口的注册和功能实现。这在实际的开发中使用比较少,但是可以作为一项技术储备来学习。在实际开发过程中,可以根据需要对 SpringMvc 的功能点进行拓展,实现特定的业务需求。这里需要注意的是 AnnotatedElementUtils.findMergedAnnotation,这是一个很好用的工具类,可以通过它找到方法上的注解。

SpringMVC-Ambiguous mapping 问题实践

4 总结

在本文主要分享了 SpringMVC-Ambiguous mapping 的问题解决方法,以及出现该问题的原因。由此引出了 RequestMappingHandlerMapping,通过其简单实现了项目接口的打印和自定义注解解析。本文中所涉及的代码已经上传至 github, 欢迎交流学习。项目地址 springboot-auth

转载自:https://juejin.cn/post/7330426020997529640
评论
请登录