【问题标题】:Interceptor not getting initialized and invoked with SpringBoot拦截器没有被 SpringBoot 初始化和调用
【发布时间】:2016-10-25 19:43:15
【问题描述】:

我有一个 Spring-Boot 应用程序,它被打包为一个带有 tomcat 依赖项的战争(所以我有两个选项 - 在通过 java -jar 命令启动它后使用打包的 .war 在嵌入式容器中运行,并且还在独立的 servlet 容器上运行)。

下面是我的App主类

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);
        }
    };
}

}

我的拦截器类如下:

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) 方法处的断点启动它,我看到控制在此时出现,系统输出消息"Adding interceptors" 登录控制台,registry 在其封装中包含我的DGVProxySvcRequestInterceptor ArrayList 但不确定为什么控制台上没有消息提及有关此拦截器 bean 的初始化的任何信息。 此外,在调用我的服务时,我没有看到已放入我的拦截器类的 preHandle 方法中的 sysout 消息 "Inside DGVProxySvcRequestInterceptor..."(这证实了拦截器没有被调用)。

有人可以帮我找出我可能在做的配置错误吗?

请注意 - 我尝试使用 WebMvcConfigurerAdapter 而不是 SpringBootServletInitializer 扩展我的主类,并覆盖 addInterceptors 方法来添加我的拦截器。在那种情况下,我的拦截器会很好地初始化(我可以在控制台日志上看到),并且在我调用我的服务 uri 时也会被调用。 所以这告诉我,当我尝试使用 SpringBootServletInitializer 时,我的配置不正确(我必须使用这个初始化程序,因为我需要将我的代码打包为可以在独立 servlet 容器上运行的战争)。

提前感谢您的任何建议/指点!

【问题讨论】:

    标签: spring spring-boot interceptor


    【解决方案1】:

    找到了解决办法。必须使用 ant 之类的 url 模式来匹配请求:

    registry.addInterceptor(dgvProxySvcRequestInterceptor()).addPathPatterns("/**");
    

    我原来的配置都很好;除了上述 url 模式外,不需要任何更改。

    【讨论】:

      【解决方案2】:

      我有同样的问题。 @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 Boot 不会在上下文中注册 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.
      }
      

      【讨论】:

        【解决方案3】:
        @Configuration
        @EnableWebMvc 
        public class AppConfig extends WebMvcConfigurerAdapter  {  
            // @Bean resolvers , etc
        
            @Override
            public void addInterceptors(InterceptorRegistry registry) {
        
                registry.addInterceptor(new DGVProxySvcRequestInterceptor()).addPathPatterns("/controller/action/*");
            }
        } 
        

        【讨论】:

        • 我相信使用 @EnableWebMvc 会避免使用 Spring 的自动配置。在不覆盖自动配置的情况下添加拦截器是否没有解决方法?
        • 另外,尝试了上述建议;没有帮助。首先调用控制器,然后调用拦截器!
        • 您是否正确替换了您的操作网址 'addPathPatterns'
        【解决方案4】:

        如果您使用的是 java 8,推荐的实现是 WebMvcConfigurationSupport。 WebMvcConfigurerAdapter 已弃用。

        【讨论】:

        • 由于某种原因,当我从 WebMvcConfigurerAdapter 切换到 WebMvcConfigurationSupport 的那一刻,我的请求开始被拦截.. 谢谢
        猜你喜欢
        • 1970-01-01
        • 2018-03-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-09-05
        • 1970-01-01
        • 2011-07-29
        相关资源
        最近更新 更多