如何配置spring拦截器以在每个请求中调用

Posted

技术标签:

【中文标题】如何配置spring拦截器以在每个请求中调用【英文标题】:How to configure spring interceptor to get called with every request 【发布时间】:2017-10-24 17:15:07 【问题描述】:

我想配置我的 spring 拦截器,使得每个请求都应该被调用。

我在 API-GATEWAY 中使用拦截器 (Spring-Boot) 我正在从 API-GATEWAY 调用其他微服务。 从 API-GATEWAY 对其他微服务的调用工作正常。 我调用的其他服务是 Node.js 服务,另一方面,我的 API-Gateway 处于 Spring Boot 中。 所有服务(Node.js + Spring-Boot)都在 Docker 容器上运行。

我在拦截器中遇到问题。我想以这样一种方式对其进行配置,即每个请求都应该被称为preHandle() 并执行我在其中编写的操作。

我注意到一个问题,我想在这里提一下。

如果我正在调用的服务已停止(未运行),则 Interceptor 正在正常工作并给我一个响应,例如 somename-service not found。 如果此时正在运行相同的服务,则不执行拦截器。

这是我的代码 sn-p

@EnableEurekaClient
@SpringBootApplication
@EnableZuulProxy
@Configuration
public class Application extends WebMvcConfigurerAdapter 

    public static void main(String[] args) 
        SpringApplication.run(Application.class, args);
    

    @Autowired
    private TokenValidateInterceptor tokenValidateInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) 

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


    

拦截器

@Component
public class TokenValidateInterceptor extends HandlerInterceptorAdapter 


    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) 
        LOG.info("#### Starting TokenValidateInterceptor.preHandle ####");

        String apiKey = null;
        try 
            apiKey = request.getHeader("apikey");

            LOG.info("The request come with apikey ======" + apiKey);

            LOG.info("Actual apikey ======" + azureApikey);



【问题讨论】:

你的 TokenValidateInterceptor 是什么样的? 我已经更新了我的问题并放入了 TokenValidateInterceptor 代码。 【参考方案1】:

您必须将此拦截器添加到您的调度程序 xml 文件中:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:p="http://www.springframework.org/schema/p"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans.xsd">


    <bean id="handlerMapping" class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" p:interceptors-ref="tokenInterceptor" />

    <bean id="tokenInterceptor" class="yourpackage.TokenValidateInterceptor" />

</beans>

这里有几个不错的示例:

Spring MVC Interceptot Dzone Spring Interceptor

【讨论】:

我正在使用 Spring-Boot。所以不需要dispatcher-servlet 你能分享你的拦截器的完整代码吗?我会很高兴检查它是如何调用服务的...... 拦截器没有调用其他节点js服务。它使用 bootstrap.yml 中配置的 Zuell 路由获取调用。我确信没有问题是服务电话。问题在于在上面提到的类中拦截请求【参考方案2】:

首先制作一个如下图所示的WebMvc Config类

@Configuration
public class WebMvcConfig extends WebMvcConfigurationSupport 
    @Override
    protected void addInterceptors(InterceptorRegistry registry) 
        registry.addInterceptor(new MyInterceptor());
    

通过扩展 HandlerInterceptorAdapter 创建请求拦截器,即 MyInterceptor

public class MyInterceptor extends HandlerInterceptorAdapter
    @Override
    public void postHandle(HttpServletRequest request, 
    HttpServletResponse response, 
    Object handler, 
    ModelAndView modelAndView) throws Exception 
        ......Write your business logic here...........

更多信息可以参考here

【讨论】:

【参考方案3】:

我认为在这种情况下你应该使用 HttpFilter,它有 doFilter 方法,只需覆盖该方法并执行你的代码。

【讨论】:

以上是关于如何配置spring拦截器以在每个请求中调用的主要内容,如果未能解决你的问题,请参考以下文章

如何拦截 Spring Interceptor 到 Node Service 的请求

请问,java高手,spring mvc拦截器如何拦截所有的请求啊,包括html和jsp页面?

使用 Spring Boot WebClient 时如何拦截请求

使用拦截器获取refreshtoken后如何调用相同的请求?

拦截器在 Spring Boot GraphQL 中不起作用

Spring Rest API 拦截器在每个/每个请求上添加响应标头