拦截器没有被 SpringBoot 初始化和调用
Interceptor not getting initialized and invoked with SpringBoot
我有一个 Spring-Boot 应用程序,它被打包为 war 并具有 tomcat 所提供的依赖性(所以我有两个选项 - 使用打包的 .[=在通过 java -jar 命令启动嵌入式容器后,48=] 到 运行 并且在独立的 servlet 容器上也到 运行。
下面是我的应用程序主class
package com.mycompany.edsa.dgv.proxysvc;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.support.SpringBootServletInitializer;
import org.springframework.context.annotation.Bean;
//import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.ImportResource;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import com.mycompany.edsa.dgv.proxysvc.interceptor.DGVProxySvcRequestInterceptor;
//import com.mycompany.edsa.dgv.proxysvc.config.ConfigExtension;
@SpringBootApplication
@ImportResource("classpath:dgv-proxy-svc-spring-ctx.xml")
//@Import(ConfigExtension.class)
public class DGVProxySvcAppMain extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(DGVProxySvcAppMain.class, args);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(DGVProxySvcAppMain.class);
}
@Bean
public DGVProxySvcRequestInterceptor dgvProxySvcRequestInterceptor() {
DGVProxySvcRequestInterceptor dgvProxySvcReqInterceptor = new DGVProxySvcRequestInterceptor();
return dgvProxySvcReqInterceptor;
}
@Bean
public WebMvcConfigurerAdapter adapter() {
return new WebMvcConfigurerAdapter() {
@Override
public void addInterceptors(InterceptorRegistry registry) {
System.out.println("Adding interceptors");
registry.addInterceptor(dgvProxySvcRequestInterceptor()).addPathPatterns("/*");
super.addInterceptors(registry);
}
};
}
}
我的拦截器 class 下面:
package com.mycompany.edsa.dgv.proxysvc.interceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
@Component
public class DGVProxySvcRequestInterceptor extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
/* Put in the code here to validate user principal before passing control to the controller */
//BXPPrincipal principal = (BXPPrincipal)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
//Map<String, ?> result = principal.getAttributes();
System.out.println("Inside DGVProxySvcRequestInterceptor...");
return super.preHandle(request, response, handler);
}
}
但是,在启动应用程序时(我通过 spring-boot:run
maven 目标启动并使用 Eclipse IDE),我没有看到我的拦截器在控制台日志中注册。
我尝试在 public void addInterceptors(InterceptorRegistry registry)
方法的断点下以调试模式启动它,我看到控制在此时出现并且 sysout 消息 "Adding interceptors"
登录到控制台并且 registry
包含我的DGVProxySvcRequestInterceptor
在其封装的 ArrayList 中,但不确定为什么控制台上没有消息提及有关此拦截器 bean 初始化的任何信息。
此外,在调用我的服务时,我没有看到系统输出消息 "Inside DGVProxySvcRequestInterceptor..."
已放入我的拦截器 class' preHandle
方法(这确认拦截器未被调用)。
有人可以帮我找出我可能犯的配置错误吗?
请注意 - 我尝试使用 WebMvcConfigurerAdapter
而不是 SpringBootServletInitializer
扩展我的主要 class 并覆盖 addInterceptors
方法来添加我的拦截器。在那种情况下,我的拦截器会得到很好的初始化(我可以在控制台日志中看到),并且在我调用我的服务 uri 时也会被调用。
所以这告诉我,当我尝试使用 SpringBootServletInitializer
时,我的配置有些不正确(我必须使用这个初始化程序,因为我需要将我的代码打包为 war 可以 运行 在独立的 servlet 容器上)。
提前感谢任何 suggestions/pointers !
@Configuration
@EnableWebMvc
public class AppConfig extends WebMvcConfigurerAdapter {
// @Bean resolvers , etc
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new DGVProxySvcRequestInterceptor()).addPathPatterns("/controller/action/*");
}
}
找到修复。必须使用 ant
like url 模式来匹配请求:
registry.addInterceptor(dgvProxySvcRequestInterceptor()).addPathPatterns("/**");
我原来的配置都很好;除了上述 url 模式外不需要任何更改。
我有同样的问题。
@SpringBootApplication
仅扫描当前包中的所有组件。为了扫描其他包,我们需要在@ComponentScan
中指定包。
例如
package com.main;
@SpringBootApplication
public class Application {
//Code goes here.
}
现在我想要注册拦截器,它既不在 com.main
也不在 com.main.**
,它在 com.test
包中可用。
package com.test.interceptor
@Configuration
public class InterceptorConfig extends WebMvcConfigurerAdapter {
@Autowired
HeaderInterceptor headerInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(headerInterceptor);
}
}
在上述情况下,Spring 引导不会在上下文中注册 HeaderInterceptor
。为了注册,我们必须明确扫描该包。
package com.main;
@SpringBootApplication
@ComponentScan("com.*") //Which takes care all the package which starts with com.
@ComponentScan({"com.main.*","com.test.*"}) //For specific packages
public class Application {
//Code goes here.
}
如果您使用的是java8,推荐的实现是WebMvcConfigurationSupport。 WebMvcConfigurerAdapter 已弃用。
我有一个 Spring-Boot 应用程序,它被打包为 war 并具有 tomcat 所提供的依赖性(所以我有两个选项 - 使用打包的 .[=在通过 java -jar 命令启动嵌入式容器后,48=] 到 运行 并且在独立的 servlet 容器上也到 运行。
下面是我的应用程序主class
package com.mycompany.edsa.dgv.proxysvc;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.support.SpringBootServletInitializer;
import org.springframework.context.annotation.Bean;
//import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.ImportResource;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import com.mycompany.edsa.dgv.proxysvc.interceptor.DGVProxySvcRequestInterceptor;
//import com.mycompany.edsa.dgv.proxysvc.config.ConfigExtension;
@SpringBootApplication
@ImportResource("classpath:dgv-proxy-svc-spring-ctx.xml")
//@Import(ConfigExtension.class)
public class DGVProxySvcAppMain extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(DGVProxySvcAppMain.class, args);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(DGVProxySvcAppMain.class);
}
@Bean
public DGVProxySvcRequestInterceptor dgvProxySvcRequestInterceptor() {
DGVProxySvcRequestInterceptor dgvProxySvcReqInterceptor = new DGVProxySvcRequestInterceptor();
return dgvProxySvcReqInterceptor;
}
@Bean
public WebMvcConfigurerAdapter adapter() {
return new WebMvcConfigurerAdapter() {
@Override
public void addInterceptors(InterceptorRegistry registry) {
System.out.println("Adding interceptors");
registry.addInterceptor(dgvProxySvcRequestInterceptor()).addPathPatterns("/*");
super.addInterceptors(registry);
}
};
}
}
我的拦截器 class 下面:
package com.mycompany.edsa.dgv.proxysvc.interceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
@Component
public class DGVProxySvcRequestInterceptor extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
/* Put in the code here to validate user principal before passing control to the controller */
//BXPPrincipal principal = (BXPPrincipal)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
//Map<String, ?> result = principal.getAttributes();
System.out.println("Inside DGVProxySvcRequestInterceptor...");
return super.preHandle(request, response, handler);
}
}
但是,在启动应用程序时(我通过 spring-boot:run
maven 目标启动并使用 Eclipse IDE),我没有看到我的拦截器在控制台日志中注册。
我尝试在 public void addInterceptors(InterceptorRegistry registry)
方法的断点下以调试模式启动它,我看到控制在此时出现并且 sysout 消息 "Adding interceptors"
登录到控制台并且 registry
包含我的DGVProxySvcRequestInterceptor
在其封装的 ArrayList 中,但不确定为什么控制台上没有消息提及有关此拦截器 bean 初始化的任何信息。
此外,在调用我的服务时,我没有看到系统输出消息 "Inside DGVProxySvcRequestInterceptor..."
已放入我的拦截器 class' preHandle
方法(这确认拦截器未被调用)。
有人可以帮我找出我可能犯的配置错误吗?
请注意 - 我尝试使用 WebMvcConfigurerAdapter
而不是 SpringBootServletInitializer
扩展我的主要 class 并覆盖 addInterceptors
方法来添加我的拦截器。在那种情况下,我的拦截器会得到很好的初始化(我可以在控制台日志中看到),并且在我调用我的服务 uri 时也会被调用。
所以这告诉我,当我尝试使用 SpringBootServletInitializer
时,我的配置有些不正确(我必须使用这个初始化程序,因为我需要将我的代码打包为 war 可以 运行 在独立的 servlet 容器上)。
提前感谢任何 suggestions/pointers !
@Configuration
@EnableWebMvc
public class AppConfig extends WebMvcConfigurerAdapter {
// @Bean resolvers , etc
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new DGVProxySvcRequestInterceptor()).addPathPatterns("/controller/action/*");
}
}
找到修复。必须使用 ant
like url 模式来匹配请求:
registry.addInterceptor(dgvProxySvcRequestInterceptor()).addPathPatterns("/**");
我原来的配置都很好;除了上述 url 模式外不需要任何更改。
我有同样的问题。
@SpringBootApplication
仅扫描当前包中的所有组件。为了扫描其他包,我们需要在@ComponentScan
中指定包。
例如
package com.main;
@SpringBootApplication
public class Application {
//Code goes here.
}
现在我想要注册拦截器,它既不在 com.main
也不在 com.main.**
,它在 com.test
包中可用。
package com.test.interceptor
@Configuration
public class InterceptorConfig extends WebMvcConfigurerAdapter {
@Autowired
HeaderInterceptor headerInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(headerInterceptor);
}
}
在上述情况下,Spring 引导不会在上下文中注册 HeaderInterceptor
。为了注册,我们必须明确扫描该包。
package com.main;
@SpringBootApplication
@ComponentScan("com.*") //Which takes care all the package which starts with com.
@ComponentScan({"com.main.*","com.test.*"}) //For specific packages
public class Application {
//Code goes here.
}
如果您使用的是java8,推荐的实现是WebMvcConfigurationSupport。 WebMvcConfigurerAdapter 已弃用。