Spring 拦截器与@RepositoryRestResource 不兼容

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

@Component
    public class TestInterceptor implements HandlerInterceptor {
        @Override
        public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3) throws Exception {
            System.out.println("afterCompletion");
        }
        @Override
        public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3) throws Exception {
            System.out.println("postHandle");
        }
        @Override
        public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception {
            System.out.println("preHandle");
            return true;
        }
    }

@SpringBootConfiguration
public class AnnotationSecurityConfiguration implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new TestInterceptor()).addPathPatterns("/api/**");
    }
}

最后使用@RepositoryRestController 将实体呈现为 REST,如下所示:

@RepositoryRestResource(excerptProjection = UserSummaryProjection.class)
public interface UserRepository extends JpaRepository<User, Long>, JpaSpecificationExecutor<User> {
}

然后调用

curl -X GET https://localhost:8080/api/v1/users 

但是拦截器没有被调用。

因为 REST 资源是使用 @RepositoryRestController 管理的 Spring Data Rest,所以不会调用拦截器。但是,如果我使用 @RestController 编写 REST 资源,它将起作用

如何让拦截器与 @RepositoryRestController 一起工作?

最佳答案

我使用以下 config/spring-boot 应用程序使其工作(在 / 上下文路径和一个简单的 User 类,spring-boot v2.4.2 上):

...
import org.springframework.web.servlet.handler.MappedInterceptor
...    

@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
       
    @Bean
    public org.springframework.web.servlet.handler.MappedInterceptor myInterceptor() {
        return new MappedInterceptor(
                new String[]{"/users/**"},  // null => maps to any repository/path
                new MyInterceptorImpl()
        );
    }

    private class MyInterceptorImpl implements HandlerInterceptor  {
         @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            System.out.println("preHandle");
            return true;
        }

        @Override
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
            System.out.println("postHandle");
        }

        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
           System.out.println("afterCompletion");
        }
    }
}

我使用了一个简化的:

@RepositoryRestResource
public interface UserRepository extends JpaRepository<User, Long>, JpaSpecificationExecutor<User> { }

关于Spring 拦截器与@RepositoryRestResource 不兼容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66176504/

相关文章:

java - Spring事务隔离不起作用

spring-boot_1.4.2数据源配置

java - Spring Boot "Ignored because not a concrete top-level class"

java - Spring Boot 模糊映射。无法映射方法

java - Spring MVC + Hibernate : No Hibernate Session bound to thread, 并且配置不允许在此处创建非事务性的

java - spring - 设置 hibernate 命名策略不起作用

java - 有关 Spring Framework 应用程序中 JDBC 逻辑的一些信息

spring - 每次测试后撤消@Sql

spring-boot - 如何在 Spring boot 应用程序的嵌入式 untertow 中禁用 HTTP TRACE

java - Spring MVC : Sharing context within ear