打造一款适合自己的快速开发框架-通用类封装之统一结果返回、统一异常处理

2,174 阅读4分钟

前言

通用类封装的主要目的是保持代码风格的统一。常用的封装比如:接口统一结果返回、错误码定义、枚举类、Mapper基类、实体类基类、RequestHolder、拦截器、过滤器等。本文主要讲解如何封装统一结果返回和统一异常处理。

统一结果返回

统一结果返回其实就是定义接口的返回规范,这里会涉及到四种类型的返回结果,有单条记录返回、有多条记录返回、有分页数据返回、无数据对象。不同的数据,外层的返回结果会保持一致。

返回样例

  • 单条记录
{
	"code": 0,
	"data": {
		"id": 1,
		"userName": "admin",
		"realName": "mldong",
		"sex": 1
	},
	"msg": "操作成功"
}
  • 多条记录
{
	"code": 0,
	"data": [{
		"id": 1,
		"userName": "admin",
		"realName": "mldong",
		"sex": 1
	},{
		"id": 2,
		"userName": "admin222",
		"realName": "mldong222",
		"sex": 1
	}],
	"msg": "操作成功"
}
  • 分页记录
{
	"code": 0,
	"data": {
        "recordCount": 10,
        "pageNum": 1,
        "pageSize": 2,
        "rows":[{
            "id": 1,
            "userName": "admin",
            "realName": "mldong",
            "sex": 1
        },{
            "id": 2,
            "userName": "admin222",
            "realName": "mldong222",
            "sex": 1
        }]
    },
	"msg": "操作成功"
}
  • 无数据对象

    • 操作成功
    {
    	"code": 0,
    	"msg": "操作成功"
    }
    
    • 操作失败
    {
    	"code": 99999999,
    	"msg": "操作失败"
    }
    
    

返回描述

属性 类型 说明
code int 返回状态码(0->成功,非0->对应的错误码)
msg String 消息描述
data Object 数据对象
data.recordCount long 总记录数
data.pageNum int 当前页
data.pageSize int 每页大小
data.totalPage int 总页数
data.rows List 数据集

通用类-统一返回

mldong-common/com/mldong/common/base/CommonResult.java

package com.mldong.common.base;

import java.io.Serializable;

/**
 * 
 * @author mldong
 *
 */
public class CommonResult<T> implements Serializable{

	/**
	 * 
	 */
	private static final long serialVersionUID = -7504120764828454657L;
	private int code;
    private String msg;
    private T data;
	/**
	 * 
	 */
    
	@SuppressWarnings("unused")
	private CommonResult () {
		
	}
	public CommonResult(Type type,String msg) {
		this.code = type.value;
		this.msg = msg;
	}
	public CommonResult(Type type,String msg,T data) {
		this.code = type.value;
		this.msg = msg;
		this.data = data;
	}
	public enum Type {
		SUCCESS(0),
		FAIL(99999999)
		;
		private final int value;
		Type(int value) {
			this.value = value;
		}
	}
	/**
	 * 返回成功
	 * @param msg
	 * @param data
	 * @return
	 */
	public static <T> CommonResult<T> success(String msg,T data) {
		return new CommonResult<T>(Type.SUCCESS, msg, data);
	}
	/**
	 * 返回成功
	 * @param data
	 * @return
	 */
	public static <T> CommonResult<T> success(T data) {
		return success("操作成功",data);
	}
	/**
	 * 返回成功
	 * @return
	 */
	public static <T> CommonResult<T> success() {
		return success("操作成功", null);
	}
	/**
	 * 返回失败
	 * @param msg
	 * @param data
	 * @return
	 */
	public static <T> CommonResult<T> fail(String msg,T data) {
		return new CommonResult<T>(Type.FAIL, msg, data);
	}
	/**
	 * 返回失败
	 * @param data
	 * @return
	 */
	public static <T> CommonResult<T> fail(T data) {
		return fail("操作失败",data);
	}
	/**
	 * 返回失败
	 * @return
	 */
	public static <T> CommonResult<T> fail() {
		return fail("操作失败", null);
	}
	// 省略 get set
}

通用类-分页数据实体

