在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
原文地址:https://www.cnblogs.com/eaglelihh/p/13604626.html