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。

推薦閱讀: