中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Spring?Boot統一接口返回及全局異常處理的方法

發布時間:2022-04-21 10:19:47 來源:億速云 閱讀:230 作者:iii 欄目:開發技術

這篇文章主要講解了“Spring Boot統一接口返回及全局異常處理的方法”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“Spring Boot統一接口返回及全局異常處理的方法”吧!

    1、解決方案

    Spring?Boot統一接口返回及全局異常處理的方法

    定義公共模塊,實現統一接口定義規范和異常處理,其他的系統進行依賴和擴展即可。

    2、具體實現

    2.1 定義狀態碼統一接口

    public interface BaseResultCode
    {
        /**
         * 狀態碼
         * @return
         */
        int getCode();
        /**
         * 提示信息
         * @return
         */
        String getMsg();
    }

    2.2 公共模塊狀態碼枚舉類

    public enum ResultCode implements BaseResultCode
    {
        OK(200, "成功"),
        ERROR(300,"系統異常"), 
        NEED_AUTH(301, "非法請求,請重新登錄"), 
        PARAMTER_ERROR(302, "參數錯誤");
        //省略其他定義錯誤碼
        private int code;
        private String msg;
        private ResultCode(int code, String msg)
        {
            this.code = code;
            this.msg = msg;
        }
        public static ResultCode getValue(int code)
        {
            for (ResultCode errorCode : values())
            {
                if (errorCode.getCode() == code)
                {
                    return errorCode;
                }
            }
            return null;
        }
       //省略Get、Set方法
     }

    2.3 定義全局自定義異常

    public class SysException extends RuntimeException
    {
        private static final long serialVersionUID = 5225171867523879342L;
        private int code;
        private String msg;
        private Object[] params;
        private BaseResultCode errorCode;
        public SysException()
        {
            super();
        }
        public SysException(String message)
        {
            super(message);
        }
        public SysException(Throwable cause)
        {
            super(cause);
        }
        public SysException(int code ,String message)
        {
            this.code = code;
            this.msg = message;
        }
        public SysException(int code ,String message,  Object[] params)
        {
            this(code, message);
            this.params= params;
        }
        public SysException(String message, Throwable cause)
        {
            super(message, cause);
        }
        public SysException(BaseResultCode errorCode)
        {
            this.errorCode = errorCode;
        }
        public SysException(String message, Object[] params)
        {
            super(message);
            this.params = params;
        }
        public SysException(BaseResultCode errorCode, String message, Object[] params)
        {
            this(message, params);
            this.errorCode = errorCode;
        }
        
        /**
         * Construct by default
         * 
         * @param message
         *            message
         * @param parameters
         *            parameters
         * @param cause
         *            cause
         */
        public SysException(String message, Object[] params, Throwable cause)
        {
            super(message, cause);
            this.params = params;
        }
    
        public int getCode()
        {
            return code;
        }
        public void setCode(int code)
        {
            this.code = code;
        }
        public String getMsg()
        {
            return msg;
        }
        public void setMsg(String msg)
        {
            this.msg = msg;
        }
        /**
         * @return the params
         */
        public Object[] getParams()
        {
            return params;
        }
        /**
         * @param params
         *            the params to set
         */
        public void setParams(Object[] params)
        {
            this.params = params;
        }
        public BaseResultCode getErrorCode()
        {
            return errorCode;
        }
        public void setErrorCode(BaseResultCode errorCode)
        {
            this.errorCode = errorCode;
        }
        
    }

    2.4 定義統一接口格式輸出類

    public class Result implements Serializable
    {
        private static final long serialVersionUID = -1773941471021475043L;
        private Object data;
        private int code;
        private String msg;
        public Result()
        {
        }
        public Result(int code, Object data, String msg)
        {
            this.code = code;
            this.data = data;
            this.msg = msg;
        }
        public Result(int code, String desc)
        {
            this(code, null, desc);
        }
        public Result(BaseResultCode errorCode)
        {
            this(errorCode.getCode(), null, errorCode.getMsg());
        }
        public static Result success()
        {
            return success(null);
        }
        public static Result success(Object data)
        {
            Result result = new Result();
            result.setData(data);
            result.setCode(ResultCode.OK.getCode());
            return result;
        }
        public static Result error(String msg)
        {
            Result result = new Result();
            result.setCode(ResultCode.ERROR.getCode());
            result.setMsg(msg);
            return result;
        }
        public static Result error(BaseResultCode baseCode)
        {
            Result result = new Result();
            result.setCode(baseCode.getCode());
            result.setMsg(baseCode.getMsg());
            return result;
        }
    }

    個人建議:統一接口輸出類不要定義為泛型類型

    2.5 定義統一接口格式輸出類

    @RestControllerAdvice
    public class SysExceptionHandler
    {
        public static Log logger = LogManager.getLogger(SysExceptionHandler.class);
        @ExceptionHandler(Exception.class)
        public Result handleException(HttpServletRequest request,
                Exception ex)
        {
            logger.error("Handle Exception Request Url:{},Exception:{}",request.getRequestURL(),ex);
            Result result = new Result();
            //系統異常
            if (ex instanceof SysException)
            {
                SysException se = (SysException) ex;
                BaseResultCode resultCode =se.getErrorCode();
                if(resultCode==null)
                {
                    result = Result.error(se.getMessage());
                }
                else
                {
                   result = new Result(resultCode.getCode(),
                                           StringUtil.isNotEmpty(se.getMessage())?se.getMessage():resultCode.getMsg());
                }
            }
            //參數錯誤
            else if (ex instanceof ConstraintViolationException)
            {
                ConstraintViolationException v = (ConstraintViolationException) ex;
                String message = v.getConstraintViolations().iterator().next()
                        .getMessage();
                result.setCode(ResultCode.PARAMTER_ERROR.getCode());
                result.setMsg(ResultCode.PARAMTER_ERROR.getMsg() + ":" + message);
            }
            //參數錯誤
            else if (ex instanceof BindException)
            {
                BindException v = (BindException) ex;
                String message = v.getAllErrors().stream().map(ObjectError::getDefaultMessage).collect(Collectors.joining(","));
                result.setCode(ResultCode.PARAMTER_ERROR.getCode());
                result.setMsg(ResultCode.PARAMTER_ERROR.getMsg() + ":" + message);
            }
            //參數錯誤
            else if (ex instanceof MethodArgumentNotValidException)
            {
                MethodArgumentNotValidException v = (MethodArgumentNotValidException) ex;
                String message = v.getBindingResult().getAllErrors().stream().map(ObjectError::getDefaultMessage).collect(Collectors.joining(","));
                result.setCode(ResultCode.PARAMTER_ERROR.getCode());
                result.setMsg(ResultCode.PARAMTER_ERROR.getMsg() + ":" + message);
            }
            else
            {
               result = new Result(ResultCode.ERROR.getCode(),ExceptionUtil.getErrorMsg(ex));
            }
            logger.info("exception handle reuslt:" + result);
            return result;
        }
    }

    上述定義已經可以實現全局接口和異常的統一處理,但是存在的如下問題

    每個controller都需要返回Reesult類型,且每個方法都需要返回Result.success()或者Result.success(data)的結果,有點重復,需要進行優化。

        @GetMapping("addUser")
        public Result add()
        {
           for(int i=0;i<10;i++)
           {
               TUser user = new TUser();
               //user.setOid(IdWorker.getId());
               user.setName("shareing_"+i);
               user.setAge(i);
               userService.addUser(user);
           }
           return Result.success();
        }

    2.6 接口統一輸出優化

    實現方式只需要實現ResponseBodyAdvice接口,重寫beforeBodyWrite方法接口。

    @RestControllerAdvice
    public class ResponseAdvice implements ResponseBodyAdvice<Object>
    {
        private Logger logger = LoggerFactory.getLogger(ResponseAdvice.class);
        @Override
        public boolean supports(MethodParameter returnType,
                Class<? extends HttpMessageConverter<?>> converterType)
        {
            return true;
        }
        @Override
        public Object beforeBodyWrite(Object o, MethodParameter returnType,
                MediaType selectedContentType,
                Class<? extends HttpMessageConverter<?>> selectedConverterType,
                ServerHttpRequest request, ServerHttpResponse response)
        {
            logger.info("before body write param:{}",o);
            if(o instanceof String)
            {
               //序列化結果輸出
               return FastJsonUtil.toJSONString(Result.success(o));
            }
            else if (o instanceof Result)
            {
                 return o;
            }
            return Result.success(o);
        }
    }

    經過優化后,controller輸出可以根據業務的需求定義輸出對象。

     @GetMapping("getUserByName")
        public TUser getUserByName1(@RequestParam String name)
        {
           logger.info("getUserByName paramter name:"+name);
           return userService.getUserByName(name); 
        }

    2.7 子系統如何實現

    子系統引入common的jar包,

      <dependency>
    	    <groupId>com.xx</groupId>
    	    <artifactId>xx-common</artifactId>
    	    <version>2.0</version>
    	</dependency>

    3、子系統定義狀態碼,實現BaseResultCode接口

     public enum OrderModelErrorCode implements BaseResultCode
    {
        ORDER_STATUS_ERROR(1000, "訂單狀態不正確");
        private int code;
        private String msg;
        private UserModelErrorCode(int code, String msg)
        {
            this.code = code;
            this.msg = msg;
        }
        @Override
        public int getCode()
        {
            return code;
        }
        @Override
        public String getMsg()
        {
            return msg;
        }
    }

    定義異常處理類,繼承公共異常處理類SysExceptionHandler

    @RestControllerAdvice
    public class OrderModalExceptionHandle extends SysExceptionHandler
    {
         @Override
        public Result handleException(HttpServletRequest request, Exception ex)
        {
            return super.handleException(request, ex);
            //子系統可以擴展異常處理
        }
    }

    子系統使用示例:

    @Override
    public Order getOrder(String orderId)
    {
    	Order order =getOrder(orderId);
            //相關偽代碼
    	if(order.getStatus()>120)
    	{
    	   throw new SysException(OrderModelErrorCode.ORDER_STATUS_ERROR);    
    	}
    	return order;
    }

    感謝各位的閱讀,以上就是“Spring Boot統一接口返回及全局異常處理的方法”的內容了,經過本文的學習后,相信大家對Spring Boot統一接口返回及全局異常處理的方法這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

    向AI問一下細節

    免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

    AI

    冷水江市| 赤壁市| 商丘市| 安宁市| 廉江市| 阳西县| 井冈山市| 荆州市| 安泽县| 曲阳县| 筠连县| 嘉祥县| 东乡| 潢川县| 天水市| 富顺县| 岢岚县| 繁峙县| 三明市| 鄯善县| 吉隆县| 奇台县| 梓潼县| 珠海市| 五指山市| 黔西县| 东方市| 彭山县| 沭阳县| 灵丘县| 方山县| 穆棱市| 彩票| 新丰县| 罗城| 临颍县| 泊头市| 比如县| 呼和浩特市| 天全县| 聂拉木县|