Spring拦截器与@RepositoryRestResource不兼容
及 最后,使用@RepositoryRestController将实体显示为REST,如下所示:Spring拦截器与@RepositoryRestResource不兼容,spring,spring-boot,spring-mvc,spring-security,spring-data-rest,Spring,Spring Boot,Spring Mvc,Spring Security,Spring Data Rest,及 最后,使用@RepositoryRestController将实体显示为REST,如下所示: @SpringBootConfiguration public class AnnotationSecurityConfiguration implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInt
@SpringBootConfiguration
public class AnnotationSecurityConfiguration implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new TestInterceptor()).addPathPatterns("/api/**");
}
}
但是拦截器没有被调用
由于REST资源是通过@RepositoryRestController管理的Spring数据REST,因此不会调用拦截器。但是如果我使用@RestController编写REST资源,它将工作
如何使拦截器与@RepositoryRestController一起工作?您必须将
TestInterceptor
添加为bean,并使用@Autowired
将其激活,只需添加以下更改即可将拦截器注册到拦截器注册表中:
curl -X GET https://localhost:8080/api/v1/users
HandlerInterceptor:
@Configuration
@SpringBootApplication
public class DemoApplication extends WebMvcConfigurerAdapter {
@Autowired
private TestInterceptor testInterceptor;
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(testInterceptor).addPathPatterns("/api/**");
}
作为示例,我已将“/api/”更改为“/”,下面是一个日志示例:
@Component
public class TestInterceptor implements HandlerInterceptor {
private static final Logger logger = LoggerFactory.getLogger(TestInterceptor.class);
@Override
public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3) throws Exception {
System.out.println("afterCompletion");
long startTime = Instant.now().toEpochMilli();
logger.info("Request URL::" + arg0.getRequestURL().toString() +
":: Start Time=" + Instant.now());
arg0.setAttribute("startTime", startTime);
}
@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;
}
}
我通过以下配置/spring boot应用程序使它工作(在/
上下文路径上,以及一个简单的用户
类spring boot v2.4.2上):
2021-02-13 00:36:31.075 INFO 14340 --- [on(2)-127.0.0.1] o.s.web.servlet.DispatcherServlet : Completed initialization in 22 ms
preHandle
postHandle
afterCompletion
2021-02-13 00:36:35.300 INFO 14340 --- [nio-8080-exec-1] com.example.demo.TestInterceptor : Request URL::http://localhost:8080/time:: Start Time=2021-02-12T22:36:35.289832Z
我使用了一个简化的:
...
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
公共接口UserRepository扩展了JpaRepository,JpaSpecificationExecutor{}
您是否尝试过使用@Component
注释对TestInterceptor
进行注释?刚刚尝试过,如果容器扫描和管理了TestInterceptor
,那么您应该将其注入,而不是执行新建TestInterceptor()
。这样行吗<代码>@Autowired TestInterceptor TestInterceptor代码>和注册表.addInterceptor(testInterceptor).addPathPathPatterns(“/api/**”)代码>刚刚尝试了autowire,同样的事情确保testinterceptor bean正在创建并注入到配置bean中?在第行注册表.addInterceptor…
之前,断言testInterceptor!=无效代码>?我不想显得粗鲁,但您至少应该通过引用来确认此解决方案的原始作者…您的代码中甚至有错误的注释,因为混淆了我在上面的注释中链接的两个答案:
2021-02-13 00:36:31.075 INFO 14340 --- [on(2)-127.0.0.1] o.s.web.servlet.DispatcherServlet : Completed initialization in 22 ms
preHandle
postHandle
afterCompletion
2021-02-13 00:36:35.300 INFO 14340 --- [nio-8080-exec-1] com.example.demo.TestInterceptor : Request URL::http://localhost:8080/time:: Start Time=2021-02-12T22:36:35.289832Z
...
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> { }