学成教育-统一异常处理实现

一、统一异常处理实现

统一在base基础工程实现统一异常处理,各模块依赖了base基础工程都 可以使用。

首先在base基础工程添加需要依赖的包:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>

1、定义一些通用的异常信息

拷贝CommonError枚举类到base工程。

package com.xuecheng.base.execption;


/**
 * @description 通用错误信息
 * @author Mr.M
 * @date 2022/9/6 11:29
 * @version 1.0
 */
public enum CommonError {

   UNKOWN_ERROR("执行过程异常,请重试。"),
   PARAMS_ERROR("非法参数"),
   OBJECT_NULL("对象为空"),
   QUERY_NULL("查询结果为空"),
   REQUEST_NULL("请求参数为空");

   private String errMessage;

   public String getErrMessage() {
      return errMessage;
   }

   private CommonError( String errMessage) {
      this.errMessage = errMessage;
   }

}

2、自定义异常类型

package com.xuecheng.base.execption;


/**
 * @description 学成在线项目异常类
 * @author Mr.M
 * @date 2022/9/6 11:29
 * @version 1.0
 */
public class XueChengPlusException extends RuntimeException {

   private static final long serialVersionUID = 5565760508056698922L;

   private String errMessage;

   public XueChengPlusException() {
      super();
   }

   public XueChengPlusException(String errMessage) {
      super(errMessage);
      this.errMessage = errMessage;
   }

   public String getErrMessage() {
      return errMessage;
   }

   public static void cast(CommonError commonError){
       throw new XueChengPlusException(commonError.getErrMessage());
   }
   public static void cast(String errMessage){
       throw new XueChengPlusException(errMessage);
   }

}

3、响应用户的统一类型

package com.xuecheng.base.execption;

import java.io.Serializable;

/**
 * 错误响应参数包装
 */
public class RestErrorResponse implements Serializable {

    private String errMessage;

    public RestErrorResponse(String errMessage){
        this.errMessage= errMessage;
    }

    public String getErrMessage() {
        return errMessage;
    }

    public void setErrMessage(String errMessage) {
        this.errMessage = errMessage;
    }
}

4、全局异常处理器

​ 从 Spring 3.0 - Spring 3.2 版本之间,对 Spring 架构和 SpringMVC 的Controller 的异常捕获提供了相应的异常处理。

  • @ExceptionHandler

    Spring3.0提供的标识在方法上或类上的注解,用来表明方法的处理异常类型。

  • @ControllerAdvice

    Spring3.2提供的新注解,从名字上可以看出大体意思是控制器增强, 在项目中来增强SpringMVC中的Controller。通常和**@ExceptionHandler** 结合使用,来处理SpringMVC的异常信息。

  • @ResponseStatus

    Spring3.0提供的标识在方法上或类上的注解,用状态代码和应返回的原因标记方法或异常类。
    调用处理程序方法时,状态代码将应用于HTTP响应。

通过上面的两个注解便可实现微服务端全局异常处理,具体代码如下:

package com.xuecheng.base.execption;

import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
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;

/**
 * @description 全局异常处理器
 * @author Mr.M
 * @date 2022/9/6 11:29
 * @version 1.0
 */
@Slf4j
@ControllerAdvice
public class GlobalExceptionHandler {

   @ResponseBody
   @ExceptionHandler(XueChengPlusException.class)
   @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
   public RestErrorResponse customException(XueChengPlusException e) {
      log.error("【系统异常】{}",e.getErrMessage(),e);
      return new RestErrorResponse(e.getErrMessage());

   }

   @ResponseBody
   @ExceptionHandler(Exception.class)
   @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
   public RestErrorResponse exception(Exception e) {

      log.error("【系统异常】{}",e.getMessage(),e);

      return new RestErrorResponse(CommonError.UNKOWN_ERROR.getErrMessage());

   }
}

二、 异常处理测试

在内容管理的api工程添加base工程的依赖

        <dependency>
            <groupId>com.xuecheng</groupId>
            <artifactId>xuecheng-plus-base</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>

