From d57863e0d5252a78e5eae81157be161bc0765472 Mon Sep 17 00:00:00 2001 From: LGH <1242479791@qq.com> Date: Sun, 26 Apr 2020 08:19:00 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E7=BB=9F=E4=B8=80=E5=BC=82?= =?UTF-8?q?=E5=B8=B8=E5=A4=84=E7=90=86=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/统一异常处理.md | 149 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 149 insertions(+) create mode 100644 doc/统一异常处理.md diff --git a/doc/统一异常处理.md b/doc/统一异常处理.md new file mode 100644 index 0000000..7a3353a --- /dev/null +++ b/doc/统一异常处理.md @@ -0,0 +1,149 @@ +## 后台异常处理 + +在开发过程中,不可避免的是需要处理各种异常,异常处理方法随处可见,所以代码中就会出现大量的`try {...} catch {...} finally {...}` 代码块,不仅会造成大量的冗余代码,而且还影响代码的可读性,所以对异常统一处理非常有必要。为此,我们定义了一个统一的异常类`YamiShopBindException` 与异常管理类 `DefaultExceptionHandlerConfig`。 + +我们先来看下 `YamiShopBindException`的代码 + +```java +public class YamiShopBindException extends RuntimeException { + + private static final long serialVersionUID = -4137688758944857209L; + + /** + * http状态码 + */ + private Integer httpStatusCode; + + /** + * @param httpStatus http状态码 + */ + public YamiShopBindException(YamiHttpStatus httpStatus) { + super(httpStatus.getMsg()); + this.httpStatusCode = httpStatus.value(); + } + + /** + * @param httpStatus http状态码 + */ + public YamiShopBindException(YamiHttpStatus httpStatus, String msg) { + super(msg); + this.httpStatusCode = httpStatus.value(); + } + + public YamiShopBindException(String msg) { + super(msg); + this.httpStatusCode = HttpStatus.BAD_REQUEST.value(); + } + + public Integer getHttpStatusCode() { + return httpStatusCode; + } + +} +``` + +`YamiHttpStatus`为我们自定义的返回状态码的枚举类,定义为一个枚举类,更直观处理异常返回的状态码及异常内容,以后每增加一种异常情况,只需增加一个枚举实例即可,不用每一种异常都定义一个异常类。 + +```java +public enum YamiHttpStatus { + /** + * 客户端看到401状态码时,应该重新登陆 + */ + UNAUTHORIZED(401, "未授权"), + + COUPONCANNOTUSETOGETHER(601, "优惠券不能共用"), + ; + + private final int value; + + private final String msg; + + YamiHttpStatus(int value, String msg) { + this.value = value; + this.msg = msg; + } + + public int value() { + return this.value; + } + + public String getMsg() { + return msg; + } + + public static YamiHttpStatus resolve(int statusCode) { + for (YamiHttpStatus status : values()) { + if (status.value == statusCode) { + return status; + } + } + return null; + } +} +``` + +再来看看 `DefaultExceptionHandlerConfig`类 + +```java +@Controller +@RestControllerAdvice +public class DefaultExceptionHandlerConfig { + + + @ExceptionHandler(YamiShopBindException.class) + public ResponseEntity unauthorizedExceptionHandler(YamiShopBindException e){ + e.printStackTrace(); + return ResponseEntity.status(e.getHttpStatusCode()).body(e.getMessage()); + } +} +``` + + + +## 前台异常处理 + + + +前端请求与相应做了封装,请求响应的内容会被拦截器所拦截,当后台返回给前台特定的状态码,前台将显示不同报错信息。请求响应非常常见,我们查看在`src\utils\httpRequest.js`里面的其中一段代码 + + + +```javascript +http.interceptors.response.use(response => { + return response +}, error => { + switch (error.response.status) { + case 400: + Message.error(error.response.data) + break + case 401: + clearLoginInfo() + router.push({ name: 'login' }) + break + case 405: + Message.error('http请求方式有误') + break + case 500: + Message.error('服务器出了点小差,请稍后再试') + break + case 501: + Message.error('服务器不支持当前请求所需要的某个功能') + break + } + return Promise.reject(error) +}) +``` + +这里将会统一拦截返回的状态码如`400`,进行错误提示。 + + + +## RESTful 风格 + +我们的上述代码使用http状态码对请求进行统一响应,其中最大的 + +RESTful架构,就是目前最流行的一种互联网软件架构。它结构清晰、符合标准、易于理解、扩展方便,所以正得到越来越多网站的采用。 + + + +[RESTful概述](https://blog.igevin.info/posts/restful-architecture-in-general/)