SpringBoot [ 2.统一响应&&异常处理&&日志输出 ]

SpringBoot [ 2.统一响应&&异常处理&&日志输出 ] - 目录

文章目录

  • 1.统一响应
    • 1.1.ExceptionConstant类,Result类
  • 2.异常处理
    • 2.1.自定义异常
    • 2.2.全局异常处理器
  • 3.日志输出
    • 3.1.引入依赖
    • 3.2.配置logback.xml


SpringBoot服务搭建服务完毕,就可以写一下服务的CURD(增删改查),但是在此之前必须要把一个项目最基本组件完善起来

1.统一响应

我是用SpringBoot的这个过程,其实我接触到的项目都是前端后端分离的项目,由后端提供接口,前端通过ajax请求拿到后端数据进行渲染,那么为了方便前端处理,就要求后端接口以统一的数据结构响应前端数据.

1.1.ExceptionConstant类,Result类

我这里是封装了ExceptionConstant类,Result类来处理

package com.mantou.boot.constants;

/**
 * 异常定义-常量
 *
 * @author mantou
 */
public class ExceptionConstant {

    /**----------------------------------------------------操作类--------------------------------------------------------*/
    /**
     * 操作成功
     */
    public static final String RET_CODE_SUCCESS = "00200";
    public static final String RET_INFO_SUCCESS = "Operate Successfully ( 操作成功 ) !";
    /**
     * 操作失败
     */
    public static final String RET_CODE_FAILED = "00500";
    public static final String RET_INFO_FAILED = "Operate Failure ( 操作失败 ) !";
    /**-----------------------------------------------------操作类-------------------------------------------------------*/


    /**---------------------------------------------------服务/业务类-------------------------------------------------------*/
    /**
     * 业务异常
     */
    public static final String RET_CODE_BUSINESS_EXCEPTION = "00010";
    public static final String RET_INFO_BUSINESS_EXCEPTION = "Business Exception ( 业务异常 ) !";

    /**
     * 服务异常
     */
    public static final String RET_CODE_SERVER_EXCEPTION = "01000";
    public static final String RET_INFO_SERVER_EXCEPTION = "Server Exception ( 服务异常 ) !";
    /**---------------------------------------------------服务/业务类-------------------------------------------------------*/


    /**----------------------------------------------------请求/参数类----------------------------------------------------*/
    /**
     * HTTP请求不正确定义: 后端接口HTTP.METHOD定义与前端发起的HTTP.METHOD不符,则视为HTTP请求不正确
     */
    public static final String RET_CODE_REQUEST_EXCEPTION = "00001";
    public static final String RET_INFO_REQUEST_EXCEPTION = "Current Request Method ( GET POST PUT DELETE ) Not Supported ( 不支持当前请求方法 ) !";

    /**
     * 参数无意义empty定义: 前端请求参数无意义(null, "", []等, 视为empty)
     */
    public static final String RET_CODE_PARAM_EMPTY = "00002";
    public static final String RET_INFO_PARAM_EMPTY = "Parameters Is Empty ( 参数无意义 ) !";
    /**-----------------------------------------------------请求/参数类----------------------------------------------------*/


}

Result类

package com.mantou.boot.result;



import com.mantou.boot.constants.ExceptionConstant;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;

import java.io.Serializable;


/**
 * 项目统一响应结果类
 *
 * @author mantou
 */
@Data
public class Result implements Serializable {

    private static final long serialVersionUID = 4559672604634663976L;
    /**
     * 返回码
     */
    private String retCode;
    /**
     * 返回基础信息
     */
    private String retInfo;

    /**
     * 返回数据
     */
    private T data;


    /**------------------------------------------------------操作类方法-----------------------------------------------------**/
    /**
     * 操作成功 - 构造方法
     *
     * @return
     */
    public static  Result success() {
        return new Result(ExceptionConstant.RET_CODE_SUCCESS, ExceptionConstant.RET_INFO_SUCCESS);
    }

    /**
     * 操作成功 - 构造方法
     *
     * @param data
     * @return
     */
    public static  Result success(Object data) {
        return new Result(ExceptionConstant.RET_CODE_SUCCESS, ExceptionConstant.RET_INFO_SUCCESS, data);
    }