在异常处理测试之前首先在代码中抛出自定义类型的异常,这里以新增课程的service方法为例进行代码修改。

 @Override
 public CourseBaseInfoDto createCourseBase(Long companyId,AddCourseDto dto) {
 ...
//合法性校验
  if (StringUtils.isBlank(dto.getName())) {
   throw new XueChengPlusException("课程名称为空");
  }

  if (StringUtils.isBlank(dto.getMt())) {
   throw new XueChengPlusException("课程分类为空");
  }

  if (StringUtils.isBlank(dto.getSt())) {
   throw new XueChengPlusException("课程分类为空");
  }

  if (StringUtils.isBlank(dto.getGrade())) {
   throw new XueChengPlusException("课程等级为空");
  }

  if (StringUtils.isBlank(dto.getTeachmode())) {
   throw new XueChengPlusException("教育模式为空");
  }

  if (StringUtils.isBlank(dto.getUsers())) {
   throw new XueChengPlusException("适应人群");
  }

  if (StringUtils.isBlank(dto.getCharge())) {
   throw new XueChengPlusException("收费规则为空");
  }
  。。。
    if ("201001".equals(charge)) {
   BigDecimal price = dto.getPrice();
   if (ObjectUtils.isEmpty(price)) {
    throw new XueChengPlusException("收费课程价格不能为空");
   }
   courseMarketNew.setPrice(dto.getPrice().floatValue());
  }
  。。。

1、首先使用httpclient测试

请求新增课程接口,故意将必填项课程名称设置为空。

测试结果与预期一致,可以捕获异常并响应异常信息,如下:

http://localhost:63040/content/course

HTTP/1.1 500 
Content-Type: application/json
Transfer-Encoding: chunked
Date: Wed, 07 Sep 2022 13:17:14 GMT
Connection: close

{
  "errMessage": "课程名称为空。"
}

三、面试

1、系统如何处理异常?

我们自定义一个统一的异常处理器去捕获并处理异常。

使用控制器增加注解@ControllerAdvice和异常处理注解@ExceptionHandler来实现。

  1. 处理自定义异常

程序在编写代码时根据校验结果主动抛出自定义异常类对象,抛出异常时指定详细的异常信息,异常处理器捕获异常信息记录异常日志并响应给用户。

  1. 处理未知异常

接口执行过程中的一些运行时异常也会由异常处理器统一捕获,记录异常日志,统一响应给用户500错误。

在异常处理器中还可以针对某个异常类型进行单独处理。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,MVC中的过滤器可以帮助我们在请求到达控制器之前或者之后进行一些预处理或后处理操作,其中异常处理也是过滤器的一种。 在MVC中,我们可以通过实现`IExceptionFilter`接口来自定义异常处理过滤器。该接口中有一个`OnException`方法,当控制器或者其它过滤器抛出异常时,该方法会被调用。我们可以在该方法中对异常进行处理并返回一个`ActionResult`类型的结果。 以下是一个简单的异常处理过滤器的示例代码: ```csharp public class CustomExceptionFilter : IExceptionFilter { public void OnException(ExceptionContext context) { // 处理异常 var exception = context.Exception; var errorMessage = "发生了一个未知的错误"; if (exception is MyCustomException) { errorMessage = exception.Message; } // 返回结果 context.Result = new ContentResult { Content = errorMessage, StatusCode = 500 }; } } ``` 在上面的代码中,我们先判断抛出的异常是否是我们自定义的`MyCustomException`类型,如果是,则将异常信息赋值给`errorMessage`变量。如果不是,则将`errorMessage`设置为一个默认值。 最后,我们将`errorMessage`作为响应内容返回给客户端,并设置状态码为500。 要使用我们自定义的异常处理过滤器,我们需要将其注册到MVC的全局过滤器集合中。可以在`Startup.cs`文件中的`ConfigureServices`方法中添加以下代码: ```csharp services.AddMvc(options => { options.Filters.Add(new CustomExceptionFilter()); }); ``` 这样,在控制器或者其它过滤器抛出异常时,就会调用我们自定义的异常处理过滤器来进行异常处理了。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值