异常处理机制

异常

如果是运行时异常:运行时异常可以直接throw抛出异常,即打印异常提示信息,不需要显式throws处理,但此时抛出代码后,下面代码不会运行;
也可以自己解决,使用try-catch-finally方法,解决之后会打印红字异常提示信息,但是和throw相比,下面代码会继续运行   (运行时异常不要考虑throws 没意义!)
如果是检查时异常:检查时异常不能直接throw抛出异常对象,需要显式throws异常类处理,也可以使用try-catch-finally方法处理。同样的,throw抛出异常后代码停止,try-catch-finally解决后代码继续运行。

SpringSecurity的异常处理机制和springboot 统一异常处理二者冲突吗?  

1.授权是在filter(FilterSecurityInterceptor)  不会被全局异常捕获

2.认证过程比较复杂

JwtAuthenticationTokenFilter  这个过滤器中的异常不会被全局捕获

loadUserByUsername中的异常方法会被全局捕获 (进入controller,所以能被全局异常捕获,即被controllerAdvice捕获)

结论: 不会冲突,只要保证两种异常处理机制返回相同格式的json即可!

一、SpringSecurity的异常处理机制

希望在认证失败或者是授权失败的情况下也能和我们的接口一样返回相同结构的json,这样可以让前端能对响应进行统一的处理。

在SpringSecurity中,如果我们在认证或者授权的过程中出现了异常会被ExceptionTranslationFilter捕获到。在ExceptionTranslationFilter中会去判断是认证失败还是授权失败出现的异常。

如果是认证过程中出现的异常会被封装成AuthenticationException然后调用AuthenticationEntryPoint对象的方法去进行异常处理。

如果是授权过程中出现的异常会被封装成AccessDeniedException然后调用AccessDeniedHandler对象的方法去进行异常处理。

所以如果我们需要自定义异常处理,我们只需要自定义AuthenticationEntryPoint和AccessDeniedHandler然后配置给SpringSecurity即可。

二、  springboot 统一异常处理

我们对SpringBoot全局的异常处理有哪些呢?_文渡呀的博客-CSDN博客

这里留下一个疑问: 统一异常处理和编译时异常冲突吗   编译时异常如果上抛到controller 是不是必须要trycatch了   ?   不是的  请结合我springboot中的事务那篇文章

使用方式

定义一个类,使用@ControllerAdvice注解该类,使用@ExceptionHandler注解方法。@RestControllerAdvice注解是@ControllerAdvice注解的扩展(@RestControllerAdvice=@ControllerAdvice+@ResponseBody),返回值自动为JSON的形式。

例子 :

学习spring security的时候

package com.sangeng.exception;

import com.sangeng.domian.ServerResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;


@ControllerAdvice
public class DefaultGlobalExceptionHandler {

    /**
     * bizException方法是品达项目 用来处理业务异常的方法
     * mySqlHandler 是mms项目处理自定义异常MyException
     * 放在一起对比学习
     */


/*    @ExceptionHandler(BizException.class)
    public R<String> bizException(BizException ex, HttpServletRequest request) {
        log.warn("BizException:", ex);
        return R.result(ex.getCode(), StrPool.EMPTY, ex.getMessage()).setPath(request.getRequestURI());
    }*/

    /**
     * 拦截捕捉自定义异常 MyException.class
     * @param ex
     * @return
     */
    @ResponseBody
    @ExceptionHandler(value = MyException.class)
    public ServerResponse mySqlHandler(MyException ex) {
        //log.error("系统自定义异常捕获到:{}", ex);
        ex.printStackTrace();
        return ServerResponse.createByErrorCodeMessage(ex.getStatus(), ex.getMsg());
    }


}

三 throw和throws的区别

详述throw 和throws;检查时异常与运行时异常_JAVAnuonuo的博客-CSDN博客_throw()可以抛出检查异常吗前者是抛出 后者是声明   

以下这行代码和 1/0是一样的 都是运行时异常  这行代码是手动抛出 1/0是系统抛 

所有的运行时异常都继承了RnuTimeException

 throw new MyException(ResponseCode.PASSWORD_ERROR);


2023/1/14 

在做fortune的项目时候 

 try里面的CSVUtils.readSalesImportDataCSV(file) 报了异常 但是程序没有停  还是插入了 

点开该方法 发现该方法用了try catch  所以不会被这里的try-catch捕捉到 

一点点总结: fortune 没有用全局处理  而是对于运行时异常采取了try-catch  发生异常被捕捉后 “5.如果发生异常,回滚数据,终止处理,发送邮件通知,更新EDI配置信息表,EDI履历主表,EDI履历明细表”

用到全局处理则另当别论  但是道理相通

通常会将事务配置在 Service 层, 当数据库操作失败时, 让 Service 层抛出运行时异常, 而不进行 try-catch 处理, Spring 事物管理器就会进行回滚. 为了事务回滚

但 Service 层抛出后. 在 Controller 层就需要 try-catch 去捕获异常, 否则会返回原生错误信息到客户端. 但是, 如果在 Controller 层的每个方法体里面都写一些模板化的 try-catch 的代码, 代码不但不美观, 也增加了维护的难度, 特别是还需要对 Service 层的不同异常进行不同处理的时候.

所以说 catch中又抛出异常 是为了回滚! 


 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值