SpringMVC-Ambiguous mapping 问题实践

思君令人老,努力加餐饭

1 前言

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

2 问题分析

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

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

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

复制代码
RequestMappingHandlerMapping.registerHandlerMethod
AbstractHandlerMethodMapping.registerHandlerMethod
AbstractHandlerMethodMapping.validateMethodMapping

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

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

3 RequestMappingHandlerMapping

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

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

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

4 总结

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

相关推荐
dunky2 小时前
Spring 的三级缓存与循环依赖
后端·spring
码云数智-园园5 天前
C++20 Modules 模块详解
java·开发语言·spring
咖啡八杯5 天前
GoF设计模式——享元模式
java·spring·设计模式·享元模式
Flittly5 天前
【AgentScope Java新手村系列】(10)实战-多Agent天气助手
java·spring boot·spring
李少兄5 天前
从原理到实战:Spring IoC/DI 核心知识体系与高频面试题全解
java·后端·spring
shushangyun_5 天前
2026年快消品B2B系统推荐:支持终端门店订货、促销政策自动化的工具?
java·运维·网络·数据库·人工智能·spring·自动化
ofoxcoding5 天前
在AI API聚合平台配置DeepSeek V3.2提示词缓存实战:快速接入与成本优化指南
人工智能·spring·缓存·ai
一杯奶茶¥5 天前
水果销售网站 CRM客户信息管理系统 超市管理系 酒店管理系统 健身房管理系统 在线音乐网站 校园招聘系统
java·vue.js·spring boot·mysql·spring·java项目
摇滚侠5 天前
SpringMVC 入门到实战 RESTFul 49-55
java·开发语言·后端·spring·intellij-idea·restful
我登哥MVP5 天前
SpringCloud Alibaba 核心组件解析:服务链路追踪
java·spring boot·后端·spring·spring cloud·java-ee·maven