首页 > 其他分享 >全局异常拦截和返回值封装

全局异常拦截和返回值封装

时间:2023-04-05 17:33:47浏览次数:37  
标签:return 封装 ErrorCode Result import 返回值 拦截 public masy

全局异常拦截和返回值封装共分为五个类,分别是错误码枚举类、返回值封装类、自定义业务异常类、全局拦截类、全局返回值处理类。

错误码枚举类

用来定义返回值的错误码。

package com.masy.global.exception;

/**
 * @ClassName ErrorCode
 * @Description 错误码枚举
 * @Author masy
 * @Date 2023/4/322:18
 **/
public enum ErrorCode {


    /*成功*/
    SUCCESS(0, "成功"),
    FAIL(500, "失败"),

    SYSTEM_ERROR(10000, "系统异常"),

    PARAM_ERROR(10100, "参数异常"),

    USER_AUTH_FAIL(20001, "用户鉴权失败"),
    ;
    private Integer code;
    private String msg;

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

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public static String getMsgByCode(Integer code) {
        for (ErrorCode ec : values()) {
            if (ec.getCode().equals(code)) {
                return ec.getMsg();
            }
        }
        return null;
    }
}

返回值封装类

用来将返回值统一封装。

package com.masy.global.exception;

import java.io.Serializable;
import java.time.LocalDateTime;

/**
 * @ClassName Result
 * @Description 返回值封装
 * @Author masy
 * @Date 2023/4/322:18
 **/
public class Result<T> implements Serializable {
    private static final long serialVersionUID = 1581329103599839148L;
    private boolean success;

    private Integer code;

    private String msg;

    private T data;

    private LocalDateTime timestamp = LocalDateTime.now();

    public Result() {
        this.success = true;
        this.code = ErrorCode.SUCCESS.getCode();
        this.msg = ErrorCode.SUCCESS.getMsg();
    }

    public Result(boolean success) {
        this.success = success;
        this.code = success ? ErrorCode.SUCCESS.getCode() : ErrorCode.FAIL.getCode();
        this.msg = success ? ErrorCode.SUCCESS.getMsg() : ErrorCode.FAIL.getMsg();
        this.timestamp = LocalDateTime.now();
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public void setSuccess(boolean success) {
        this.success = success;
    }

    public void setData(T data) {
        this.data = data;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public static <T> Result<T> success() {
        Result<T> res = new Result<>();
        res.setSuccess(true);
        res.setCode(ErrorCode.SUCCESS.getCode());
        res.setMsg(ErrorCode.SUCCESS.getMsg());
        return res;
    }

    public static <T> Result<T> success(T data) {
        Result<T> res = new Result<>();
        res.setSuccess(true);
        res.setCode(ErrorCode.SUCCESS.getCode());
        res.setMsg(ErrorCode.SUCCESS.getMsg());
        res.setData(data);
        return res;
    }

    public static <T> Result<T> fail(ErrorCode errorResponse) {
        Result<T> res = new Result<>();
        res.setSuccess(false);
        res.setCode(errorResponse.getCode());
        res.setMsg(errorResponse.getMsg());
        return res;
    }

    public static <T> Result<T> fail(ErrorCode errorResponse, T data) {
        Result<T> res = new Result<>();
        res.setSuccess(false);
        res.setCode(errorResponse.getCode());
        res.setMsg(errorResponse.getMsg());
        res.setData(data);
        return res;
    }

    public boolean isSuccess() {
        return success;
    }

    public Integer getCode() {
        return code;
    }

    public String getMsg() {
        return msg;
    }

    public T getData() {
        return data;
    }

    public LocalDateTime getTimestamp() {
        return timestamp;
    }

    public void setTimestamp(LocalDateTime timestamp) {
        this.timestamp = timestamp;
    }
}

自定义业务异常类

用来抛出业务异常。

package com.masy.global.exception;

/**
 * @ClassName BusinessException
 * @Description 业务异常
 * @Author masy
 * @Date 2023/4/322:18
 **/
public class BusinessException extends RuntimeException {

    private ErrorCode errorCode;

    public BusinessException() {
        this.errorCode = ErrorCode.FAIL;
    }

    public BusinessException(ErrorCode errorCode) {
        this.errorCode = errorCode;
    }

    public ErrorCode getErrorCode() {
        return errorCode;
    }
}

全局异常拦截类

用来拦截抛出的异常,做处理。

package com.masy.global.exception;

import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;


/**
 * @ClassName GlobalExceptionHandler
 * @Description 全局异常拦截
 * @Author masy
 * @Date 2023/4/322:18
 **/
@RestControllerAdvice
public class GlobalExceptionHandler {

    /**
     * 空指针异常
     *
     * @param e 异常
     * @return com.masy.global.exception.Result<?>
     * @author masy
     * @date 2023/4/3 22:46
     */
    @ExceptionHandler(value = NullPointerException.class)
    public Result<?> handler(NullPointerException e) {
        return Result.fail(ErrorCode.SYSTEM_ERROR);
    }

    /**
     * 参数异常
     *
     * @param e 异常
     * @return com.masy.global.exception.Result<?>
     * @author masy
     * @date 2023/4/3 22:46
     */
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public Result<?> handler(MethodArgumentNotValidException e) {
        return Result.fail(ErrorCode.PARAM_ERROR);
    }

    /**
     * 捕获业务异常
     *
     * @param e 异常
     * @return com.masy.global.exception.Result<?>
     * @author masy
     * @date 2023/4/3 22:46
     */
    @ExceptionHandler(value = BusinessException.class)
    public Result<?> handler(BusinessException e) {
        return Result.fail(e.getErrorCode());
    }

    /**
     * 捕获其他异常
     *
     * @param e 异常
     * @return com.masy.global.exception.Result<?>
     * @author masy
     * @date 2023/4/3 22:46
     */
    @ExceptionHandler(value = Exception.class)
    public Result<?> handler(Exception e) {
        return Result.fail(ErrorCode.FAIL);
    }
}

全局返回值处理类

用来将返回值统一封装,不用在每个接口中封装。

package com.masy.global.config;

import com.masy.global.exception.Result;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

/**
 * @ClassName ResponseResultAdvice
 * @Description 返回数据封装
 * @Author masy
 * @Date 2023/4/323:49
 **/
@RestControllerAdvice
public class ResponseResultAdvice implements ResponseBodyAdvice<Object> {

    /**
     * 跳过判断是否有返回值,直接调用beforeBodyWrite
     *
     * @param returnType    返回值类型
     * @param converterType
     * @return boolean
     * @author masy
     * @date 2023/4/3 23:50
     */
    @Override
    public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
        return true;
    }

    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
        if (body instanceof Result) {
            return body;
        } else {
            return Result.success(body);
        }
    }
}

