SpringBoot 2.x :拦截器

类似以前SpringMVC的拦截器,但也有一些区别

SpringBoot的拦截器有两种方式:

第一种方式:过时的方式,适用于SpringBoot1.x的方式

package org.dreamtech.springboot.interceptor;

import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

@SuppressWarnings(“deprecation”)
public class CustomWebMvcConfigurer extends WebMvcConfigurerAdapter {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginIntercepter()).addPathPatterns("/test/*/**");
super.addInterceptors(registry);
}
}

第二种方式:基于Java8与Spring5的方式

原理:在WebMvcConfigurer接口中定义了默认方法,利用Java8新特性:接口中可以写方法

package org.dreamtech.springboot.interceptor;

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 CustomWebMvcConfigurer implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/login/*/**");
WebMvcConfigurer.super.addInterceptors(registry);
}
}

LoginInterceptor:只是实现了三个基本方法,分别打印一句话,了解执行顺序:

package org.dreamtech.springboot.interceptor;

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

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

public class LoginInterceptor implements HandlerInterceptor {
/**
* 拦截之前调用(进入Controller之前)
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
System.out.println("[ preHandle LoginInterceptor ]");
return HandlerInterceptor.super.preHandle(request, response, handler);
}

/**
 * 调用方法之后,视图渲染之前
 */
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
        ModelAndView modelAndView) throws Exception {
    System.out.println("[ postHandle LoginInterceptor ]");
    HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
}

/**
 * 完成拦截之后,用于清理资源
 */
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
        throws Exception {
    System.out.println("[ afterCompletion LoginInterceptor ]");
    HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
}

}

Controller:

package org.dreamtech.springboot.controller;

import java.util.HashMap;
import java.util.Map;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class DemoController {

@RequestMapping("/login/account")
private Object account() {
    Map<String, Object> modelMap = new HashMap<String, Object>();
    modelMap.put("money", 1000);
    System.out.println("[ account DemoController ]");
    return modelMap;
}

}

访问localhost:8080/login/account打印情况如下:

[ preHandle LoginInterceptor ]
[ account DemoController ]
[ postHandle LoginInterceptor ]
[ afterCompletion LoginInterceptor ]

如果没有以上打印,要注意这几点:

1.是否有@Configuration注解

2.是否将拦截路径写成/xxx//**,如果是/xxx//*就会拦截失败

同样地,我们可以添加多个拦截器

    registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/login/*/**");
    registry.addInterceptor(new TestInterceptor()).addPathPatterns("/test/*/**");
    registry.addInterceptor(new DemoInterceptor()).addPathPatterns("/demo/*/**");

或者链式调用:拦截所有路径,但不包括/login

registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**").excludePathPatterns("/login");

多个拦截器的调用顺序:可以理解为包裹的方式

package org.dreamtech.springboot.interceptor;

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 CustomWebMvcConfigurer implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/login//**");
registry.addInterceptor(new DemoInterceptor()).addPathPatterns("/login/
/**");
WebMvcConfigurer.super.addInterceptors(registry);
}
}

DemoInterceptor和LoginInterceptor内容基本一致

最终的打印:

[ preHandle LoginInterceptor ]
[ preHandle DemoInterceptor ]
[ account DemoController ]
[ postHandle DemoInterceptor ]
[ postHandle LoginInterceptor ]
[ afterCompletion DemoInterceptor ]
[ afterCompletion LoginInterceptor ]

最后:

Filter和Interceptor的区别:

1.Filter基于Servlet,而Interceptor不依赖于Servlet容器

2.Filter只在容器被初始化的时候被调用一次,Interceptor次数没有限制

3.Interceptor基于AOP思想,Filter基于doFilter方法

两者的执行顺序:

过滤前->拦截前->Controller->拦截后->过滤后
深圳网站建设:https://www.sz886.com

猜你喜欢

转载自blog.csdn.net/chenmh12/article/details/89950440
今日推荐