SpringBoot中使用借助Interceptor编写拦截器呢?

戚薇 SpringBoot 发布时间:2023-06-22 10:42:15 阅读数:11930 1
下文笔者讲述SpringBoot中编写拦截器的方法分享
学习完本篇之后,你将掌握SpringBoot中拦截器的编写方法,如下所示

SpringBoot拦截器的编写方法

springboot中编写拦截器非常简单
   我们只需实现HandlerInterceptor或AsyncHandlerInterceptor接口
   然后在配置文件中添加一下拦截器即可完成一个拦截器的开发和配置
   (AsyncHandlerInterceptor接口继承HandlerInterceptor
     多了一个afterConcurrentHandlingStarted方法)
这些接口中的方法: 
	preHandle:
	    在Controller之前运行
        可以判断参数,执行的controller方法等
        返回值为boolean
        返回true继续往下运行
        (下面的拦截器和controller)
		否则开始返回操作(运行之前的拦截器返回等操作)

	postHandle:
	    在Controller之后
         视图返回前运行
         可对ModelAndView进行处理再返回;

	afterCompletion:
	    请求完成后执行;

	afterConcurrentHandlingStarted:
	   controller返回值是java.util.concurrent.Callable时
	     才会调用该方法并使用新线程运行;

方法运行顺序有两种:
	preHandle -> 执行Controller -> postHandle -> afterCompletion;

	preHandle -> 执行Controller -> afterConcurrentHandlingStarted
	      -> callable线程执行call()方法 -> 新线程开始preHandle 
		  -> postHandle -> afterCompletion(controller方法返回Callable对象时)

配置拦截器:
   实现WebMvcConfigurer接口里的addInterceptors方法
    使用参数InterceptorRegistry对象添加自己的拦截器
     可以添加指定拦截路径或者去掉某些过滤路径
     还可以设置拦截器的优先级order
      优先级由小到大,默认0;

多个拦截器的运行顺序
    preHandle方法
	   按照order由小到大顺序
       运行完controller后
       其他方法则反向顺序
       跟过滤器Filter类似
例:拦截器的示例
package testspringboot.test9interceptor;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Test9Main {
	public static void main(String[] args) {
		SpringApplication.run(Test9Main.class, args);
	} 
}

controller类  

package testspringboot.test9interceptor;
 
import java.util.concurrent.Callable; 
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
 

@RestController
@RequestMapping("/interceptor")
public class Test9Controller {
 
    @RequestMapping("/a")
    public String a(String s) {
        System.out.println(">>>a():" + s);
        return "OK";
    }
    
    @RequestMapping("/b")
    public Callable<String> b() {
        Callable<String> callable = new Callable<String>() {
            @Override
            public String call() throws Exception {
                Thread.sleep(2000);
                System.out.println("call() thread id=" + Thread.currentThread().getId());
                Thread.sleep(2000);
                return "abcdefg";
            }
        };
        System.out.println(">>>b()");
        return callable;
    }
    
}

两个自定义拦截器1和2

package testspringboot.test9interceptor;
 
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
 
public class MyInterceptor1 implements HandlerInterceptor {
 
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        System.out.println("preHandle 1, handler=" + handler);
        return request.getQueryString().length() < 10 ? true : false; 
    }
    
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
            ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle 1");
    }
    
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
            throws Exception {
        System.out.println("afterCompletion 1");
    }
    
}

package testspringboot.test9interceptor;
 
import java.util.Date; 
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.AsyncHandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
 
@Component
public class MyInterceptor2 implements AsyncHandlerInterceptor {
 
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        System.out.println("preHandle 2 " + new Date() + " ThreadId=" + Thread.currentThread().getId());
        return true;
    }
    
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
            ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle 2");
    }
    
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
            throws Exception {
        System.out.println("afterCompletion 2");
    }
    
    @Override
    public void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        System.out.println("afterConcurrentHandlingStarted 2 " + new Date());
    }
    
}

配置拦截器

package testspringboot.test9interceptor;
 
import javax.annotation.Resource;
 
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
 
/**
 * @author XWF
 *
 */
@Configuration
public class MyInterceptorConfig implements WebMvcConfigurer {
 
    @Resource
    MyInterceptor2 myinterceptor2;
    
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new MyInterceptor1())
            .addPathPatterns("/interceptor/a")        //添加拦截路径,两种参数list<String>和String ...
            .excludePathPatterns("/interceptor/b")        //排除路径,两种参数List<String>和String ...
            .order(1);        //设置拦截器顺序,由小到大,默认0
        registry.addInterceptor(myinterceptor2);    //也可以使用spring管理的对象
    }
    
}

发送一个post测试请求
  http://192.168.1.30:8080/interceptor/a?s=hello
    拦截器2的order默认0
	拦截器1的order为1
    preHandle先执行2
    controller执行之后
   剩下的Handle都是先执行1再执行2的;

发送preHandle返回false的请求
  http://192.168.1.30:8080/interceptor/a?s=hello123456789
  拦截器1的preHandle返回false后
  直接运行2的afterCompletion;

发送测试callable的请求
   http://192.168.1.30:8080/interceptor/b?s=hello
    拦截路径配置跳过拦截器1只运行拦截器2
     通过threadid可以看到前后使用的是两个线程;
 
版权声明

本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。

本文链接: https://www.Java265.com/JavaFramework/SpringBoot/202306/6862.html

最近发表

热门文章

好文推荐

Java265.com

https://www.java265.com

站长统计|粤ICP备14097017号-3

Powered By Java265.com信息维护小组

使用手机扫描二维码

关注我们看更多资讯

java爱好者