    /**
     * 操作失败 - 构造方法
     *
     * @return
     */
    public static  Result failed() {
        return new Result(ExceptionConstant.RET_CODE_FAILED, ExceptionConstant.RET_INFO_FAILED);
    }

    /**
     * 操作失败 - 构造方法 自定义返回基础信息
     *
     * @return
     */
    public static  Result failed(String retInfo) {
        return new Result(ExceptionConstant.RET_CODE_FAILED, retInfo);
    }

    /**
     * 操作是否成功 - 构造方法
     */
    public static  Result isSuccess(boolean isSuccess, String errorMessage, T data) {
        return isSuccess ? Result.success(data) : Result.failed(errorMessage);
    }
    /**------------------------------------------------------操作类方法-----------------------------------------------------**/


    /**----------------------------------------------------服务/业务类方法----------------------------------------------------**/
    /**
     * 服务异常 - 构造方法
     *
     * @return
     */
    public static  Result serverException() {
        return new Result(ExceptionConstant.RET_CODE_SERVER_EXCEPTION, ExceptionConstant.RET_INFO_SERVER_EXCEPTION);
    }

    /**
     * 服务异常 - 构造方法 自定义返回基础信息
     *
     * @return
     */
    public static  Result serverException(String retInfo) {
        return new Result(ExceptionConstant.RET_CODE_SERVER_EXCEPTION, retInfo);
    }

    /**
     * 业务异常 - 构造方法
     *
     * @return
     */
    public static  Result businessException() {
        return new Result(ExceptionConstant.RET_CODE_BUSINESS_EXCEPTION, ExceptionConstant.RET_INFO_BUSINESS_EXCEPTION);
    }

    /**
     * 业务异常 - 构造方法 自定义返回基础信息
     *
     * @param retInfo
     * @return
     */
    public static  Result businessException(String retInfo) {
        return new Result(ExceptionConstant.RET_CODE_BUSINESS_EXCEPTION, retInfo);
    }

    /**
     * 参数无意义 - 构造方法
     *
     * @return
     */
    public static  Result paramsEmpty() {
        return new Result(ExceptionConstant.RET_CODE_PARAM_EMPTY, ExceptionConstant.RET_INFO_PARAM_EMPTY);
    }
    /**----------------------------------------------------服务/业务类方法----------------------------------------------------**/


    /**-----------------------------------------------------自定义类方法------------------------------------------------------**/
    /**
     * 自定义返回码, 返回基础信息 - 构造方法
     *
     * @param retCode
     * @param retInfo
     */
    public Result(String retCode, String retInfo) {
        this.retCode = retCode;
        this.retInfo = retInfo;
    }

    /**
     * 自定义返回码, 返回基础信息, 返回数据 - 构造方法
     *
     * @param retCode
     * @param retInfo
     * @param data
     */
    public Result(String retCode, String retInfo, T data) {
        this.retCode = retCode;
        this.retInfo = retInfo;
        this.data = data;
    }

    /**
     * 自定义返回码, 返回基础信息 - Set方法
     *
     * @param retCode
     * @param retInfo
     */
    public void setCodeInfo(String retCode, String retInfo) {
        this.retCode = retCode;
        this.retInfo = retInfo;
    }
    /**------------------------------------------------------自定义类方法----------------------------------------------------**/


}

2.异常处理

除了接口统一响应,异常处理也是一个项目的必要组成

2.1.自定义异常

为什么异常要自定义异常?
首先因为Java的程序异常Exception有一般异常和运行时异常,出现这个异常一般是程序的异常导致; 在项目中某一个接口的业务发生异常时,为了标识这类业务异常,我们通常会进行自定义异常。当在接口层(controller)出现业务异常时,我们可以使用Result.failed()来对前端响应业务异常信息,在业务层(service)出现业务异常时,我们可以throw new BusinessException(“业务异常”)抛出异常,再由全局异常处理器捕获住异常,最后给前端响应异常信息。

我这里定义了一个BusinessException

**
 * @description 业务异常
 * @author mantou
 */
public class BusinessException extends RuntimeException {

    private String info;
    private String code;

