在Spring中拦截器的使用

Filter

Filter是Servlet容器实现的,并不是由Spring 实现的
下面是一个例子

import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.filter.OncePerRequestFilter;

/**
 * @date: 2020-09-02
 */
@Slf4j
public class MyFilter extends OncePerRequestFilter {
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
        log.info("filter - request : {}, response : {}", request, response);
        filterChain.doFilter(request, response);
    }
}

HandlerInterceptorAdapter

HandlerInterceptorAdapter 是Spring 通过Aop来实现的
下面是一个例子

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

/**
 * @date: 2020-09-02
 */
@Slf4j
public class MyInterceptor extends HandlerInterceptorAdapter {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        log.info("HandlerInterceptorAdapter - request : {}, response : {}", request, response);
        return true;
    }
}

HandlerMethodArgumentResolver

通过它可以对controller方法里面的参数进行赋值,比如@RequestParam注解就是通过这个拦截器实现的
下面是一个例子

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface AddHello {
}
import javax.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.MethodParameter;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

/**
 * @date: 2020-09-02
 */
@Slf4j
public class MyResolver implements HandlerMethodArgumentResolver {

    private static final String NAME_ATTRIBUTE = "name";

    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        log.info("supportsParameter, {}", parameter);
        return parameter.hasParameterAnnotation(AddHello.class);
    }

    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
                                  NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
        HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class);
        log.info("resolveArgument, {}", request);
        return request == null ? null : "hello, " + request.getParameter(NAME_ATTRIBUTE);
    }
}

config(配置类)

import java.util.List;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * @date: 2020-09-02
 */
@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Bean
    public FilterRegistrationBean<MyFilter> myFilterRegistrationBean() {
        FilterRegistrationBean<MyFilter> registrationBean = new FilterRegistrationBean();
        MyFilter i18nFilter = new MyFilter();
        registrationBean.setFilter(i18nFilter);
        registrationBean.addUrlPatterns("/*");
        registrationBean.setOrder(1);
        return registrationBean;
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new MyInterceptor());
    }

    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
        argumentResolvers.add(new MyResolver());
    }
}
import javax.servlet.http.HttpServletRequest;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @date: 2020-09-02
 */
@RestController
@RequestMapping("/hello")
public class HelloController {
    @GetMapping
    public String get(HttpServletRequest request, String name, @AddHello String hello) {
        return hello;
    }
}

实验结果

当你访问 http://127.0.0.1:8443/hello?name=abc时,会返回 hello, abc,这是因为Resolver将信息注入到hello参数中了
并且打印的日志如下,可以看到MyFilter、MyInterceptor和MyResolver都拦截到了。

10758 2020-09-02 21:30:37.272 [http-nio-8443-exec-1] INFO  c.e.d.s.a.intercept.MyFilter - filter - request : org.apache.catalina.connector.RequestFacade@27e424a4, response : org.apache.catalina.connector.ResponseFacade@37897bdf
10766 2020-09-02 21:30:37.280 [http-nio-8443-exec-1] INFO  c.e.d.s.a.intercept.MyInterceptor - HandlerInterceptorAdapter - request : org.apache.catalina.connector.RequestFacade@27e424a4, response : org.apache.catalina.connector.ResponseFacade@37897bdf
10778 2020-09-02 21:30:37.292 [http-nio-8443-exec-1] INFO  c.e.d.s.a.intercept.MyResolver - supportsParameter, method 'get' parameter 1
10783 2020-09-02 21:30:37.297 [http-nio-8443-exec-1] INFO  c.e.d.s.a.intercept.MyResolver - supportsParameter, method 'get' parameter 2
10783 2020-09-02 21:30:37.297 [http-nio-8443-exec-1] INFO  c.e.d.s.a.intercept.MyResolver - resolveArgument, org.apache.catalina.connector.RequestFacade@27e424a4
posted @   eaglelihh  阅读(324)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
点击右上角即可分享
微信分享提示