您的位置:首页 > 汽车 > 新车 > 全国企业信用信息公开系统查询_网页设计作品展_宁波谷歌seo推广公司_百度竞价代运营托管

全国企业信用信息公开系统查询_网页设计作品展_宁波谷歌seo推广公司_百度竞价代运营托管

2024/12/25 9:39:10 来源:https://blog.csdn.net/qq_32430463/article/details/144703546  浏览:    关键词:全国企业信用信息公开系统查询_网页设计作品展_宁波谷歌seo推广公司_百度竞价代运营托管
全国企业信用信息公开系统查询_网页设计作品展_宁波谷歌seo推广公司_百度竞价代运营托管

文章目录

  • 前言
  • 一、先定义一个业务异常类
  • 二、定义全局异常处理器
  • 二、测试
      • 抛出异常:
      • 抛出自定义异常:
  • 总结


前言

上一章对统一返回值进行封装,但是都是基于正常情况下的返回,系统难免会出现异常的情况,我们不可能在每一个地方都try...catch,但是异常有分为很多种类,我们需要对异常进行统一的拦截,希望友好的返回给客户端信息,而不是报一堆错误代码…


Spring中提供了一个@RestControllerAdvice它是 @ControllerAdvice@ResponseBody 的结合体,意味着使用该注解的类可以为所有的@RequestMapping 处理方法提供通用的异常处理和数据绑定等增强功能,并且方法的返回值将被直接写入 HTTP 响应体中,这里用来做全局异常处理正合适不过。

我们需要配合@ExceptionHandler@ResponseStatus一起结合着使用

  • @ExceptionHandler该注解用于标注在异常处理方法,该方法需要@RestControllerAdvice写到类中,其作用是当控制器抛出异常时候,Spring会根据异常的类型调用相应的异常处理方法,我们可以利用该注解实现各种不同类型的异常处理逻辑

  • @ResponseStatus该注解也是注解到异常处理方法上的,主要是为了设置返回的http状态码。如果我们希望在后端异常的时候,客户端的http状态码也跟随变化,则需要用到此注解


一、先定义一个业务异常类

com.light.common中创建一个exception包,并在exception中创建一个ServiceException代码如下:

import com.light.common.result.IResultCode;import java.io.Serial;/*** 自定义业务异常类*/
public class ServiceException extends RuntimeException {@Serialprivate static final long serialVersionUID = -2184933109131865121L;private IResultCode resultCode;public ServiceException(IResultCode resultCode) {super(resultCode.getMessage());this.resultCode = resultCode;}public ServiceException(String message) {super(message);}public ServiceException(Throwable cause) {super(cause);}public ServiceException(String message, Throwable cause) {super(message, cause);}public IResultCode getErrorCode() {return resultCode;}
}

二、定义全局异常处理器

exception中创建一个GlobalExceptionHandler代码如下:

