springboot-7-自定义过滤器+ 自定义拦截器

SpringBoot 自定义过滤的使用:

  • (1)@WebFilter注解标记一个类为filter,并被spring进行扫描
  • (2)主启动类上面加一个@ServletComponentScan注解,进行扫描
  • (3) 非前后端分离项目适用,前后端分离项目,可以使用拦截器
  • (4) 拦截器和过滤器区别:最明显的区别:过滤器可以过滤所有资源,拦截器只能拦截请求!

1. 自定义过滤器

package com.example.lchtest.springbootdemo1.customfilter;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
 * 自定义过滤器
 */
//@WebFilter(urlPatterns = "/*",filterName = "loginFilter")  // urlPatterns如果是配置成/*则是拦截所有请求
@WebFilter(urlPatterns = "/api/*",filterName = "loginFilter")
public class LoginFilter implements Filter {
    /**
     *
     * @param filterConfig 过滤器配置
     * @throws ServletException
     */
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("LoginFilter init");
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("自定义过滤器执行doFilter逻辑.");
        HttpServletRequest req = (HttpServletRequest)request;
        HttpServletResponse resp = (HttpServletResponse) response;
        String username = req.getParameter("username");
        if(username.equals("test")){
            filterChain.doFilter(req, resp);
        } else {
            // 使用response.sendRedirect,login.html放在resources/static下面才可以,放到templates目录下不行,使用modelAnaView返回逻辑视图名可以跳到templates目录下,why??
            resp.sendRedirect("/login.html");
        }

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

在上面的自定义过滤器中,检测url中的username,如果为test则校验通过,如果为其他的值,则校验不通过,重定向到login.html :
在这里插入图片描述

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>error</title>
</head>
<body>
<h2>过滤器测试,过滤器中校验不通过,重定向到该页面!</h2>
</body>
</html>

2. 自定义拦截器

(1)自定义的拦截器,实现HandlerInterceptor 接口,重写preHandle/ postHandle / afterCompletion方法,定制业务逻辑
(2) 编写一个配置类,实现WebMvcConfigurer 接口,

package com.example.lchtest.springbootdemo1.custominterceptor;

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

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;

/**
 * 自定义拦截器
 */
public class LoginInterceptor implements HandlerInterceptor {
    /**
     * 进入controller方法之前
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("自定义拦截器 preHandle");
        // 拦截器业务处理逻辑
        String username = request.getParameter("username");
        if("test2".equals(username)){
            return true;
        } else {
            PrintWriter writer = response.getWriter();
            String result = "{\"errMsg\":\"user unAuthorized\", \"retCode\":\"401\"}";
            writer.print(result);
            writer.flush();
            writer.close();
            return false;
        }
    }

    /**
     * 调用完controller执行,视图渲染之前,如果controller中出现异常,postHandle不会被执行 afterCompletion 
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("自定义拦截器 postHandle");
    }

    /**
     * 整个controller完成之后;不管有没有异常,afterCompletion都会被调用,通常用于资源清理
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("自定义拦截器 afterCompletion");
    }
}
package com.example.lchtest.springbootdemo1.custominterceptor;

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

/**
 * 配置自定义拦截器的url并注册到springMVC中,加上@Configuration注解
 */
@Configuration
public class CustomWebMvcConfigurer implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // /*是拦截目录,/**才是拦截url路径
        registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/api2/*/**");
        WebMvcConfigurer.super.addInterceptors(registry);
    }
}

测试controller:自定义过滤器对/api/xx 的请求进行处理,自定义拦截器对api2/xx 的请求进行拦截处理

package com.example.lchtest.springbootdemo1.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

/**
 * 登录控制器:用于测试自定过滤器和自定义拦截器
 * 自定义过滤器对/api/*的请求进行处理
 * 自定义拦截器对api2/*的请求进行拦截处理
 */
@RestController
public class CustomFilterController {

    /**
     * 自定义过滤器测试
     * http://localhost:8080/api/testFilter?username=test 直接返回,改变username的值,则返回login.html
     * @param username
     * @return
     */
    @GetMapping("/api/testFilter")
    public String testFilter(@RequestParam("username") String username){
        System.out.println("username=" + username);
        return "testFilter Success";
    }

    /**
     * 自定义拦截器测试
     *  http://localhost:8080/api2/testInterceptor?username=test2 username改为其他值,返回{errMsg=user unAuthorized, retCode=401}
     * @param username
     * @return
     */
    @GetMapping("/api2/testInterceptor")
    public String testInterceptor(@RequestParam("username") String username){
        System.out.println("username=" + username);
        return "testInterceptor Success";
    }

    /**
     * 自定义拦截器,不管controlelr中有无异常,拦截器中的afterCompletion方法都会执行
     * http://localhost:8080/api2/testException?username=test2 
     * @param username
     * @return
     */
    @GetMapping("/api2/testException")
    public String testInterceptor2(@RequestParam("username") String username){
        System.out.println("username=" + username);
        int i = 1/0;
        return "testInterceptor Success";
    }
    /**
     * *********requestInitialized *********
     * 2020-01-01 14:15:57.217  INFO 12208 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
     * 2020-01-01 14:15:57.217  INFO 12208 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
     * 2020-01-01 14:15:57.219  INFO 12208 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 2 ms
     * 自定义拦截器 preHandle
     * username=test2
     * 2020-01-01 14:15:57.278  WARN 12208 --- [nio-8080-exec-1] .m.m.a.ExceptionHandlerExceptionResolver : Resolved [java.lang.ArithmeticException: / by zero]
     * 自定义拦截器 afterCompletion
     * *********requestDestroyed *********
     */
}

自定义过滤器测试结果:username为test时,校验通过,返回字符串,为其他值时,校验失败,重定向到指定页面
在这里插入图片描述
自定义拦截器测试:username为test2时,校验通过,执行后续的逻辑,为其他值时,返回校验不通过的json串
在这里插入图片描述
需要注意的是,自定义的拦截器,不管controlelr中有无异常,拦截器中的afterCompletion方法都会执行!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值