springBoot 在过滤器中如何捕获抛出的异常并自定义返回信息
一般springBoot自带的全局异常捕获机制都是在业务层发生的异常来进行捕获的,因为过滤器的执行顺序是在全局异常机制启动之前执行的,所以一旦过滤器中发生异常,全局异常捕获机制无法使用
现在有一个围魏救赵的思路
在过滤器中try-catch掉需要捕获的异常,然后转发到controller在重新抛出,这样全局异常机制可以起作用,返回自定义信息
举个例子:
SpringSecurity使用过滤器链来实现用户校验,一旦签名出错,过滤器链中抛出响应的异常,我们不想抛出异常,而是返回相关错误信息。此时使用上述思路很容易做到
下面是真实代码:
这是一个过滤器,我们try-catch掉异常,然后转发给相应的controller
public class JWTAuthorizationFilter extends BasicAuthenticationFilter {private static final String LOGIN_URL = "/login";private static String token = null;public JWTAuthorizationFilter(AuthenticationManager authenticationManager) {super(authenticationManager);}@Overrideprotected void doFilterInternal(HttpServletRequest request,HttpServletResponse response,FilterChain chain) throws IOException, ServletException {String tokenHeader = request.getHeader(TokenEnum.TOKEN_HEADER.getValue());// 如果请求头中没有Authorization信息或者是登录接口直接放行了if (tokenHeader == null || !tokenHeader.startsWith(TokenEnum.TOKEN_PREFIX.getValue()) || request.getRequestURL().toString().contains(LOGIN_URL)) {chain.doFilter(request, response);return;}// 如果请求头中有token,则进行解析,并且设置认证信息try {if (JWTAuthorizationFilter.token != null) {refreshToken(token);SecurityContextHolder.getContext().setAuthentication(getAuthentication(token));} else {refreshToken(tokenHeader);SecurityContextHolder.getContext().setAuthentication(getAuthentication(tokenHeader));}} catch (RefreshTokenException | ExpiredJwtException e) {// 异常捕获,发送到expiredJwtExceptionrequest.setAttribute("expiredJwtException", e);//将异常分发到/expiredJwtException控制器request.getRequestDispatcher("/expiredJwtException").forward(request, response);} catch (AccessDeniedException | SignatureException e) {// 异常捕获,发送到signatureExceptionrequest.setAttribute("signatureException", e);//将异常分发到/signatureException控制器request.getRequestDispatcher("/signatureException").forward(request, response);}super.doFilterInternal(request, response, chain);}
异常controller
package com.hongseng.app.controller;import com.hongseng.app.config.exception.RefreshTokenException;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.security.SignatureException;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import javax.servlet.http.HttpServletRequest;/*** @program: fire_control* @description:* @author: fbl* @create: 2021-01-18 07:54**/
@RestController
public class JwtExceptionController {/*** 重新抛出异常*/@RequestMapping("/expiredJwtException")public void expiredJwtException(HttpServletRequest request) throws ExpiredJwtException, RefreshTokenException {if (request.getAttribute("expiredJwtException") instanceof ExpiredJwtException) {throw ((ExpiredJwtException) request.getAttribute("expiredJwtException"));} else {throw new RefreshTokenException();}}@RequestMapping("/signatureException")public void signatureException(HttpServletRequest request) throws SignatureException {throw ((SignatureException) request.getAttribute("signatureException"));}}
然后在使用全局异常机制捕获并返回自定义信息即可
package com.hongseng.app.config.exception;import enums.ErrorCodeEnum;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.security.SignatureException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import result.Result;/*** @program: fire_control* @description: 处理自定义的业务异常* @author: fbl* @create: 2021-01-15 16:21**/
@ControllerAdvice
public class GlobalExceptionHandler {/*** token过期** @return*/@ExceptionHandler(value = {ExpiredJwtException.class, RefreshTokenException.class})@ResponseBodypublic Result expiredJwtException() {return Result.failure(ErrorCodeEnum.SYS_ERR_TOKEN_EXPIRED);}/*** token错误** @return*/@ExceptionHandler(value = SignatureException.class)@ResponseBodypublic Result signatureException() {return Result.failure(ErrorCodeEnum.SYS_ERR_TOKEN_SIGNATURE);}}
springBoot 在过滤器中如何捕获抛出的异常并自定义返回信息相关推荐
- java中主函数抛出的异常怎么解决_java – 从递归函数中抛出异常
我为一个更大的应用程序构建了一个库/模块,它从函数中抛出异常.如果找不到文件或文件包含错误格式,则抛出Exeption. 该方法看起来像: Shape parse(String path) throw ...
- java 异常 不抛_java中的不抛出的异常是什么
RuntimeException与其子类和错误(Error)不是必须要捕获或抛出. Java异常Throwable分为两类:Error和Exception,Error类是错误,程序本身不能处理的. E ...
- JSqlParser4.3版本无法解析mysql中JSON_OBJECT函数抛出ParseException异常
2022年3月31日,找了一下午的bug bug 已经提交issues,详情请看GitHub,地址:https://github.com/JSQLParser/JSqlParser/issues/15 ...
- java抛异常 代替返回_请问业务层方法是抛出一个异常好还是返回一个结果更好...
@Override public Response checkUserToken(long uid, String accessToken, String deviceToken){ Response ...
- java 抛出指定异常信息_java 抛出异常处理的方法
java 抛出异常处理的方法 为了避免调用的人不知道有异常,才抛出异常的,所以是谁掉用的久在哪里处理.说的对吗 对. 1.throws关键字通常被应用在声明方法时,用来指定可能抛出的异常.多个异常可以 ...
- Java中主线程如何捕获子线程抛出的异常
Java中主线程如何捕获子线程抛出的异常 参考文章: (1)Java中主线程如何捕获子线程抛出的异常 (2)https://www.cnblogs.com/jpfss/p/10272885.html ...
- java 异常 不抛,java中不捕获或抛出的异常
java中不捕获或抛出的异常 发布时间:2020-06-25 14:29:16 来源:亿速云 阅读:137 作者:Leah 这期内容当中小编将会给大家带来有关java中不捕获或抛出的异常,文章内容丰富 ...
- 【Java 多线程】Java中主线程如何捕获子线程抛出的异常
首先明确线程代码的边界.其实很简单,Runnable接口的run方法所界定的边界就可以看作是线程代码的边界.Runnable接口中run方法原型如下: public void run(); 而所有的具 ...
- [转]Java中主线程如何捕获子线程抛出的异常
这么来看待这个问题.首先明确线程代码的边界.其实很简单,Runnable接口的run方法所界定的边界就可以看作是线程代码的边界.Runnable接口中run方法原型如下: << ...
最新文章
- 优化:梯度下降法、牛顿法、共轭梯度法
- 优化mysql服务器硬件包括_MySQL优化之一:服务器硬件和操作系统
- java redis设置过期时间_Redis的一些核心原理
- NOIP模拟题——dun
- 关于wcf三大工具的使用(wsdl.exe svcutil.exe disco.exe)
- Context node attribute expand trouble shooting guide
- java version 和javac版本不一致_解决linux下javac -version和java -version版本显示不一致...
- 页面访问的常见错误码解析
- 随机森林需要分训练集测试集吗_讨论记录用随机森林对生存数据降维,筛选signature...
- haproxy5-ssl
- 资深面试官解答:大厂月薪过20K的测试工程师,都需要满足哪些要求?
- 学习J2ME需要掌握的七种技术
- SCSA网络安全------数据传输安全-------广域网加速解决方案
- 算法竞赛入门经典经典例题及习题题解
- Context.getDir
- 京东静态网页设计案例(1)
- STM32基础11--模数转换(ADC)
- Linux下文件备份和同步的工具软件
- 网络系统高可用是几个9?
- ftp文件缓存服务器,ftp服务器上的缓存在哪