【问题标题】:How to apply HandlerInterceptor to Spring Boot Actuator endpoints?如何将 HandlerInterceptor 应用于 Spring Boot Actuator 端点?
【发布时间】:2015-08-30 14:31:33
【问题描述】:

我正在使用 Java 8Spring 1.2.3 构建在 Tomcat 7 容器中运行的应用程序。

我确实使用非常简单的HandlerInterceptor 拦截了对我的网络应用程序的每一次调用,它记录了创建响应所花费的总时间以及每个请求的返回码。

我通过简单地添加 spring-boot-starter-actuator 依赖项来激活执行器端点,并通过调用添加拦截器

@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {

    @Autowired
    private Application application;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(application.executeTimeInterceptor());
    }

}

显然,Spring Boot Actuator 管理的所有端点(/info/health 等)都不会被拦截:如何确保拦截器拦截对我的应用程序的所有调用,包括调用执行器提供的端点的那些?

【问题讨论】:

  • 你用的是tomcat还是jetty?
  • Tomcat 7 - 也添加到问题中

标签: java spring spring-mvc spring-boot


【解决方案1】:

在 tomcat 中,您还可以添加一个阀门来拦截对 Web 服务器的调用。阀门将拦截所有端点,而不管它们的拦截器堆栈如何。

这是一个关于如何在 spring boot 中实现阀门的示例:

@Configuration
public class TomcatConfiguration {

    private static final Logger LOG = LoggerFactory.getLogger(TomcatConfiguration.class);

    @Bean
    public EmbeddedServletContainerFactory servletContainer() {
        final TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory();
        tomcat.addContextValves(new ValveBase() {
            @Override
            public void invoke(final Request request, final Response response) throws IOException, ServletException {
                final long start = System.currentTimeMillis();
                getNext().invoke(request, response);
                LOG.debug("Used time to invoke " + request.getRequestURI() + " : " + (System.currentTimeMillis() - start));
            }
        });
        return tomcat;
    }

}

【讨论】:

  • 我试过你的方法,阀门只在嵌入式tomcat中工作。如果我生成 .war 文件并将其部署到 tomcat 实例,则不会调用 Valve。你知道如何解决这个问题吗?谢谢。
  • 您可能必须在 context.xml 中手动配置它。有关详细信息,请参阅文档tomcat.apache.org/tomcat-7.0-doc/config/valve.html
【解决方案2】:

在 Spring Boot 1.x 中,您可以使用 EndpointHandlerMappingCustomizer 来配置执行器端点的拦截器。例如:

@Bean
public EndpointHandlerMappingCustomizer mappingCustomizer() {
    return new EndpointHandlerMappingCustomizer() {

        @Override
        public void customize(EndpointHandlerMapping mapping) {
            mapping.setInterceptors(new Object[] { application.executeTimeInterceptor() });
        }

    };
}

【讨论】:

  • 根据this conversation,在SpringBoot 2.0中删除了EndpointHandlerMappingCustomizer。这里是一个example基于Servlet Filters提出的解决方案。
猜你喜欢
  • 2016-05-10
  • 1970-01-01
  • 2021-08-25
  • 2016-06-01
  • 2015-02-22
  • 1970-01-01
  • 1970-01-01
  • 2020-09-15
  • 2016-09-07
相关资源
最近更新 更多