JavaWeb中的拦截器 Interceptor 解析

发布时间:2023年12月20日

一、概述

概念:是一种动态拦截方法的调用机制,类似于过滤器。Spring框架提供的,用来动态拦截控制器方法执行。

作用:拦截请求,在指定的方法调用前后,根据业务需要执行预先设定的代码。

二、快速入门

2.1 定义拦截器

实现HandlerInterceptor接口,并重写其所有的方法。

package com.itheima.tliaswebmanagement.interceptor;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

@Component
public class LoginCheckInterceptor implements HandlerInterceptor {
    //目标资源方法运行前运行,返回true: 放行, 返回false: 不放行
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("preHandle ...");
        return true;
    }

    //目标资源方法运行后运行
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle ...");
    }

    //视图渲染完毕后运行,最后运行
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("afterCompletion ...");
    }
}

2.2 注册拦截器

注册拦截器,并且添加拦截路径。

package com.itheima.tliaswebmanagement.config;

import com.itheima.tliaswebmanagement.interceptor.LoginCheckInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

public class WebConfig implements WebMvcConfigurer {

    //自动装配方法,将自定义的拦截器通过反射获取
    @Autowired
    private LoginCheckInterceptor checkInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 添加拦截器和拦截路径
        registry.addInterceptor(checkInterceptor).addPathPatterns("/**");
    }

}

2.3 拦截路径

拦截器可以根据需求,配置不同的拦截路径:

2.4?执行流程

三、登录校验Interceptor

3.1 登录检验流程图

步骤如下:

? ? ? ? 1. 获取请求url。

? ? ? ? 2. 判断请求url中是否包含login,如果包含,说明是登录操作,放行。

? ? ? ? 3. 获取请求头中的令牌(token)。

? ? ? ? 4. 判断令牌是否存在,如果不在,返回错误结果(未登录)。

? ? ? ? 5. 解析token,如果解析失败,返回错误结果(未登录)。

? ? ? ? 6. 放行。

流程图如下:

3.2 登录检验核心代码

下面是登录校验的核心代码,通过检测用户是否进行登录操作(是:就直接放行),如不是就进行jwt令牌登录校验。

package com.itheima.tliaswebmanagement.interceptor;

import com.alibaba.fastjson.JSONObject;
import com.itheima.tliaswebmanagement.pojo.Result;
import com.itheima.tliaswebmanagement.utils.JwtUtils;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

@Component
@Slf4j
public class LoginCheckInterceptor implements HandlerInterceptor {
    //目标资源方法运行前运行,返回true: 放行, 返回false: 不放行
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("preHandle ...");

        String url = request.getRequestURL().toString();
        if (url.contains("login")){
            log.info("登陆操作, 放行...");
            return true;
        }

        // 查看请求头中的token令牌
        String jwt = request.getHeader("token");
        if (!StringUtils.hasLength(jwt)){
            Result error = Result.error("NOT_LOGIN");
            String notLogin = JSONObject.toJSONString(error);
            response.getWriter().write(notLogin);
            return false;
        }

        try {
            // 调用JWT的工具类,进行解析验证
            JwtUtils.parseJWT(jwt);
        } catch (Exception e) {
            Result error = Result.error("NOT_LOGIN");
            String notLogin = JSONObject.toJSONString(error);
            response.getWriter().write(notLogin);
            e.printStackTrace();
            return false;
        }

        // 令牌合法,进行放行
        return true;
    }

    //目标资源方法运行后运行
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle ...");
    }

    //视图渲染完毕后运行,最后运行
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("afterCompletion ...");
    }
}

四、异常处理

4.1 异常来源

在一个项目中会有较多的Controller类,且每一个类都包含数个不同的方法,如果为每一个方法添加try、catch异常处理,整个代码出现臃肿。为了解决这个问题,我们可以订正一个全局异常处理器用来处理所有的异常问题。

4.2 异常处理

在项目中创建一个单独异常处理类,代码如下。

package com.itheima.tliaswebmanagement.exception;

import com.itheima.tliaswebmanagement.pojo.Result;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

@RestControllerAdvice // 异常类注解
public class GlobalExceptionHandler {

    @ExceptionHandler(Exception.class) // 定义处理什么种类的注解
    public Result ex(Exception exception){
        // 异常打印出来
        exception.printStackTrace();
        return Result.error("出现异常,请联系管理员");
    }
}

五、总结

以上就是小编的拦截器Interceptor相关知识点,如果有遗漏之处诚邀诸位指点,也希望各位看官给个点赞、留言加关注,你的支持就是我最大的动力。

文章来源:https://blog.csdn.net/Wang_ning__/article/details/135078076
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。