项目中的异常处理

规范异常类型

在Service类的业务方法中有很多的参数合法性校验,当请求参数不合法的时候会抛出异常,但此时异常信息只会在控制台输出,前端界面并不会提示用户

实际开发前端和后端需要做一些约定: 一般将错误提示信息统一以json格式返回前端,以HTTP状态码决定当前请求是否出错(非200为操作异常)

{
    "timestamp":"2023-02-02T14:42:36.820+00:00",
    // 添加课程设置一个负数的课程价格会报500异常
    "status":500,
    "error":"Internal Server Error",
    "message":"",
    "path":"/content/course"
}

为了统一处理异常信息,我们需要在业务方法自定义规范项目中抛出的异常类型,这样可以便于统一去捕获这一类或几类的异常

规范了异常类型, 我们需要捕获异常信息,使用try/catch方式去捕获代码比较臃肿,可以统一由SpringMVC提供的控制器增强类去完成异常的捕获

在这里插入图片描述

异常处理(base工程)

第一步: 添加依赖,base基础工程实现统一异常处理,由于各模块依赖base基础工程所以都可以使用异常处理

<dependency&gt;
    <groupId&gt;org.springframework</groupId>
    <artifactId>spring-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>

第二步: 定义一个枚举CommonError,枚举一些通用的异常信息对象

package com.xuecheng.base.execption;
/**
* @description 通用错误信息
*/
public enum CommonError {
    UNKOWN_ERROR("执行过程异常,请重试"),
    PARAS_ERROR("非法参数"),
    OBJECT_NULL("对象为空"),
    QUERY_NULL("查询结果为空"),
    REQUEST_NULL("请求参数为空");
    private String errMessage;
    public String getErrMessage() {
        return errMessage;
    }
    CommonError(String errMessage) {
        this.errMessage = errMessage;
    }
}

第三步: 自定义项目的异常类型XueChengPlusException

package com.xuecheng.base.execption;
/**
* @description 学成在线项目异常类
*/
public class XueChengPlusException extends RuntimeException {
    private String errMessage;

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

第四步: 自定义响应异常信息的模型

package com.xuecheng.base.execption;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class RestErrorResponse implements Serializable {
    private String errMessage;
}

第五步: 定义全局异常处理器捕获异常信息同时记录异常日志, 将异常信息封装到异常信息的模型类并响应用户,实现服务端全局异常处理

package com.xuecheng.base.execption;
/**
* @description 全局异常处理器
*/
@Slf4j
@ControllerAdvice
public class GlobalExceptionHandler {
    @ResponseBody
    @ExceptionHandler(XueChengPlusException.class)// 处理项目自定义异常类型
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) // 该异常枚举对象的错误码为500
    public RestErrorResponse customException(XueChengPlusException exception) {
        log.error("系统异常:{}", exception.getErrMessage());
        return new RestErrorResponse(exception.getErrMessage());
    }

    @ResponseBody
    @ExceptionHandler(Exception.class)// 未知类型的异常
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)// 该异常枚举对象的错误码为500
    public RestErrorResponse exception(Exception exception) {
        log.error("系统异常:{}", exception.getMessage());
        return new RestErrorResponse(exception.getMessage());
    }
}

异常处理测试(api工程)

第一步: 在内容管理服务api工程添加base工程依赖

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

第二步: 当业务方法中出现异常时抛出项目自定义的异常类型,这里新增课程的业务方法为例进行代码修改

@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(charge.equals("201001")){
        if(courseMarketNew.getPrice() ==null || courseMarketNew.getPrice().floatValue()<=0){
            throw new XueChengPlusException("课程的价格不能为空并且必须大于0");
        }
    }
}

第三步: 使用HTTP Client进行测试,故意将收费课程价格设置为负数, 查看捕获到的响应信息

在这里插入图片描述

POST http://localhost:53040/content/course

HTTP/1.1 500 
Content-Type: application/json
Transfer-Encoding: chunked
Date: Fri, 03 Feb 2023 02:32:20 GMT
Connection: close

{
  "errMessage": "课程设置了收费,价格不能为空,且必须大于0"
}

原文地址:https://blog.csdn.net/qq_57005976/article/details/134679695

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。

如若转载,请注明出处:http://www.7code.cn/show_3998.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注