filter,servlet,listener,interceptor

在SpringBootApplication上使用@ServletComponentScan注解后,

Servlet、Filter、Listener可以直接通过@WebServlet、@WebFilter、@WebListener注解自动注册,无需其他代码。

过滤器

默认使用的4个

在启动打印出来的日志里有:

  • Filter 'requestContextFilter' configured for use

  • Filter 'hiddenHttpMethodFilter' configured for use

  • Filter 'characterEncodingFilter' configured for use

  • Filter 'formContentFilter' configured for use

优先级

低位值意味着更高的优先级。自定义Filter,避免和默认的Filter优先级一样,不然会冲突。

 

作用(使用场景)

  • 比如用户验证。

  • 如果涉及页面跳转,filter就不适合 前后端分离的情况。

实例

启动类 加上 注解

@ServletComponentScan

自定义的filter

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebFilter(urlPatterns = {"/api/*"})
public class LoginFilter implements Filter {

    /**
     * 容器加载的时候调用
     */
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("init loginFilter");
    }

    /**
     * 请求被拦截的时候进行调用
     */
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("doFilter loginFilter");
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        String username = request.getParameter("username");
        if ("xdclass".equals(username)) {
            filterChain.doFilter(request, response);
        }else {
            response.sendRedirect("/index.html");    // 重定向
        }
    }

    @Override
    public void destroy() {
        System.out.println("destroy loginFilter");
    }
}

测试

添加controller的访问方法。

@GetMapping(value="/api/v1/account")
public Object account(){
    params.put("money", "1000");
    return params;
}

访问  http://localhost:8080/api/v1/account?username=xdclass

{
"money": "1000"
}

测试通过。

自定义servlet

例子

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet(urlPatterns = {"/v1/api/test/customs"}, name = "userServlet")
public class UserServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.getWriter().print("custom sevlet");
        resp.getWriter().flush();
        resp.getWriter().close();
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req, resp);
    }
}

启动类 加上 @ServletComponentScan , 和 过滤器的使用 很像。

监听器

自定义Listener(常用的监听器 servletContextListener、httpSessionListener、servletRequestListener)。

@WebListener
public class RequestListener implements ServletRequestListener {

    @Override
    public void requestDestroyed(ServletRequestEvent sre) {
        // TODO Auto-generated method stub
       System.out.println("======requestDestroyed========");
    }

    @Override
    public void requestInitialized(ServletRequestEvent sre) {
     System.out.println("======requestInitialized========");
  } 、
}

拦截器

1、老方法,jdk8之前

继承 WebMvcConfigurerAdapter

 
 

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

 
 


@Configuration
public class CustomOldWebMvcConfigurer extends WebMvcConfigurerAdapter {

 
 

@Override
public void addInterceptors(InterceptorRegistry registry) {

 
 

registry.addInterceptor(new LoginIntercepter()).addPathPatterns("/api/");

super.addInterceptors(registry);
}

 

 

2、jdk8之后的新方法

使用 implements WebMvcConfigurer

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 LoginIntercepter())
.addPathPatterns("/api/login/**");
WebMvcConfigurer.super.addInterceptors(registry);
}
}

 

3、以上添加了拦截器,现在 给出自定义的拦截器。

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

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

public class LoginIntercepter implements HandlerInterceptor{

    /**
     * 进入controller方法之前
     */
    @Override
    public boolean preHandle(HttpServletRequest request,
            HttpServletResponse response, Object handler) throws Exception {
        System.out.println("LoginIntercepter------->preHandle");

//        String token = request.getParameter("access_token");
//        
//        response.getWriter().print("fail");
        
        return HandlerInterceptor.super.preHandle(request, response, handler);
    }

    /**
     * 调用完controller之后,视图渲染之前
     */
    @Override
    public void postHandle(HttpServletRequest request,
            HttpServletResponse response, Object handler,
            ModelAndView modelAndView) throws Exception {
        
        System.out.println("LoginIntercepter------->postHandle");
        
        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }

    /**
     * 整个完成之后,通常用于资源清理
     */
    @Override
    public void afterCompletion(HttpServletRequest request,
            HttpServletResponse response, Object handler, Exception ex)
            throws Exception {
        System.out.println("LoginIntercepter------->afterCompletion");
        
        HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
    }
    
    
}

小结

  • 是基于函数回调 doFilter(),而Interceptor则是基于AOP思想。

  • Filter在只在Servlet前后起作用,而Interceptor能够深入到方法前后、异常抛出前后等。

  • 依赖于Servlet容器即web应用中,而Interceptor不依赖于Servlet容器所以可以运行在多种环境。

  • 在接口调用的生命周期里,Interceptor可以被多次调用,而Filter只能在容器初始化时调用一次。

  • Filter和Interceptor的执行顺序 过滤前->拦截前->action执行->拦截后->过滤后。

 

猜你喜欢

转载自www.cnblogs.com/wuyicode/p/11251983.html