仅供参考——自定义结果封装类

26 篇文章 0 订阅

如题

从事开发的小伙伴想必都知道,当一个项目逐渐庞大时,特别是前后端分离的项目,我们与前端交互时,往往需要将所有数据交互的返回结果都按统一的格式封装,这样制定一个标准,看起来简单,整洁,便于理解,以便于我们跟前端小姐姐深入交流~
在这里插入图片描述
这里我记录一下自己用到的结果封装类,有需要的可以参考,拿走不谢。

1. 自定义全局响应类

package com.xxx.common.response;

import lombok.Data;

@Data
public class ResponseBean<T> {

    /**
     * 200:操作成功  -1:操作失败
     **/

    // http 状态码
    private boolean success;

    // 返回的数据
    private T data;

    public static <T> ResponseBean<T> success(T data) {
        ResponseBean<T> responseBean = new ResponseBean<>();
        responseBean.setSuccess(true);
        responseBean.setData(data);
        return responseBean;
    }


    public static <T> ResponseBean<T> error(T errorData) {
        ResponseBean<T> responseBean = new ResponseBean<>();
        responseBean.setSuccess(false);
        responseBean.setData(errorData);
        return responseBean;
    }

    public static <T> ResponseBean<T> success() {
        ResponseBean<T> responseBean = new ResponseBean<>();
        responseBean.setSuccess(true);
        return responseBean;
    }
}

代码很简单,就不做介绍了。


那么产生异常的错误码如何定义呢?看下面,首先自定义一个BaseError错误的父接口,后面所有枚举的错误类都要实现该接口:

2. 自定义error基础接口(父接口):

package com.xxx.common.error;

/**
 * 自定义的错误描述枚举类需实现该接口
 **/
public interface BaseError {

    /**
     * 获取错误码
     *
     * @return
     */
    int getErrorCode();

    /**
     * 获取错误信息
     *
     * @return
     */
    String getErrorMsg();


    /**
     * 设置错误信息
     *
     * @param message
     * @return
     */
    BaseError setErrorMsg(String message);
}

2.1 基于业务的错误码类和异常类封装:
  • BusinessCodeEnum(业务错误码枚举类封装):
package com.xxx.common.error;

import lombok.Getter;

/**
 * 业务错误码:返回结果的状态码
 * 如果想要代码更具维护性一点,可以定义不同种类的错误码,都实现 BaseCodeInterface
 **/
@Getter
public enum BusinessCodeEnum implements BaseError {
// ——注:括号内参数为(errcode: "", errorMsg: "")
    //假设,通用的异常以0000开头  
    PARAMETER_ERROR(00001, "参数不合法"),
    // 数据操作错误自定义
    BODY_NOT_MATCH(400, "请求的数据格式不符!"),
    SIGNATURE_NOT_MATCH(401, "请求的数字签名不匹配!"),
    NOT_FOUND(404, "未找到该资源!"),
    INTERNAL_SERVER_ERROR(500, "服务器内部错误!"),
    SERVER_BUSY(503, "服务器正忙,请稍后再试!"),
    //用户相关自定义:10000**
    USER_ACCOUNT_NOT_FOUND(10001, "账号不存在!"),
    DoNotAllowToDisableTheCurrentUser(10002, "不允许禁用当前用户"),
    //业务异常自定义
	// ...
	
    /**
     * 错误码
     */
    private int errorCode;

    /**
     * 错误描述
     */
    private String errorMsg;

    BusinessCodeEnum(int errorCode, String errorMsg) {
        this.errorCode = errorCode;
        this.errorMsg = errorMsg;
    }

    @Override
    public int getErrorCode() {
        return this.errorCode;
    }

    @Override
    public String getErrorMsg() {
        return this.errorMsg;
    }

    @Override
    public BaseError setErrorMsg(String errorMsg) {
        this.errorMsg = errorMsg;
        return this;
    }

}

  • BusinessException(业务异常类封装):
package com.xxx.common.error;

import lombok.Data;

/**
 * 业务异常
 *
 * @Author channy
 * @Date 2020/3/1 14:47
 * @Version 1.0
 **/
@Data
public class BusinessException extends Exception implements BaseError {

    //所有实现了BaseError的ErrorEnum.
    private BaseError baseError;

