springboot拦截器过滤token,并返回结果及异常处理操作

下面我将为你详细讲解如何使用Spring Boot实现拦截器过滤Token并返回结果及异常处理操作。

什么是拦截器及Token认证

在Spring Boot中,拦截器是一种非常常用的组件,它可以拦截请求,进行一些处理,并执行相应的操作。Token认证是指在用户登录成功后,服务器会生成一个Token并返回给客户端,客户端在以后的请求中携带这个Token用于鉴权,服务器会验证Token的有效性以判断请求是否合法。

前置准备

在使用拦截器过滤Token之前,需要先引入相关的依赖。我们可以在pom.xml文件中添加以下内容:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.9.1</version>
</dependency>

其中,spring-boot-starter-web是Spring Boot的Web相关依赖,jjwt是JWT(Java Web Token)的Java实现库,用于Token的生成和校验。

实现拦截器过滤Token

为了实现拦截器过滤Token,我们需要创建一个实现HandlerInterceptor接口的拦截器类,在该类中实现Token的验证和相应的处理逻辑。以下是一个简单的示例:

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

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

@Component
public class AuthInterceptor implements HandlerInterceptor {

    @Autowired
    private TokenConfig tokenConfig;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (request.getMethod().equals(RequestMethod.OPTIONS.name())) {
            response.setStatus(HttpServletResponse.SC_OK);
            return true;
        }
        String token = request.getHeader("Authorization");
        if (token == null) {
            throw new ApiException("缺少AccessToken");
        }
        Claims claims = Jwts.parser().setSigningKey(tokenConfig.getSecretKey()).parseClaimsJws(token).getBody();
        if (claims == null) {
            throw new ApiException("无效AccessToken");
        }
        // TODO: 进行权限验证
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

    }
}

其中,TokenConfig是一个封装了Token认证相关配置内容的类;ApiException是一个自定义异常类,用于统一处理异常并返回错误信息。在preHandle方法中,我们首先对OPTIONS请求进行处理,因为它是一个预检请求,不需要进行Token的验证。然后,我们从Authorization请求头中获取Token,如果有Token,就使用jjwt解析出其中的Claims内容,并进行权限验证(这里我们只是简单地验证了Token是否有效),如果验证成功,就返回true;否则,就抛出ApiException异常并返回错误信息。

接下来,我们需要将该拦截器注册到Spring Boot的配置中,这可以通过WebMvcConfigurer接口的实现类来实现。例如:

import org.springframework.beans.factory.annotation.Autowired;
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 WebConfig implements WebMvcConfigurer {

    @Autowired
    private AuthInterceptor authInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(authInterceptor).addPathPatterns("/**");
    }
}

在该类中,我们先注入了上面实现的拦截器类AuthInterceptor,然后在addInterceptors方法中将其添加到InterceptorRegistry中,并配置需要拦截的路径。在这里,我们配置了所有请求都需要经过AuthInterceptor的处理。

返回结果及异常处理操作

在拦截器中,我们可以通过抛出异常来处理请求过程中的错误。但是,在实际应用中,为了更好地返回错误信息并方便客户端处理,我们需要对异常进行统一的处理,以便将错误信息封装到接口响应体中返回给客户端。

以下是一个实现了接口响应统一格式的示例:

import lombok.Data;

@Data
public class ApiResponse<T> {

    private Integer code;
    private String message;
    private T data;

    public static <T> ApiResponse<T> ok(T data) {
        ApiResponse<T> response = new ApiResponse<>();
        response.setCode(200);
        response.setMessage("OK");
        response.setData(data);
        return response;
    }

    public static <T> ApiResponse<T> error(Integer code, String message) {
        ApiResponse<T> response = new ApiResponse<>();
        response.setCode(code);
        response.setMessage(message);
        response.setData(null);
        return response;
    }
}

在该类中,我们定义了接口响应的统一格式,包括状态码、错误信息和响应数据。我们还添加了两个静态方法,用于构建成功和失败的接口响应。

