博客项目(5、全局统一处理)

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第6天,点击查看活动详情

一、前言

在上一章中我对个人博客项目进行了项目创建,初始化pom文件,使用mybatis-plus自动生成代码并成功启动项目

本章我对个人博客项目的全局异常处理,使用同一返回类Result,使用mybatis-plus分页插件,

二、全局异常处理

全局异常处理是配合着同一返回响应来的,可能也说不上谁配合谁,处理异常,然后返回统一的Result

创建全局异常类 BlogExceptionHandler 使用 @RestControllerAdvice 注解来拦截所有的Controller异常,使用 @ExceptionHandler 注解来拦截指定的异常类

异常枚举类如下

package com.ningxuan.blog.common.exception;

public enum ErrorEnum {
    /*** 通用部分 100 - 599***/
    // 成功请求
    SUCCESS(200, "successful"),
    // 重定向
    REDIRECT(301, "redirect"),
    // 资源未找到
    NOT_FOUND(404, "not found"),
    // 服务器错误
    SERVER_ERROR(500, "server error"),
    ;
    /**
     * 响应状态码
     */
    private Integer code;
    /**
     * 响应信息
     */
    private String message;

    ErrorEnum(Integer code, String msg) {
        this.code = code;
        this.message = msg;
    }

    public Integer getCode() {
        return code;
    }

    public String getMessage() {
        return message;
    }
}
复制代码

自定义异常如下

@Data
public class BlogException extends RuntimeException {
    private static final long serialVersionUID = 1L;

    private int code;
    private String msg;

    public BlogException(int code) {
        this.code = code;
        this.msg = ErrorEnum.SUCCESS.getMessage();
    }

    public BlogException(int code, String... params) {
        this.code = code;
        this.msg = ErrorEnum.SUCCESS.getMessage();
    }

    public BlogException(int code, Throwable e) {
        super(e);
        this.code = code;
        this.msg = ErrorEnum.SUCCESS.getMessage();
    }

    public BlogException(int code, Throwable e, String... params) {
        super(e);
        this.code = code;
        this.msg = ErrorEnum.SUCCESS.getMessage();
    }

    public BlogException(String msg) {
        super(msg);
        this.code = ErrorEnum.SUCCESS.getCode();
        this.msg = msg;
    }

    public BlogException(String msg, Throwable e) {
        super(msg, e);
        this.code = ErrorEnum.SUCCESS.getCode();
        this.msg = msg;
    }

}
复制代码

全局异常处理如下

@RestControllerAdvice
public class BlogExceptionHandler {
    private static final Logger logger = LoggerFactory.getLogger(BlogExceptionHandler.class);


    /**
     * 处理自定义异常
     */
   @ExceptionHandler(BlogException.class)
   public ResultVo handleRenException(BlogException ex){
        ResultVo result = new ResultVo();
      result.error(ex.getCode(), ex.getMsg());
      return result;
   }


    /**
     * 处理全局异常
     * @param ex
     * @return
     */
    @ExceptionHandler(Exception.class)
    public ResultVo handleException(Exception ex){
        logger.error(ex.getMessage(), ex);

        return new ResultVo().error();
    }
}
复制代码

三、同一返回工具Result

现在大多都是使用微服务框架, 每个人一个或多个模块开发,后端如此,前端也一样, 所以记性一个统一的返回响应格式是很有必要的。

统一响应采用Result风格,json格式,由状态码code,消息message,返回内容date,请求状态success构成,具体如下

package com.ningxuan.blog.model.base;

import com.ningxuan.blog.common.exception.ErrorEnum;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;

import java.io.Serializable;

@Data
@AllArgsConstructor
public class ResultVo<T> implements Serializable {
    /**
     * 编码:0表示成功,其他值表示失败
     */
    @ApiModelProperty(value = "编码:200表示成功,其他值表示失败")
    private int code = 200;
    /**
     * 消息内容
     */
    @ApiModelProperty(value = "消息内容")
    private String msg = "请求成功";
    /**
     * 响应数据
     */
    @ApiModelProperty(value = "响应数据")
    private T data;
    /**
     * success
     */
    @ApiModelProperty(value = "success")
    private Boolean success = true;

    public ResultVo<T> ok(T data) {
        this.setData(data);
        return this;
    }

    public boolean success() {
        return code == 200;
    }

    public ResultVo<T> error() {
        this.code = ErrorEnum.SUCCESS.getCode();
        this.msg = ErrorEnum.SUCCESS.getMessage();
        return this;
    }

    public ResultVo<T> error(int code) {
        this.code = code;
        this.msg = ErrorEnum.SUCCESS.getMessage();
        return this;
    }

    public ResultVo<T> error(int code, String msg) {
        this.code = code;
        this.msg = msg;
        return this;
    }

    public ResultVo<T> error(String msg) {
        this.code = ErrorEnum.SUCCESS.getCode();
        this.msg = msg;
        return this;
    }


    public ResultVo() {
        this.code = code;
        this.msg = msg;
        this.data = data;
        this.success = success;
    }


}
复制代码

封装的page分页类如下

@Data
@AllArgsConstructor
@NoArgsConstructor
public class PageVo {
    @ApiModelProperty("模糊查询, 关键字查询")
    private String keyword;

    @ApiModelProperty("开始时间")
    private LocalDateTime startTime;

    @ApiModelProperty("结束时间")
    private LocalDateTime endTime;

    // 默认第一页
    @ApiModelProperty
    private Integer page = 1;

    // 默认每页10行
    @ApiModelProperty
    private Integer size = 10;
}
复制代码

四、使用mybatis-plus插件

这边直接使用的mybatis-plus官方的分页插件和校验工具

@Configuration
public class MybatisPlusConfig {

    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
        // 分页插件
        mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor());
        // 乐观锁
        mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        // 防止全表更新与删除
        mybatisPlusInterceptor.addInnerInterceptor(new BlockAttackInnerInterceptor());

        return mybatisPlusInterceptor;
    }

}
复制代码

五、总结

本章到这里就结束了,完成了项目开发之前的一些准备工作,下一章开始就是代码开发了

下几章的内容应该是

  • 登录接口文章(使用验证码,jwt生成token,redis存储token)
  • 文章、分类、标签管理、评论区和归档的简单增删改查

项目启动正常 image.png

猜你喜欢

转载自juejin.im/post/7129057556172898340