分页数据实体的封装主要是将持久层框架分页实体转成自己框架的分页实体。这样保证了对外的返回结果符合我们自己的返回规范。

mldong-common/com/mldong/common/base/CommonPage.java

package com.mldong.common.base;

import java.io.Serializable;
import java.util.List;

import com.github.pagehelper.Page;
/**
 * 分页数据实体
 * @author mldong
 *
 * @param <T>
 */
public class CommonPage<T> implements Serializable{

	/**
	 * 
	 */
	private static final long serialVersionUID = -8297224397945376979L;
	/**
	 * 每几页
	 */
	private int pageNum;
	/**
	 * 每页大小
	 */
    private int pageSize;
    /**
     * 总数
     */
    private long recordCount;
    /**
     * 总页数
     */
    private int totalPage;
    /**
     * 数据集合
     */
    private List<T> rows;
    /**
     * 将mybatis分页插件实体转成通用分页数据实体
     * @param page
     * @return
     */
    public static <T> CommonPage<T> toPage(Page<T> page) {
        CommonPage<T> result = new CommonPage<T>();
        result.setTotalPage(page.getPages());
        result.setPageNum(page.getPageNum());
        result.setPageSize(page.getPageSize());
        result.setRecordCount(page.getTotal());
        result.setRows(page.getResult());
        return result;
    }
	// 省略 get set    
}

统一异常处理

统一异常处理,主要目的也是为了结果返回的统一,当程序异常的情况下,可能就不会返回正常的结果,这时候就需要定义一个统一的全局异常来捕获这些信息,并作为一种结果返回。这里主要使用 @ControllerAdvice 来实现,这里不做解释,如需要了解,再自行百度。

全局异常处理类

mldong-common/com/mldong/common/exception/DefaultExceptionHandler.java

package com.mldong.common.web;

import java.util.stream.Collectors;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import com.mldong.common.base.CommonResult;
/**
  * 全局异常处理类
  * @author mldong
  *
*/
@ControllerAdvice
public class DefaultExceptionHandler {
 
    private static Logger log = LoggerFactory.getLogger(DefaultExceptionHandler.class);  
    
    /**
     * 控制层参数校验异常
     * @param e
     * @return
     */
    @ExceptionHandler(MethodArgumentNotValidException.class) 
    @ResponseBody
    public CommonResult<?> methodArgumentNotValidExceptionHandler(MethodArgumentNotValidException e){
    	log.error("参数校验异常:{}", e.getMessage());
    	;
    	String errorMsg = String.join(",", e.getBindingResult().getAllErrors().stream().map(item->{
    		return item.getDefaultMessage();
    	}).collect(Collectors.toList()));
    	return CommonResult.fail(errorMsg, e.getBindingResult());
    }
    /**
     * 其他异常
     * @param e
     * @return
     */
    @ExceptionHandler(Exception.class) 
    @ResponseBody
    public CommonResult<?> excetionHandler(Exception e){
    	log.error("未捕获异常:", e);
    	return CommonResult.fail(e.getMessage(), null);
    }
}

目录结构

只罗列需要新增或修改的文件

├── mldong-admin  管理端接口
    ├── src/main/java
      └──com.mldong.modules.sys
        └── controller 控制层
        	└── SysUserController.java
        └── service 服务层
        	├── impl
        		└── SysUserServiceImpl
        	└── SysUserService.java
├── mldong-common  工具类及通用代码
	├── src/main/java
      ├──com.mldong.common.base
      	├── CommonResult.java
      	└── CommonPage.java
      └──com.mldong.common.exception
     	└── DefaultExceptionHandler.java
	└── pom.xml
├── mldong-generator  代码生成器
└── mldong-mapper 持久层

小结

这次写的文章不够全,下一篇会结合部分业务来说明。

项目源码地址

  • 后端

gitee.com/mldong/mldo…

  • 前端

gitee.com/mldong/mldo…

相关文章

打造一款适合自己的快速开发框架-先导篇

打造一款适合自己的快速开发框架-后端脚手架搭建

打造一款适合自己的快速开发框架-集成mapper

打造一款适合自己的快速开发框架-集成swaggerui和knife4j