使用

package com.masy.global.controller;

import com.alibaba.fastjson.JSON;
import com.masy.global.exception.BusinessException;
import com.masy.global.exception.ErrorCode;
import com.masy.global.exception.Result;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

/**
 * @ClassName Test
 * @Description TODO
 * @Author masy
 * @Date 2023/4/322:54
 **/
@RestController
@RequestMapping("test")
public class Test {

    @GetMapping()
    public Map<String,String> test() {
        Map<String,String> map = new HashMap<>();
        map.put("a","1");
        return map;
    }

    @GetMapping("success")
    public Result<Map<String,String>> test1() {
        Map<String,String> map = new HashMap<>();
        map.put("a","1");
        return Result.success(map);
    }


    @GetMapping("fail")
    public Result<String> fail(){
        throw new BusinessException(ErrorCode.PARAM_ERROR);
    }
}

返回效果

标签:return,封装,ErrorCode,Result,import,返回值,拦截,public,masy
From: https://www.cnblogs.com/masy-lucifer/p/17289900.html

相关文章

  • Spring 源码解析 - xml解析封装BeanDefinition(1)
    -  XML解析封装BeanDefinition  断点在 DefaultListableBeanFacy,registerBeanDefinition()二 如果给属性赋值 三 各种postprocessor       ##2、Spring套路点-1、AbstractBeanDefinition看看何时给容器中注入了什么组件-2、BeanFactory让......
  • C++库封装JNI接口——实现java调用c++
    1.JNI原理概述通常为了更加灵活高效地实现计算逻辑,我们一般使用C/C++实现,编译为动态库,并为其设置C接口和C++接口。用C++实现的一个库其实是一个或多个类的简单编译链接产物。然后暴露其实现类构造方法和纯虚接口类。这样就可以通过多态调用到库内部的实现类及其成员方法。进一步......
  • Android 原生 SQLite 数据库的一次封装实践
    作者:LiBingyan本文主要讲述原生SQLite数据库的一次ORM封装实践,给使用原生数据库操作的业务场景(如:本身是一个SDK)带来一些启示和参考意义,以及跟随框架的实现思路对数据库操作、APT、泛型等概念更深一层的理解。实现思路:通过动态代理获取请求接口参数进行SQL拼凑,并以接口返回值(泛型)......
  • 使用logging封装日志
    自己封装的logging,封装日志的几个组件Logger记录器暴露了应用程序代码直接使用的接口。Handler处理器将日志记录(由记录器创建)发送到适当的目标。Filter过滤器提供了更细粒度的功能,用于确定要输出的日志记录。Formatter格式器指定最终输出中日志记录的样式。日志等级......
  • NestJS 拦截器 和 RxJs
    为什么要介绍RxJs因为在Nestjs已经内置了RxJs无需安装并且Nestjs也会有一些基于Rxjs提供的APIRxJs是什么RxJs使用的是观察者模式,用来编写异步队列和事件处理。Observable可观察的物件Subscription监听ObservableOperators纯函数可以处理管道的数据如mapfil......
  • 微店商品详情接口,微店商品数据接口,微店商品优惠券接口封装代码教程
    业务场景:作为全球最大的B2C电子商务平台之一,微店平台提供了丰富的商品资源,吸引了大量的全球买家和卖家。为了方便开发者接入微店平台,微店平台提供了丰富的API接口,其中商品详情接口是非常重要的一部分。大家有探讨稳定采集微店整站实时商品详情数据接口,通过该接口开发者可以更......
  • 微信小程序自定义封装组件-showModal
    封装一个组件这里由于最近使用微信小程序居多,所以着重写的是小程序的,但是万变不离其宗,组件实现思路其实都差不多的微信小程序开发中官方自带的wx.showModal,这个弹窗API有时候并不能满足我们的弹窗效果,所以往往需要自定义modal组件。下面我们进行一个自定义modal弹窗组件的开发,并......
  • 拦截器
    1、拦截器的基本概念拦截器是SpringBoot的一个强大的控件,它可以使得程序在进入控制器之前做一些操作,或在控制器方法完成后、甚至是在视图渲染时进行操作,常用于对控制器方法进行预处理和后处理,如进行登录、权限验证问题的处理。拦截器和过滤器的概念相似。过滤器是Ser......
  • JS封装思想
      js:   ......
  • Qt学习笔记9——P30-33. 自定义控件封装,鼠标事件,定时器
    P30.自定义控件封装P31.Qt中的鼠标事件P32.定时器1P33.定时器2P30.自定义控件封装(创建了新项目) 添加新的界面和类:右键项目的文件夹(顶层的文件)->Qt——Qt设计师界面类->“选择界面模板”选"Widget"->在"Classname"中取个类名(此案例中改成了SmallWidget)->别的没......