AuthInterceptor中抛出异常时,我们可以在GlobalExceptionHandler中对其进行捕获和处理,并返回相应的错误信息。以下是一个简单的实现示例:

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {

    @ExceptionHandler(ApiException.class)
    public ApiResponse<Void> handleApiException(ApiException e) {
        log.warn("请求发生异常: {}", e.getMessage());
        return ApiResponse.error(e.getCode(), e.getMessage());
    }

    @ExceptionHandler(Exception.class)
    public ApiResponse<Void> handleException(Exception e) {
        log.error("请求发生异常: ", e);
        return ApiResponse.error(500, "服务内部错误,请稍后重试");
    }
}

在该类中,我们定义了两个异常处理方法,一个是处理ApiException异常,用于捕获AuthInterceptor中抛出的异常并返回错误信息;另一个是处理Exception异常,用于捕获其他未处理的异常,并返回服务内部错误的错误信息。

综合示例

以下是一个完整的示例,其中包含了基于Spring Boot的Token认证和拦截器过滤Token,并对Token认证异常进行了统一处理:

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import com.example.demo.exception.ApiException;

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

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Autowired
    private AuthInterceptor authInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(authInterceptor).addPathPatterns("/**");
    }
}

@Slf4j
@Component
public class AuthInterceptor implements HandlerInterceptor {

    @Autowired
    private TokenConfig tokenConfig;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (request.getMethod().equals(RequestMethod.OPTIONS.name())) {
            response.setStatus(HttpServletResponse.SC_OK);
            return true;
        }
        String token = request.getHeader("Authorization");
        if (token == null) {
            throw new ApiException("缺少AccessToken");
        }
        Claims claims = Jwts.parser().setSigningKey(tokenConfig.getSecretKey()).parseClaimsJws(token).getBody();
        if (claims == null) {
            throw new ApiException("无效AccessToken");
        }
        // TODO: 进行权限验证
        return true;
    }
}

@Data
public class ApiResponse<T> {

    private Integer code;
    private String message;
    private T data;

    public static <T> ApiResponse<T> ok(T data) {
        ApiResponse<T> response = new ApiResponse<>();
        response.setCode(200);
        response.setMessage("OK");
        response.setData(data);
        return response;
    }

    public static <T> ApiResponse<T> error(Integer code, String message) {
        ApiResponse<T> response = new ApiResponse<>();
        response.setCode(code);
        response.setMessage(message);
        response.setData(null);
        return response;
    }
}

@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {

    @ExceptionHandler(ApiException.class)
    public ApiResponse<Void> handleApiException(ApiException e) {
        log.warn("请求发生异常: {}", e.getMessage());
        return ApiResponse.error(e.getCode(), e.getMessage());
    }

    @ExceptionHandler(Exception.class)
    public ApiResponse<Void> handleException(Exception e) {
        log.error("请求发生异常: ", e);
        return ApiResponse.error(500, "服务内部错误,请稍后重试");
    }
}

public class ApiException extends RuntimeException {

    private Integer code;

    public ApiException(String message) {
        this(message, 400);
    }

    public ApiException(String message, Integer code) {
        super(message);
        this.code = code;
    }

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }
}

@ConfigurationProperties(prefix = "jwt")
@Data
public class TokenConfig {

    private String secretKey;
    private Long expireSeconds;
}

@RestController
@RequestMapping("/api")
public class ApiController {

    @RequestMapping(value = "/test", method = RequestMethod.GET)
    public ApiResponse<Void> test() {
        return ApiResponse.ok(null);
    }
}

在这个示例中,TokenConfigGlobalExceptionHandler类分别用于配置Token认证和统一异常处理。我们在WebConfig中将AuthInterceptor注册到了Spring Boot的配置中,并配置其拦截所有请求。在ApiController中,我们实现了一个简单的接口 test,它用于测试接口的响应结果。

到这里,我们已经完成了基于Spring Boot的Token认证和拦截器过滤Token,并对Token认证异常进行了统一处理的实现。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:springboot拦截器过滤token,并返回结果及异常处理操作 - Python技术站

(0)
上一篇 2023年5月19日
下一篇 2023年5月19日

