zoukankan      html  css  js  c++  java
  • rest-spring-boot-starter

    rest-spring-boot-starter

    基于spring boot,统一业务异常处理,统一返回格式包装

    依赖

    <dependency>
        <groupId>tk.fishfish</groupId>
        <artifactId>rest-spring-boot-starter</artifactId>
        <version>1.0.0.RELEASE</version>
    </dependency>
    

    统一业务异常处理

    @RestController
    public class DemoController {
    
        @GetMapping("/list")
        public List<String> list() {
            throw new BizException(10001, "xxx错误");
        }
    
    }
    

    业务异常统一处理:

    {
        "code": 10001,
        "msg": "xxx错误",
        "data": null
    }
    

    统一返回格式包装

    @RestController
    public class DemoController {
    
        @GetMapping("/list")
        public List<String> list() {
            return Arrays.asList("1", "2");
        }
    
    }
    

    返回值进行包装,忽略org.springframework.http.ResponseEntity值类型。

    {
        "code": 0,
        "msg": null,
        "data": [
            "1",
            "2"
        ]
    }
    

    原理

    定义统一格式:

    {
        "code": 返回码,
        "msg": 描述,
        "data": 数据
    }
    

    约定:

    • code:-1,代表全局异常处理的错误;0,成功;正数,业务错误码
    • msg:一段描述
    • data:真正的数据

    异常处理

    使用org.springframework.web.bind.annotation.RestControllerAdvice,全局捕获异常。

    package tk.fishfish.rest;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.core.annotation.Order;
    import org.springframework.web.bind.annotation.ExceptionHandler;
    import org.springframework.web.bind.annotation.RestControllerAdvice;
    
    /**
     * 全局异常处理,优先级为100
     *
     * @author 奔波儿灞
     * @since 1.0
     */
    @Order(100)
    @RestControllerAdvice
    public class GlobalExceptionHandler {
    
        private static final Logger LOG = LoggerFactory.getLogger(GlobalExceptionHandler.class);
    
        @ExceptionHandler(BizException.class)
        public ApiResult<Void> handleBizException(BizException e) {
            LOG.warn("handle bizException", e);
            Integer code = e.getCode();
            String msg = e.getMessage();
            return ApiResult.fail(code, msg);
        }
    
        @ExceptionHandler(Exception.class)
        public ApiResult<Void> handleException(Exception e) {
            LOG.warn("handle exception", e);
            String msg = e.getMessage();
            return ApiResult.fail(-1, msg);
        }
    
    }
    

    统一返回

    通过实现org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice,在写入响应前统一包装返回内容。

    package tk.fishfish.rest;
    
    import org.springframework.core.MethodParameter;
    import org.springframework.http.MediaType;
    import org.springframework.http.ResponseEntity;
    import org.springframework.http.converter.HttpMessageConverter;
    import org.springframework.http.server.ServerHttpRequest;
    import org.springframework.http.server.ServerHttpResponse;
    import org.springframework.web.bind.annotation.RestController;
    import org.springframework.web.bind.annotation.RestControllerAdvice;
    import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
    
    /**
     * 返回body处理,包装成ApiResult。如果是ResponseEntity,则不包装
     *
     * @author 奔波儿灞
     * @see tk.fishfish.rest.ApiResult
     * @since 1.0
     */
    @RestControllerAdvice(annotations = RestController.class)
    public class ApiResultResponseBodyAdvice implements ResponseBodyAdvice<Object> {
    
        @Override
        public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> aClass) {
            return true;
        }
    
        @Override
        public Object beforeBodyWrite(Object body, MethodParameter methodParameter,
                                      MediaType mediaType, Class<? extends HttpMessageConverter<?>> aClass,
                                      ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
            // ResponseEntity,则不包装
            if (body instanceof ResponseEntity) {
                return body;
            }
            // ApiResult,也不包装
            if (body instanceof ApiResult) {
                return body;
            }
            // todo 基本数据类型是否特殊处理
            // 其余统一包装成ApiResult
            return ApiResult.ok(body);
        }
    
    }
    

    项目地址

  • 相关阅读:
    免费的mysql客户端管理工具
    vue配置反向代理
    composer下载地址
    mysql多个字段模糊查询是否包含某个词
    Laravel 7 中文文档
    datatable显示文字改为中文
    MongoDB
    node 与 Ajax 的等待响应
    关于 <!DOCTYPE html> 对移动端和PC端的影响
    Vue中 scoped属性
  • 原文地址:https://www.cnblogs.com/bener/p/11801660.html
Copyright © 2011-2022 走看看