异常
如果是运行时异常:运行时异常可以直接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中又抛出异常 是为了回滚!