【学习笔记-拦截器的实现】

这篇博客详细介绍了Spring拦截器的定义、配置及执行顺序。内容包括多个拦截器的执行逻辑,当preHandle返回false时的影响,以及拦截器与过滤器的区别。此外,还讨论了拦截器的核心机制ThreadLocal的作用,以及如何使用HandlerInterceptorAdapter适配器来避免实现不必要的回调方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  • 拦截器的定义
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Component
public class MyHandlerInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("--------------拦截器A进行preHandle拦截--------------");
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("--------------拦截器A进行postHandle拦截--------------");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("--------------拦截器A进行afterCompletion拦截--------------");
    }
}

可以复制实现多个拦截器,执行顺序按照配置文件的配置顺序进行执行

  • 拦截器的配置
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Autowired
    private MyHandlerInterceptor myHandlerInterceptor;

    @Autowired
    private MyHandlerInterceptorB myHandlerInterceptorB;


    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(myHandlerInterceptor).addPathPatterns("/*");
        registry.addInterceptor(myHandlerInterceptorB).addPathPatterns("/**");

    }
}

ConfigApplication不许需要加格外的注释

  • 拦截器和过滤器的执行顺序
    在这里插入图片描述

  • 两个拦截器的执行顺序
    在这里插入图片描述
    上述为所有拦截器均正常通行(preHandle方法return true),当preHandle方法return false时,执行结果如下:

  • 拦截器A的preHandle为FALSE:
    在这里插入图片描述

  • 拦截器B的preHandle为FALSE:
    在这里插入图片描述

原因如下:

  1. 拦截器A放行,拦截器B的preHandle才会执行。
  2. 拦截器B的preHandle不放行,拦截器B的postHandle和afterCompletion都不会执行。
  3. 只要有一个拦截器不放行,postHandle不会执行。

特别的是afterCompletion,类似于try-catch-finally中的finally,但仅调用处理器执行链中preHandle返回true的拦截器的afterCompletion。

拦截器总结

  1. 在preHandler中return false,则postHandle、afterCompletion都不会执行
  2. 在handler中抛出异常,则afterCompletion会执行,postHandle不执行(无论是否有ExceptionHandler)
  3. 正常运行,则postHandle、afterCompletion两个方法都会执行
  4. 拦截器核心:ThreadLocal。主要作用:实现本地线程内实现数据共享.并且是线程安全的

拦截器的适配器

有时候我们可能只需要实现三个回调方法中的某一个,如果实现HandlerInterceptor接口的话,三个方法必须实现,不管你需不需要,此时spring提供了一个HandlerInterceptorAdapter适配器(一种适配器设计模式的实现),允许我们只实现需要的回调方法。

在JWS SOAP Web Service中,可以使用Handler实现过滤器/拦截器的效果,对接口请求和响应进行处理。 Handler是Java EE中的一个标准接口,用于处理Web Service请求和响应。在JWS SOAP Web Service中,Handler可以对请求和响应进行处理,类似于Servlet中的过滤器和拦截器。 Handler可以在请求到达Web Service之前或者响应离开Web Service之后进行处理,可以对SOAP消息的头和体进行处理,可以修改SOAP消息中的内容,可以设置SOAP消息的属性等。 在JWS SOAP Web Service中,使用Handler需要完成以下步骤: 1. 创建Handler类,实现javax.xml.ws.handler.Handler接口,并实现其方法。 2. 在Web Service实现类中,使用@HandlerChain注解指定Handler链的位置和名称。 3. 在Handler链的配置文件中,指定Handler类的位置和名称,并指定Handler类的处理顺序。 示例代码如下: Handler类: ```java public class MyHandler implements SOAPHandler<SOAPMessageContext> { public boolean handleMessage(SOAPMessageContext context) { Boolean outbound = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY); if (outbound) { System.out.println("Handle outbound message."); } else { System.out.println("Handle inbound message."); } return true; } public boolean handleFault(SOAPMessageContext context) { System.out.println("Handle message fault."); return true; } public void close(MessageContext context) { System.out.println("Close handler."); } public Set<QName> getHeaders() { return null; } } ``` Web Service实现类: ```java @WebService @HandlerChain(file = "handler-chain.xml") public class MyWebService { @WebMethod public String sayHello(String name) { return "Hello, " + name + "!"; } } ``` Handler链配置文件handler-chain.xml: ```xml <?xml version="1.0" encoding="UTF-8"?> <handler-chains xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/handler-chains_1_0.xsd"> <handler-chain> <handler> <handler-class>com.example.MyHandler</handler-class> </handler> </handler-chain> </handler-chains> ``` 在上面的示例中,我们创建了一个MyHandler类,实现javax.xml.ws.handler.Handler接口,并实现了handleMessage、handleFault、close和getHeaders方法。在MyWebService类中,使用@HandlerChain注解指定了Handler链的位置和名称。在handler-chain.xml中,指定了MyHandler类的位置和名称,并指定了处理顺序。 当Web Service被调用时,MyHandler类会对请求和响应进行处理,并输出相关信息。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值