相关文章

  • 如何使用Java编译期注解?

    下面是关于“如何使用Java编译期注解”的完整使用攻略。 什么是编译期注解? 编译期注解是在Java编译期间处理的一种注解,它可以被编译器直接解释和处理。编译器可以识别和处理这些注解,并在编译期执行相应的操作。相比于运行时注解,编译期注解更加高效、可靠和安全。 如何使用Java编译期注解? 使用Java编译期注解需要按照以下步骤进行: 1. 定义注解类 首先…

    Java 2023年5月11日
    00
  • Java中的Comparable和Comparator接口是什么?

    Java中的Comparable和Comparator接口是用于在对象排序过程中进行比较的重要接口。 Comparable接口 Comparable接口是一个内部比较器,用来实现自然排序。一个类实现了Comparable接口,就必须实现其中的compareTo()方法。该方法会返回一个整数值,表示比较结果。如果该对象小于给定对象,返回一个负整数;如果该对象等…

    Java 2023年4月27日
    00
  • SpringBoot处理JSON数据方法详解

    下面就是关于“SpringBoot处理JSON数据方法详解”的完整攻略。 1.概述 在SpringBoot中,我们通常需要使用JSON来传递数据,处理JSON数据是非常常见的操作。 SpringBoot提供了多种方式来处理JSON数据,包括: 使用SpringMVC默认的jackson插件 使用GSON插件 使用FastJson插件 这三种方式中,Sprin…

    Java 2023年5月20日
    00
  • Java定时器通信协议管理模块Timer详解

    Java定时器通信协议管理模块Timer详解 Java中的Timer类可以用于执行定时任务,其执行方式是基于线程池的,也就是说可以同时执行多个任务,并且不影响彼此之间的执行。 Timer类的基本用法 Timer类提供了两种主要的创建方式: 直接创建Timer java Timer timer = new Timer(); 指定线程名称创建Timer java…

    Java 2023年5月20日
    00
  • 自定义注解和springAOP捕获Service层异常,并处理自定义异常操作

    下面是关于自定义注解和Spring AOP结合进行Service层异常捕获并处理自定义异常操作的攻略。 1. 自定义注解 在Java的语言中,注解是一种元数据,它提供了一种在类、接口、字段、方法等的声明语句中添加元数据的方法。注解可以被标记为编译时的元数据或运行时的元数据。 自定义注解可以根据业务需求进行定义,其中注解应该只用于描述类、方法和变量等方面的信息…

    Java 2023年5月27日
    00
  • Spring Boot外部化配置实战解析

    SpringBoot外部化配置实战解析 SpringBoot是一个非常流行的Java Web框架,它可以帮助我们快速构建Web应用程序。在实际开发中,我们通常需要将一些配置信息从代码中分离出来,以便于在不同的环境中进行配置。本文将详细讲解SpringBoot外部化配置实战解析的完整攻略,并提供两个示例。 1. 配置文件 在SpringBoot中,我们可以使用…

    Java 2023年5月15日
    00
  • 一篇文章带你了解常用的Maven命令

    一篇文章带你了解常用的Maven命令 Maven是一个流行的Java项目管理工具,它可以帮助我们管理Java项目的依赖库、构建工具、测试工具等,让Java项目开发变得更加高效和便捷。在使用Maven时,我们需要学习一些常用的命令,以便能够熟练地使用Maven来管理Java项目。本篇文章将带你了解常用的Maven命令。 1. mvn clean mvn cle…

    Java 2023年5月19日
    00
  • java循环结构、数组的使用小结

    Java循环结构、数组的使用小结 循环结构 在Java中,循环结构通常有三种类型:while、do-while和for。它们都可以用于重复执行某段代码块,具体使用方式如下: while循环 使用while循环,需要在循环前定义一个初始变量,然后在每次循环结束后更新变量值,从而控制循环的几次次数 或 是否继续进入循环内部。需要注意的是,如果初始变量的值不满足条…

    Java 2023年5月26日
    00
合作推广
合作推广
分享本页
返回顶部