    /**
     * 异常码, 异常信息
     * @param code
     * @param info
     */
    public BusinessException(String code, String info) {
        super(info);
        this.info = info;
        this.code = code;
    }

    /**
     * 异常信息
     * @param info
     */
    public BusinessException(String info) {
        super(info);
        this.info = info;
        this.code = ExceptionConstant.RET_CODE_BUSINESS_EXCEPTION;
    }

    public BusinessException() {
        this(ExceptionConstant.RET_CODE_BUSINESS_EXCEPTION, ExceptionConstant.RET_INFO_BUSINESS_EXCEPTION);
    }


}

2.2.全局异常处理器

全局异常处理器的作用就是捕获项目中的异常,并且按照一定的规则响应给前端异常信息

使用@RestControllerAdvice注解实现全局异常处理器

/**
 * @description 全局异常处理器
 * @author mantou
 */
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {

    /**
     * 请求方法不正确
     * @param exception
     * @return
     */
    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
    public Result HttpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException exception) {
        //打印日志
        log("[HttpRequest异常,请求方法不正确]", exception);
        return Result.failed(exception.getMessage());
    }


    /**
     * SysException异常处理
     * @param e
     * @return
     */
    @ExceptionHandler(value = BusinessException.class)
    public Result sysExceptionHandler(BusinessException e){
        //打印日志
        log("[SysException业务异常]", e);
        return Result.failed(e.getMessage());
    }

    /**
     * Exception异常处理
     * @param e
     * @return
     */
    @ExceptionHandler(value = Exception.class)
    public Result defaultErrorHandler(Exception e){
        //打印日志
        log("[Exception系统异常]", e);
        return Result.failed(e.getMessage());
    }

    /**
     * 打印日志
     * @param e
     */
    private void log(String message, Exception e) {
        log.error("--------------------------------------异常开始------------------------------------------");
        log.error(e.getMessage(), e);
        log.error("--------------------------------------异常结束------------------------------------------");
    }

3.日志输出

日志作为项目十分重要的一个组成,一定要重视!!!
它的作用实在是太大了,可以用来调试程序,用来监控程序…
SpringBoot [ 2.统一响应&&异常处理&&日志输出 ]_第1张图片
可以看一下依赖,SpringBoot默认的日志是Logback,由于Logback兼容其他日志,实现了Slf4j的API,所以我这里日志使用Slf4j进行日志打印,用LogBack来配置日志的输出格式与输出格式;

3.1.引入依赖

引入Lombok依赖,Lombok提供@Slf4j注解

    
    
        org.projectlombok
        lombok
        provided
    

在类上使用@Slf4j注解即可使用log进行日志打印

在这里插入图片描述
在这里插入图片描述
日志的默认输出路径就是控制台

3.2.配置logback.xml

logback.xml主要是用来控制日志的输出等级,日志的输出路径,日志的输出格式等

日志的等级有很多,但是项目开发通常只用四种,从高到低分别是ERROR,WARN,DEBUG,INFO; 级别越高输出的日志信息越少,比如说现在输出了这四种级别的日志,当前日志等级为ERROR就只输出ERROR日志,当前日志等级为WARN就输出ERROR,WARN;DEBUG和INFO依此类推。


















	
		${CONSOLE_LOG_PATTERN}
	




	${log.path}/debug_${application.name}.log
	
		${log.path}/%d{yyyy-MM, aux}/debug_${application.name}.%d{yyyy-MM-dd}.%i.log.gz
		
		50MB
		
		30
	
	
		%date [%thread] %-5level [%logger{50}] %file:%line - %msg%n
	




	${log.path}/error_${application.name}.log
	
		${log.path}/%d{yyyy-MM}/error_${application.name}.%d{yyyy-MM-dd}.%i.log.gz
		
		50MB
		
		30
	
	
		%date [%thread] %-5level [%logger{50}] %file:%line - %msg%n
	
	
	
		ERROR
	







	
	
	
	
	
	

启动服务/停止服务,项目会生成一个log文件夹
SpringBoot [ 2.统一响应&&异常处理&&日志输出 ]_第2张图片

你可能感兴趣的:(Spring-Boot)