import cn.hutool.core.convert.Convert;
import cn.hutool.http.HTMLFilter;
import com.light.common.result.BaseResult;
import com.light.common.result.ResultCode;
import io.micrometer.common.util.StringUtils;
import jakarta.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingPathVariableException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;/*** 全局异常处理器*/
@RestControllerAdvice
public class GlobalExceptionHandler {private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);/*** 自定义业务异常*/@ExceptionHandler(ServiceException.class)@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)@ResponseBodypublic Object handleServiceException(ServiceException e, HttpServletRequest request) {log.error("自定义业务异常,'{}'", e.getMessage(), e);if (e.getErrorCode() != null) {return BaseResult.error(e.getErrorCode());}return BaseResult.error(e.getMessage());}/*** 自定义验证异常*/@ExceptionHandler(BindException.class)@ResponseStatus(HttpStatus.BAD_REQUEST)@ResponseBodypublic BaseResult<?> handleBindException(BindException e) {log.error(e.getMessage(), e);BindingResult bindingResult = e.getBindingResult();String message = null;if (bindingResult.hasErrors()) {FieldError fieldError = bindingResult.getFieldError();if (fieldError != null) {message = fieldError.getField() + fieldError.getDefaultMessage();}}return BaseResult.error(message);}/*** 请求参数类型不匹配*/@ExceptionHandler(MethodArgumentTypeMismatchException.class)@ResponseStatus(HttpStatus.BAD_REQUEST)@ResponseBodypublic BaseResult<?> handleMethodArgumentTypeMismatchException(MethodArgumentTypeMismatchException e,HttpServletRequest request) {String requestURI = request.getRequestURI();String value = Convert.toStr(e.getValue());if (StringUtils.isNotEmpty(value)) {value = new HTMLFilter().filter(value);}log.error("请求参数类型不匹配'{}',发生系统异常.", requestURI, e);return BaseResult.error(String.format("请求参数类型不匹配,参数[%s]要求类型为:'%s',输入值为:'%s'", e.getName(), e.getRequiredType().getName(), value));}/*** 请求路径中缺少必需的路径变量*/@ExceptionHandler(MissingPathVariableException.class)@ResponseStatus(HttpStatus.BAD_REQUEST)@ResponseBodypublic BaseResult<?> handleMissingPathVariableException(MissingPathVariableException e, HttpServletRequest request) {String requestURI = request.getRequestURI();log.error("请求路径中缺少必需的路径变量'{}',发生系统异常.", requestURI, e);return BaseResult.error(String.format("请求路径中缺少必需的路径变量[%s]", e.getVariableName()));}/*** 参数验证异常*/@ExceptionHandler(MethodArgumentNotValidException.class)@ResponseStatus(HttpStatus.BAD_REQUEST)@ResponseBodypublic BaseResult<?> handleMethodArgumentNotValidException(MethodArgumentNotValidException e, HttpServletRequest request) {String requestURI = request.getRequestURI();BindingResult bindingResult = e.getBindingResult();String message = null;if (bindingResult.hasErrors()) {FieldError fieldError = bindingResult.getFieldError();if (fieldError != null) {message = fieldError.getField() + fieldError.getDefaultMessage();}}log.error("请求地址'{}',参数验证失败", requestURI);return BaseResult.error(ResultCode.VALIDATE_FAILED, message);}/*** 请求方式异常*/@ExceptionHandler(HttpRequestMethodNotSupportedException.class)@ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED)@ResponseBodypublic BaseResult<?> handleHttpRequestMethodNotSupported(HttpRequestMethodNotSupportedException e,HttpServletRequest request) {String requestURI = request.getRequestURI();log.error("请求地址'{}',不支持'{}'请求", requestURI, e.getMethod());return BaseResult.error(ResultCode.METHOD_FAILED, "请求方式不支持:{}" + e.getMethod());}/*** 拦截未知的运行时异常*/@ExceptionHandler(RuntimeException.class)@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)@ResponseBodypublic BaseResult exceptionHandler(RuntimeException e, HttpServletRequest request) {String requestURI = request.getRequestURI();log.error("请求地址'{}',发生未知异常.", requestURI, e);return BaseResult.error("未知异常:"+e.getMessage());}/*** 拦截系统异常*/@ExceptionHandler(Exception.class)@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)@ResponseBodypublic BaseResult handleException(Exception e, HttpServletRequest request) {String requestURI = request.getRequestURI();log.error("请求地址'{}',发生系统异常.", requestURI, e);return BaseResult.error("系统异常:"+e.getMessage());}
}

二、测试

通过上述代码处理后,我们在写业务逻辑的时候,只需要关心自己的主要业务,无需花费大量精力去写try...catch

抛出异常:

  • 我们在控制器中人为制造一个异常比如,除数为0
    @GetMapping("/getMsg")public BaseResult<?> getTest() {int s=1/0;
//        throw new ServiceException("自定义异常");return BaseResult.success("成功");}

测试请求,返回结果如下
在这里插入图片描述

抛出自定义异常:

如果需要对自己的业务代码进行自定义抛出异常可采用此方式

    @GetMapping("/getMsg")public BaseResult<?> getTest() {throw new ServiceException("自定义异常");}

测试请求,返回结果如下
在这里插入图片描述

总结

至此,我们对整个系统进行的全局异常的统一处理,写代码的时候不再花费大量精力考虑try...catch的事情了,这也是后端需要做到的统一返回标准

下一章写统一日志处理

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com