Java中Controller引起的Ambiguous mapping問題及解決
Controller引起的Ambiguous mapping問題
問題描述
出現java.lang.IllegalStateException: Ambiguous mapping. Cannot map 'xxx' method異常。
通過上面代碼我們可以看出來當spring添加Controller的接口Mapping的時候會先進行效驗,如果以存在相同的Mapping瞭,並且方法來源不是同一個類,那麼就會報錯
比如:
- 子類繼承父類的Controller的方法,url都一樣
- 兩個不同類的Controller內的方法url地址都一樣,但是方法行為都不同(名稱.參數,返回值…)
- 總結:隻要出現相同的url接口就會報錯
解決辦法
- 重寫RequestMappingHandlerMapping的getMappingForMethod方法。
- 判斷是準備註冊的Mapping是否以存在
- 如果存在那麼就將原來的Mapping刪除使用現在的Mapping
代碼
//解決重寫Controller, 方法參數返回值不一致的問題, //解決辦法就是如果子類中有相同路徑的url接口那麼就不映射父類的url接口瞭 public class PathTweakingRequestMappingHandlerMapping extends RequestMappingHandlerMapping { //handlerType.equals(ParentclassController.class) || handlerType.equals(SubclassController.class) @Override protected RequestMappingInfo getMappingForMethod(Method method, Class<?> handlerType) { RequestMappingInfo methodMapping = super.getMappingForMethod(method, handlerType); if (methodMapping==null) { return methodMapping; } Map<RequestMappingInfo, HandlerMethod> handlerMethods = super.getHandlerMethods(); for (Map.Entry<RequestMappingInfo, HandlerMethod> requestMappingInfoHandlerMethodEntry : handlerMethods.entrySet()) { for (String pattern : requestMappingInfoHandlerMethodEntry.getKey().getPatternsCondition().getPatterns()) { for (String s : methodMapping.getPatternsCondition().getPatterns()) { if (pattern.equals(s)) { //發現有重復的 //刪除原來的 super.unregisterMapping(requestMappingInfoHandlerMethodEntry.getKey()); return null; } } } } return methodMapping; } }
package com.schemautils.config; import com.schemautils.PathTweakingRequestMappingHandlerMapping; import org.springframework.boot.autoconfigure.web.servlet.WebMvcRegistrations; import org.springframework.context.annotation.Configuration; @Configuration public class WebMvcRegistrationsConfig implements WebMvcRegistrations { @Override public PathTweakingRequestMappingHandlerMapping getRequestMappingHandlerMapping() { return new PathTweakingRequestMappingHandlerMapping(); } }
Ambiguous mapping(模糊映射)
小白的報錯日常
Ambiguous mapping
Ambiguous mapping. Cannot map 'customerController' method
public com.cdmtc.model.CommonResult com.cdmtc.controller.CustomerController.insert(com.cdmtc.model.Customer)
to {[/insert],methods=[POST]}: There is already 'baseInfoController' bean method
public org.springframework.http.ResponseEntity<com.cdmtc.model.modelui.ResponseResult> com.cdmtc.controller.BaseInfoController.insert(com.cdmtc.model.BaseInfo) mapped.
有道翻譯如下:
模糊映射。無法映射“customerController”方法
公共com.cdmtc.model.CommonResult com.cdmtc.controller.CustomerController.insert (com.cdmtc.model.Customer)
對於{[/insert],methods=[POST]}:已經有瞭’baseInfoController’ bean方法
公共org.springframework.http.ResponseEntity < com.cdmtc.model.modelui。ResponseResult > com.cdmtc.controller.BaseInfoController.insert (com.cdmtc.model.BaseInfo)映射。
原因:
有value值重復的PostMapping
在controller 找的結果如下
@PostMapping(value = "/insert") public ResponseEntity<ResponseResult> insert(@RequestBody @ApiParam(name="基礎數據對象", type="BaseInfo", value="傳入json格式", required=true) BaseInfo baseInfo) @PostMapping(value = "/insert") @ApiOperation(value = "插入數據") public CommonResult insert(@RequestBody Customer customer)
解決辦法
修改contoller 下 value 的值 ,讓他們不一樣就可以解決啦
以上為個人經驗,希望能給大傢一個參考,也希望大傢多多支持WalkonNet。
推薦閱讀:
- SpringBoot如何根據目錄路徑生成接口的url路徑
- SpringBoot根據目錄結構自動配置Url前綴方式
- springboot @Controller和@RestController的區別及應用詳解
- SpringBoot根據目錄結構自動生成路由前綴的實現代碼
- Java工具類之@RequestMapping註解