    //直接构造错误消息的构造异常
    public BusinessException(BaseError baseError) {
        super(baseError.getErrorMsg());
        this.baseError = baseError;
    }

    //自定义错误消息的构造异常
    public BusinessException(BaseError baseError, String customErrorMessage) {
        super();
        this.baseError = baseError;
        this.baseError.setErrorMsg(customErrorMessage);
    }

    @Override
    public int getErrorCode() {
        return this.baseError.getErrorCode();
    }

    @Override
    public String getErrorMsg() {
        return this.baseError.getErrorMsg();
    }

    @Override
    public BaseError setErrorMsg(String message) {
        this.baseError.setErrorMsg(message);
        return this;
    }
}

2.2 基于系统的错误码类和异常封装:
  • SystemCodeEnum(系统错误码类自定义):
package com.xxx.common.error;


public enum SystemCodeEnum implements BaseError {
    PARAMETER_ERROR(50000, "参数不合法"),
    TOKEN_ERROR(50001, "用户未认证");

    /**
     * 错误码
     */
    private int errorCode;

    /**
     * 错误描述
     */
    private String errorMsg;

    SystemCodeEnum(int errorCode, String errorMsg) {
        this.errorCode = errorCode;
        this.errorMsg = errorMsg;
    }

    @Override
    public int getErrorCode() {
        return this.errorCode;
    }

    @Override
    public String getErrorMsg() {
        return this.errorMsg;
    }

    @Override
    public BaseError setErrorMsg(String errorMsg) {
        this.errorMsg = errorMsg;
        return this;
    }
}

  • SystemException(系统异常类封装):
package com.xxx.common.error;

// 继承异常基类,实现自定义错误父接口
public class SystemException extends Exception implements BaseError {
    //所有实现了BaseError的ErrorEnum.
    private BaseError baseError;

    //直接构造错误消息的构造异常
    public SystemException(BaseError baseError) {
        super(baseError.getErrorMsg());
        this.baseError = baseError;
    }

    //自定义错误消息的构造异常
    public SystemException(BaseError baseError, String customErrorMessage) {
        super(customErrorMessage);
        this.baseError = baseError;
        this.baseError.setErrorMsg(customErrorMessage);
    }

    @Override
    public int getErrorCode() {
        return this.baseError.getErrorCode();
    }

    @Override
    public String getErrorMsg() {
        return this.baseError.getErrorMsg();
    }

    @Override
    public BaseError setErrorMsg(String message) {
        this.baseError.setErrorMsg(message);
        return this;
    }
}

3. 自定义MyMebMvcConfigurer配置类实现WebMvcConfigurer接口

package com.xxx.config;

import com.xxx.common.error.BusinessException;
import com.xxx.common.error.SystemException;
import com.xxx.common.response.ResponseBean;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.shiro.authz.UnauthorizedException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.NoHandlerFoundException;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;

/**
 * @Author cyl
 * @Date 2020/12/13 13:48
 * @Version 1.0
 **/
