【问题标题】:Spring Boot RestController inheritance and ambiguous mapping issueSpring Boot RestController 继承和不明确的映射问题
【发布时间】:2019-08-03 22:44:43
【问题描述】:

我正在尝试为我的 Spring Boot Rest 项目实现继承的控制器。正如您在示例代码 sn-ps 中看到的,我在 BaseTableController 中为所有控制器提供了标准端点,但对于一些具体的控制器,我需要覆盖方法。当我像这样实现它时,我在启动时得到Ambiguous mapping. Cannot map 'clientRfmController' method 异常。

public abstract class BaseTableController<T extends BaseTableModel> {  

@Override
    public BaseTableService<T> getService() {
        return (BaseTableService<T>) super.getService();
    }
   @GetMapping({
            PATH_GET,
            PATH_VIEW_GET}
    )
    public T getWithParam(@RequestParam UUID gid) {
        T t = null;
        if (gid != null) {
            t = getService().get(gid);
        }
        return getWithErrorCheck(t);
    }
}

-

@RestController
@RequestMapping(TBL_CLIENTRFM)
public class ClientRfmController extends BaseTableController<ClientRfmCommon> {
    @Override
    public ClientRfmService getService() {
        return (ClientRfmService) super.getService();
    }

    @GetMapping(value = {PATH_GET, PATH_VIEW_GET})
    public List<ClientRfmCommon> getByAccid(Long accid, @RequestParam(required = false) UUID gid) {
        List<ClientRfmCommon> byAccid = null;
        if (gid != null) {
            byAccid = Collections.singletonList(super.getWithParam(gid));
        } else {
            byAccid = Collections.singletonList(getService().getByAccid(accid));
        }
        return byAccid;
    }


}

我通过实现自定义 RequestMappingHandlerMapping 找到了解决方法。

  @Configuration
    public class WebMvcRegistrationsConfig implements WebMvcRegistrations {

        @Override
        public OoRequestMappingHandlerMapping getRequestMappingHandlerMapping() {
            OoRequestMappingHandlerMapping ooRequestMappingHandlerMapping = new OoRequestMappingHandlerMapping();
            ooRequestMappingHandlerMapping.setOrder(0);
            return ooRequestMappingHandlerMapping;
        }


    }

-

public class OoRequestMappingHandlerMapping extends RequestMappingHandlerMapping {

    @Override
    protected void registerHandlerMethod(Object handler, Method method, RequestMappingInfo mapping) {
        HandlerMethod existingHandlerMethod = getHandlerMethods().get(mapping);
        if (existingHandlerMethod != null) {
            HandlerMethod handlerMethod = createHandlerMethod(handler, method);
            if (handlerMethod.getMethod().getDeclaringClass().isAssignableFrom(existingHandlerMethod.getMethod().getDeclaringClass())) {
                logger.warn(handlerMethod.getBeanType().getSimpleName() + " type (" + handlerMethod.getMethod().getDeclaringClass().getSimpleName() + "->" + handlerMethod.getMethod().getName() +
                        ") registration omitted to avoid ambigious mapping (" + existingHandlerMethod.getMethod().getDeclaringClass().getSimpleName() + "->" + existingHandlerMethod.getMethod().getName() + ")");
                return;
            }
            unregisterMapping(mapping);
        }
        super.registerHandlerMethod(handler, method, mapping);
    }

}
  1. 这是正确的处理方式吗?
  2. 当我添加@EnableWebMvc 注解时,这变得没用了。有没有更通用的解决方案?

【问题讨论】:

  • 你有重复的映射,你不能将同一个 URL 映射到不同的方法,不管你是否覆盖。所以不,这不是处理它的方法。不要扩展基类,只实现这里的逻辑。
  • @M.Deinum 这是控制器的一小部分。我在基本控制器上有很多不同的方法。我只想用相同的 url 覆盖其中一个。
  • 你不能因为所有的元数据都将被处理导致相同的 URL/映射。它仅在映射不同时才有效。显然您正在添加一个不同的参数,因此将其包含在映射信息中以获得唯一映射。

标签: java spring spring-boot spring-restcontroller


【解决方案1】:
  @GetMapping({
            PATH_GET,
            PATH_VIEW_GET}
    ) 

在父类和子类中都被重复,所以你面临着不明确的映射。请换一个路径。

【讨论】:

  • 我知道他们有相同的映射。我想让RequestMappingHandlerMapping选择子控制器的方法。
猜你喜欢
  • 1970-01-01
  • 2015-05-10
  • 1970-01-01
  • 2016-01-04
  • 1970-01-01
  • 2017-07-23
  • 1970-01-01
  • 2016-06-27
  • 2016-02-17
相关资源
最近更新 更多