全局异常是无法处理Filter过滤器的异常信息
Tomcat容器的请求路径是:从过滤器后再到拦截器的。如果过滤器异常,拦截器压根就没法执行方法。
如果想了解完整Tomcat容器结构,请跳转查看:
全局异常拦截说明
@ExceptionHandler支持多个异常数组
但是多个@ExceptionHandler的异常类信息不允许重复,切记!
@ResponseStatus(value = HttpStatus.BAD_REQUEST) 用于指定响应码。
当然也可以在方法的返回值设为ResponseEntity,在此对象指定响应吗。
全局异常拦截器代码
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.CannotAcquireLockException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import javax.servlet.http.HttpServletRequest;
/**
* @Author :zanglk
* @DateTime :2021/3/11 13:54
* @Description :AOP 思想 统一全局异常处理。MVC提供一个@ControllerAdvice注解去处理异常
* @Notes :
* 特别说明
* 1、@ExceptionHandler支持多个异常数组。但是多个@ExceptionHandler的异常类信息不允许重复,切记!
* 2、@ResponseStatus(value = HttpStatus.BAD_REQUEST) 用于指定响应码。当然也可以在方法的返回值设为ResponseEntity,在此对象指定响应吗。
*/
@ControllerAdvice // 如果需要关闭全局异常拦截,直接注释此注解即可
public class GlobalExceptionHandler {
private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);
/**
* 处理非法参数异常
*
* @param req 请求:可以记录一些传参的内容。你可以自定义日志与向响应的信息,只是当前没用到。
* @param e 异常对象。
* @return 响应实体
*/
@ExceptionHandler(value = IllegalStateException.class)
@ResponseBody
public ResponseEntity bizExceptionHandler(HttpServletRequest req, IllegalStateException e) {
logger.error("接收了一个非法参数的异常:{}", e.getMessage());
return ResponseEntity.badRequest().body("数据传输错误,导致非法参数异常,请联系管理员处理!");
}
/**
* 处理空指针的异常
*
* @param req 请求:可以记录一些传参的内容。你可以自定义日志与向响应的信息,只是当前没用到。
* @param e 异常对象。
* @return 响应实体
*/
@ExceptionHandler(value = NullPointerException.class)
@ResponseBody
public ResponseEntity exceptionHandler(HttpServletRequest req, NullPointerException e) {
logger.error("接收了一个空指针的异常:{}", e.getMessage());
return ResponseEntity.badRequest().body("空指针异常,请联系管理员处理!");
}
/**
* 数字格式异常异常处理
*
* @param req 请求:可以记录一些传参的内容。你可以自定义日志与向响应的信息,只是当前没用到。
* @param e 异常对象。
* @return 响应实体
*/
@ExceptionHandler(value = NumberFormatException.class)
@ResponseBody
public ResponseEntity numberFormatException(HttpServletRequest req, NumberFormatException e) {
logger.error("接收了一个数字格式的异常:{}", e.getMessage());
return ResponseEntity.badRequest().body("好兄弟,数字转换异常!请检查传参的数据类型哈!");
}
/**
* 请求方法不支持异常
*
* @param req 请求:可以记录一些传参的内容。你可以自定义日志与向响应的信息,只是当前没用到。
* @param e 异常对象。
* @return 响应实体
*/
@ExceptionHandler(value = HttpRequestMethodNotSupportedException.class)
@ResponseBody
public ResponseEntity httpRequestMethodNotSupportedException(HttpServletRequest req, NumberFormatException e) {
//e.printStackTrace();
logger.error("请求方式错误的异常:{}", e.getMessage());
return ResponseEntity.badRequest().body("好兄弟,请求方式不对哈!请检查请求方式!");
}
/**
* 类型转换异常处理
*
* @param req 请求:可以记录一些传参的内容。你可以自定义日志与向响应的信息,只是当前没用到。
* @param e 异常对象。
* @return 响应实体
*/
@ExceptionHandler(value = ClassCastException.class)
@ResponseBody
public ResponseEntity classCastException(HttpServletRequest req, NumberFormatException e) {
logger.error("类型转换 异常:{}", e.getMessage());
return ResponseEntity.badRequest().body("好兄弟,类型转换异常!请检查传参的数据类型哈!");
}
/**
* 死锁异常 不能确认锁异常:可能产生原因:A是大事务,然后指定了B业务,B业务也有个事务,A等B提交事务,B一直无法提交事务,这个事务 上述有执行一遍 就会造成死锁异常
*
* @param req 请求:可以记录一些传参的内容。你可以自定义日志与向响应的信息,只是当前没用到。
* @param e 异常对象。
* @return 响应实体
*/
@ExceptionHandler(value = CannotAcquireLockException.class)
@ResponseBody
public ResponseEntity cannotAcquireLockException(HttpServletRequest req, NumberFormatException e) {
logger.error("死锁异常:{},为了避免锁表,请使用'select * from information_schema.INNODB_TRX' 如果锁表了,快速kill 某个trx_mysql_thread_id,以解除锁表", e.getMessage());
return ResponseEntity.badRequest().body("好兄弟,锁表异常!请检查管理员处理!");
}
@ExceptionHandler(value = HttpMessageNotReadableException.class)
public ResponseEntity httpMessageNotReadableExceptionHandler(HttpServletRequest req, HttpMessageNotReadableException e) {
logger.error("HttpMessageNotReadableException 异常" +
"[传参问题:下面给出一些常见排查方案] \n" +
"1、请求体为空\n" +
"例如接口需要 @RequestBody 参数,但前端未传递或请求体为空。\n" +
"2、JSON 格式错误\n" +
"前端传递的 JSON 语法有误,如缺少括号、逗号等。\n" +
"3、参数类型不匹配\n" +
"请求体字段类型与后端实体类不一致,比如字符串传成了数字。\n" +
"4、字段名不匹配\n" +
"JSON 字段名与后端对象属性名不一致,且未加映射注解。\n" +
"5、Content-Type 错误\n" +
"请求头未设置 Content-Type: application/json,导致无法反序列化。\n" +
"6、GET 请求带请求体\n" +
"GET 方法本不支持请求体,但接口参数用了 @RequestBody。\n" +
"7、日期格式不对\n" +
"JSON 中的日期字符串格式与后端实体类不兼容。", e);
return ResponseEntity.badRequest().body("传参有误,请联系管理员看下日志");
}
/**
* 全部异常处理,一旦上述异常没有捕获到,就会触发本方法去拦截异常!
*
* @param req 请求:可以记录一些传参的内容。你可以自定义日志与向响应的信息,只是当前没用到。
* @param e 异常对象。
* @return 响应实体
*/
@ExceptionHandler(value = Exception.class)
@ResponseBody
public ResponseEntity allException(HttpServletRequest req, Exception e) {
logger.error("接收了一个未处理的异常:{}", e.getMessage());
return ResponseEntity.badRequest().body("后台没有定义本次异常的处理,请联系后台,并向后台提供异常操作时间,以便于检查日志!");
}
}
然后抓一个异常,就可以被拦截了。
特殊说明:
上述文章均是作者实际操作后产出。烦请各位,请勿直接盗用!转载记得标注原文链接:www.zanglikun.com
第三方平台不会及时更新本文最新内容。如果发现本文资料不全,可访问本人的Java博客搜索:标题关键字。以获取最新全部资料 ❤
免责声明: 本站文章旨在总结学习互联网技术过程中的经验与见解。任何人不得将其用于违法或违规活动!所有违规内容均由个人自行承担,与作者无关。
第三方平台不会及时更新本文最新内容。如果发现本文资料不全,可访问本人的Java博客搜索:标题关键字。以获取最新全部资料 ❤
免责声明: 本站文章旨在总结学习互联网技术过程中的经验与见解。任何人不得将其用于违法或违规活动!所有违规内容均由个人自行承担,与作者无关。

评论(0)