@Configuration
public class MyMebMvcConfigurer implements WebMvcConfigurer {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Override
    public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {
        resolvers.add((httpServletRequest, httpServletResponse, o, e) -> {
            ResponseBean result;
            HashMap<String, Object> errorData = new HashMap<>();
            logger.info("请求错误,url:{}", httpServletRequest.getRequestURL());
            if (e instanceof BusinessException) {
                BusinessException businessException = (BusinessException) e;
                logger.info("业务模块-错误码:{},错误信息:{}", businessException.getErrorCode(), businessException.getErrorMsg());
                errorData.put("errorCode", businessException.getErrorCode());
                errorData.put("errorMsg", businessException.getErrorMsg());
            } else if (e instanceof SystemException) {
                SystemException systemException = (SystemException) e;
                logger.info("系统模块-错误码:{},错误信息:{}", systemException.getErrorCode(), systemException.getErrorMsg());
                errorData.put("errorCode", systemException.getErrorCode());
                errorData.put("errorMsg", systemException.getErrorMsg());
            } else if (e instanceof UnauthorizedException) {
                UnauthorizedException unauthorizedException = (UnauthorizedException) e;
                logger.info("系统模块-错误码:{},错误信息:{}", HttpStatus.UNAUTHORIZED.value(), unauthorizedException.getMessage());
                errorData.put("errorCode", HttpStatus.UNAUTHORIZED.value());
                errorData.put("errorMsg", "服务器向你抛了一个异常,并表示(操作无权限)");
            } else if (e instanceof HttpRequestMethodNotSupportedException) {
                logger.info("系统模块-错误码:{},错误信息:{}", HttpStatus.BAD_REQUEST.value(), e.getMessage());
                errorData.put("errorCode", HttpStatus.BAD_REQUEST.value());
                errorData.put("errorMsg", "不支持该http请求方式");
            } else if (e instanceof NoHandlerFoundException) {
                logger.error("接口不存在-错误码:{},错误信息:{}", HttpStatus.NOT_FOUND.value(), e.getMessage());
                errorData.put("errorCode", HttpStatus.NOT_FOUND.value());
                errorData.put("errorMsg", "API接口:[" + httpServletRequest.getServletPath() + "]不存在");
            } else {
                logger.error("系统异常-错误码:{},错误信息:{}", HttpStatus.INTERNAL_SERVER_ERROR.value(), e.getMessage(), e);
                errorData.put("errorCode", HttpStatus.INTERNAL_SERVER_ERROR.value());
                errorData.put("errorMsg", "服务器异常,请联系管理员");
            }
            result = ResponseBean.error(errorData);
            responseResult(httpServletResponse, result);
            return new ModelAndView();
        });
    }


    /**
     * <h2>响应结果</h2>
     *
     * @param response
     * @param result
     */
    private void responseResult(HttpServletResponse response, ResponseBean result) {
        response.setCharacterEncoding("UTF-8");
        response.setHeader("Content-type", "application/json;charset=UTF-8");
        response.setStatus(HttpStatus.OK.value());
        try {
            ObjectMapper objectMapper = new ObjectMapper();
            response.getWriter().write(objectMapper.writeValueAsString(result));
        } catch (IOException ex) {
            logger.error(ex.getMessage());
        }
    }


}

最后举例子调用以上封装类
  1. controller层(调用的是以全局结果封装类作为返回的格式):
@GetMapping("/detail/{id}")
public ResponseBean detail(@PathVariable String id) throws BusinessException {
    Xxx detail = xxxService.detail(id);
    return ResponseBean.success(detail);
}

// 删除
@GetMapping("/delete/{id}")
public ResponseBean delete(@PathVariable String id) throws BusinessException {
    xxxService.delete(id);
    return ResponseBean.success();
}
  1. service层(重点看对异常的抛出怎么调用以上自定义的异常类):
// 业务级
@Override
public Xxx detail(String id) throws BusinessException {
    XxxVO xxxVO = new XxxVO();
    logger.info("detail id:" + id);

    Xxx xxx = xxxMapper.selectByPrimaryKey(id);
    if(xxx==null){
        throw new BusinessException(BusinessCodeEnum.PARAMETER_ERROR,"订单不存在");
    }
    BeanUtils.copyProperties(xxx,xxxVO);
    return xxxVO; // 返回订单信息
}
// 系统级
/**
 * 删除用户
 * @param id 用户ID
 */
@Transactional
@Override
public void deleteById(Long id) throws SystemException {
    User user = userMapper.selectByPrimaryKey(id);
    ActiveUser activeUser = (ActiveUser) SecurityUtils.getSubject().getPrincipal();

    if(user==null){
        throw new SystemException(SystemCodeEnum.PARAMETER_ERROR,"要删除的用户不存在");
    }

    if(user.getId().equals(activeUser.getUser().getId())){
        throw new SystemException(SystemCodeEnum.PARAMETER_ERROR,"不能删除当前登入用户");
    }

    userMapper.deleteByPrimaryKey(id);
    //删除对应[用户-角色]记录
    Example o = new Example(UserRole.class);
    o.createCriteria().andEqualTo("userId",id);
    userRoleMapper.deleteByExample(o);
}
//   ...

以JSON格式显示返回的结果集是这样的形式:

{
“success”: true,
“data”: “xxxxxxx”
}

{
“success”: false,
“data”: {
“errorCode”: 1,
“errorMsg”: “xxxxxxxxx”
}
}

以上就是这些。


共勉~

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值