java - Spring Data REST Controller 不得在类级别使用@RequestMapping,因为这会导致向 Spring MVC 进行双重注册

标签 java spring-boot spring-mvc spring-data-rest

从 Spring Boot 2.5.5 升级到 2.5.6 在我的 Controller 测试中触发了这种类型的错误:

Spring Data REST controller WidgetController$$EnhancerBySpringCGLIB$$9dfdd90c_3 must not use @RequestMapping on class level as this would cause double registration with Spring MVC!

Caused by: java.lang.IllegalStateException: Spring Data REST controller WidgetController$$EnhancerBySpringCGLIB$$9dfdd90c_3 must not use @RequestMapping on class level as this would cause double registration with Spring MVC!
    at org.springframework.data.rest.webmvc.BasePathAwareHandlerMapping.isHandler(BasePathAwareHandlerMapping.java:165) ~[spring-data-rest-webmvc-3.5.6.jar:3.5.6]
    at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.processCandidateBean(AbstractHandlerMethodMapping.java:265) ~[spring-webmvc-5.3.12.jar:5.3.12]
    at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.initHandlerMethods(AbstractHandlerMethodMapping.java:225) ~[spring-webmvc-5.3.12.jar:5.3.12]
    at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.afterPropertiesSet(AbstractHandlerMethodMapping.java:213) ~[spring-webmvc-5.3.12.jar:5.3.12]
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping.afterPropertiesSet(RequestMappingHandlerMapping.java:206) ~[spring-webmvc-5.3.12.jar:5.3.12]
    at org.springframework.data.rest.webmvc.config.RepositoryRestMvcConfiguration.restHandlerMapping(RepositoryRestMvcConfiguration.java:690) ~[spring-data-rest-webmvc-3.5.6.jar:3.5.6]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64) ~[na:na]
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
    at java.base/java.lang.reflect.Method.invoke(Method.java:564) ~[na:na]
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154) ~[spring-beans-5.3.12.jar:5.3.12]
    ... 88 common frames omitted

Controller 遵循这种模式:

@RepositoryRestController
@RequestMapping("/api/widgets")
@RequiredArgsConstructor
public class WidgetController {
    private final @NotNull WidgetHandler widgetHandler;

    @GetMapping
    public ResponseEntity<List<Widget>> widgets() {
        return ResponseEntity.ok().body(widgetHandler./*...*/);
    }

    // ...
}

最佳答案

从堆栈跟踪来看,异常是由 BasePathAwareHandlerMapping 类的 isHandler 方法抛出的。

2.5.5

    protected boolean isHandler(Class<?> beanType) {
        Class<?> type = ProxyUtils.getUserClass(beanType);
        return type.isAnnotationPresent(BasePathAwareController.class);
    }

2.5.6

    protected boolean isHandler(Class<?> beanType) {
    ...
    if (AnnotatedElementUtils.hasAnnotation(type, RequestMapping.class)) {
        throw new IllegalStateException(String.format(AT_REQUEST_MAPPING_ON_TYPE, beanType.getName()));
    }
    ...
}

如果您需要 spring data rest 的功能并且想使用@RepositoryRestController,您可以在方法级别使用带有完整路径的@RequestMapping(或相关的@GetMapping、@PostMapping 等)。

@RepositoryRestController
@RequiredArgsConstructor
public class WidgetController {
    private final @NotNull WidgetHandler widgetHandler;

    @GetMapping("/api/widgets")
    public ResponseEntity<List<Widget>> widgets() {
        return ResponseEntity.ok().body(widgetHandler./*...*/);
    }

// ...

关于java - Spring Data REST Controller 不得在类级别使用@RequestMapping,因为这会导致向 Spring MVC 进行双重注册,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69825704/

相关文章:

linux和windows之间的java剪贴板

java - ClassNotFoundException : org. springframework.web.context.ContextLoaderListener 问题

java - Spring MVC 和 Spring Data Repository 不起作用

java - doOnError 没有捕获异常

java - 来自 HttpServletResponse 的 Spring MVC 相对重定向

java - 读取非常大的图像时 ImageIO.read(FileInputStream) 返回 null

rest - 自定义 ObjectMapper 不适用于 spring boot hateoas

spring-boot - Spring boot + keycloak 应用程序在部署到 tomcat 时不起作用

spring-boot - 如何在 Spring Boot 中关闭 liquibase 横幅?

jquery - 向 spring mvc3 Controller 提交 Handsontable - 不支持内容类型 'application/x-www-form-urlencoded'