日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java项目构建基础:统一结果,统一异常,统一日志

發布時間:2023/12/10 java 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java项目构建基础:统一结果,统一异常,统一日志 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

? ? ? ? ?

統一結果返回

目前的前后端開發大部分數據的傳輸格式都是json,因此定義一個統一規范的數據格式有利于前后端的交互與UI的展示。

統一結果的一般形式

  • 是否響應成功;

  • 響應狀態碼;

  • 狀態碼描述;

  • 響應數據

  • 其他標識符


結果類枚舉

前三者可定義結果枚舉,如:success,code,message

@Getter public?enum?ResultCodeEnum?{SUCCESS(true,20000,"成功"),UNKNOWN_ERROR(false,20001,"未知錯誤"),,PARAM_ERROR(false,20002,"參數錯誤"),;//?響應是否成功private?Boolean?success;//?響應狀態碼private?Integer?code;//?響應信息private?String?message;ResultCodeEnum(boolean?success,?Integer?code,?String?message)?{this.success?=?success;this.code?=?code;this.message?=?message;} }


統一結果類

第5個屬于自定義返回,利用前4者可定義統一返回對象

注意:

  • 外界只可以調用統一返回類的方法,不可以直接創建,因此構造器私有;

  • 內置靜態方法,返回對象;

  • 為便于自定義統一結果的信息,建議使用鏈式編程,將返回對象設類本身,即return this;

  • 響應數據由于為json格式,可定義為JsonObject或Map形式;

@Data public?class?R?{private?Boolean?success;private?Integer?code;private?String?message;private?Map<String,?Object>?data?=?new?HashMap<>();//?構造器私有private?R(){}//?通用返回成功public?static?R?ok()?{R?r?=?new?R();r.setSuccess(ResultCodeEnum.SUCCESS.getSuccess());r.setCode(ResultCodeEnum.SUCCESS.getCode());r.setMessage(ResultCodeEnum.SUCCESS.getMessage());return?r;}//?通用返回失敗,未知錯誤public?static?R?error()?{R?r?=?new?R();r.setSuccess(ResultCodeEnum.UNKNOWN_ERROR.getSuccess());r.setCode(ResultCodeEnum.UNKNOWN_ERROR.getCode());r.setMessage(ResultCodeEnum.UNKNOWN_ERROR.getMessage());return?r;}//?設置結果,形參為結果枚舉public?static?R?setResult(ResultCodeEnum?result)?{R?r?=?new?R();r.setSuccess(result.getSuccess());r.setCode(result.getCode());r.setMessage(result.getMessage());return?r;}/**------------使用鏈式編程,返回類本身-----------**///?自定義返回數據public?R?data(Map<String,Object>?map)?{this.setData(map);return?this;}//?通用設置datapublic?R?data(String?key,Object?value)?{this.data.put(key,?value);return?this;}//?自定義狀態信息public?R?message(String?message)?{this.setMessage(message);return?this;}//?自定義狀態碼public?R?code(Integer?code)?{this.setCode(code);return?this;}//?自定義返回結果public?R?success(Boolean?success)?{this.setSuccess(success);return?this;} }


控制層返回

視圖層使用統一結果

@RestController @RequestMapping("/api/v1/users") public?class?TeacherAdminController?{@Autowiredprivate?UserService?userService;@GetMappingpublic?R?list()?{List<Teacher>?list?=?teacherService.list(null);return?R.ok().data("itms",?list).message("用戶列表");} }????

json結果

{"success":?true,"code":?20000,"message":?"查詢用戶列表","data":?{"itms":?[{"id":?"1","username":?"admin","role":?"ADMIN","deleted":?false,"gmtCreate":?"2019-12-26T15:32:29","gmtModified":?"2019-12-26T15:41:40"},{"id":?"2","username":?"zhangsan","role":?"USER","deleted":?false,"gmtCreate":?"2019-12-26T15:32:29","gmtModified":?"2019-12-26T15:41:40"}]} }

統一結果類的使用參考了mybatis-plus中R對象的設計

統一異常處理

使用統一返回結果時,還有一種情況,就是程序的保存是由于運行時異常導致的結果,有些異常我們可以無法提前預知,不能正常走到我們return的R對象返回。

因此,我們需要定義一個統一的全局異常來捕獲這些信息,并作為一種結果返回控制層

@ControllerAdvice

該注解為統一異常處理的核心

是一種作用于控制層的切面通知(Advice),該注解能夠將通用的@ExceptionHandler、@InitBinder和@ModelAttributes方法收集到一個類型,并應用到所有控制器上

該類中的設計思路:

  • 使用@ExceptionHandler注解捕獲指定或自定義的異常;

  • 使用@ControllerAdvice集成@ExceptionHandler的方法到一個類中;

  • 必須定義一個通用的異常捕獲方法,便于捕獲未定義的異常信息;

  • 自定一個異常類,捕獲針對項目或業務的異常;

  • 異常的對象信息補充到統一結果枚舉中;


自定義全局異常類

@Data public?class?CMSException?extends?RuntimeException?{private?Integer?code;public?CMSException(Integer?code,?String?message)?{super(message);this.code?=?code;}public?CMSException(ResultCodeEnum?resultCodeEnum)?{super(resultCodeEnum.getMessage());this.code?=?resultCodeEnum.getCode();}@Overridepublic?String?toString()?{return?"CMSException{"?+?"code="?+?code?+?",?message="?+?this.getMessage()?+?\'}\';} }

統一異常處理器

//?... import?org.springframework.web.bind.annotation.ControllerAdvice; import?org.springframework.web.bind.annotation.ExceptionHandler; import?org.springframework.web.bind.annotation.ResponseBody;@ControllerAdvice public?class?GlobalExceptionHandler?{/**--------?通用異常處理方法?--------**/@ExceptionHandler(Exception.class)@ResponseBodypublic?R?error(Exception?e)?{e.printStackTrace();return?R.error();????//?通用異常結果}/**--------?指定異常處理方法?--------**/@ExceptionHandler(NullPointerException.class)@ResponseBodypublic?R?error(NullPointerException?e)?{e.printStackTrace();return?R.setResult(ResultCodeEnum.NULL_POINT);}@ExceptionHandler(HttpClientErrorException.class)@ResponseBodypublic?R?error(IndexOutOfBoundsException?e)?{e.printStackTrace();return?R.setResult(ResultCodeEnum.HTTP_CLIENT_ERROR);}/**--------?自定義定異常處理方法?--------**/@ExceptionHandler(CMSException.class)@ResponseBodypublic?R?error(CMSException?e)?{e.printStackTrace();return?R.error().message(e.getMessage()).code(e.getCode());} }


控制層展示

以下為展示當遇到null指定異常時,返回的結果信息

{"success":?false,"code":?20007,"message":?"空指針異常","data":?{} }

本節介紹統一異常較為簡略,詳細參考:

https://juejin.im/post/5cbc744a6fb9a0685a3f01a7


統一日志收集

日志是追蹤錯誤定位問題的關鍵,尤其在生產環境中,需要及時修復熱部署,不會提供開發者debug的環境,此時日志將會是最快解決問題的關鍵

日志的框架比較豐富,由于spring boot對logback的集成,因此推薦使用logback在項目中使用。

Logback

關于logback的配置和介紹,可以參考官網或推薦博客glmapper的logback博客,logback-spring.xml配置文件

https://blog.csdn.net/xu_san_duo/article/details/80364600


配置

以下直接貼出配置信息,介紹信息可以直接參考備注

<?xml?version="1.0"?encoding="UTF-8"?><configuration??scan="true"?scanPeriod="10?seconds"><contextName>logback</contextName><property?name="log.path"?value="D:/Documents/logs/edu"?/><conversionRule?conversionWord="clr"?converterClass="org.springframework.boot.logging.logback.ColorConverter"?/><conversionRule?conversionWord="wex"?converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter"?/><conversionRule?conversionWord="wEx"?converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter"?/><property?name="CONSOLE_LOG_PATTERN"?value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd?HH:mm:ss.SSS}){faint}?%clr(${LOG_LEVEL_PATTERN:-%5p})?%clr(${PID:-?}){magenta}?%clr(---){faint}?%clr([%15.15t]){faint}?%clr(%-40.40logger{39}){cyan}?%clr(:){faint}?%m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/><appender?name="CONSOLE"?class="ch.qos.logback.core.ConsoleAppender"><filter?class="ch.qos.logback.classic.filter.ThresholdFilter"><level>debug</level></filter><encoder><Pattern>${CONSOLE_LOG_PATTERN}</Pattern><charset>UTF-8</charset></encoder></appender><appender?name="DEBUG_FILE"?class="ch.qos.logback.core.rolling.RollingFileAppender"><file>${log.path}/edu_debug.log</file><encoder><pattern>%d{yyyy-MM-dd?HH:mm:ss.SSS}?[%thread]?%-5level?%logger{50}?-?%msg%n</pattern><charset>UTF-8</charset>?</encoder><rollingPolicy?class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><fileNamePattern>${log.path}/web-debug-%d{yyyy-MM-dd}.%i.log</fileNamePattern><timeBasedFileNamingAndTriggeringPolicy?class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"><maxFileSize>100MB</maxFileSize></timeBasedFileNamingAndTriggeringPolicy><maxHistory>15</maxHistory></rollingPolicy><filter?class="ch.qos.logback.classic.filter.LevelFilter"><level>debug</level><onMatch>ACCEPT</onMatch><onMismatch>DENY</onMismatch></filter></appender><appender?name="INFO_FILE"?class="ch.qos.logback.core.rolling.RollingFileAppender"><file>${log.path}/edu_info.log</file><encoder><pattern>%d{yyyy-MM-dd?HH:mm:ss.SSS}?[%thread]?%-5level?%logger{50}?-?%msg%n</pattern><charset>UTF-8</charset></encoder><rollingPolicy?class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><fileNamePattern>${log.path}/web-info-%d{yyyy-MM-dd}.%i.log</fileNamePattern><timeBasedFileNamingAndTriggeringPolicy?class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"><maxFileSize>100MB</maxFileSize></timeBasedFileNamingAndTriggeringPolicy><maxHistory>15</maxHistory></rollingPolicy><filter?class="ch.qos.logback.classic.filter.LevelFilter"><level>info</level><onMatch>ACCEPT</onMatch><onMismatch>DENY</onMismatch></filter></appender><appender?name="WARN_FILE"?class="ch.qos.logback.core.rolling.RollingFileAppender"><file>${log.path}/edu_warn.log</file><encoder><pattern>%d{yyyy-MM-dd?HH:mm:ss.SSS}?[%thread]?%-5level?%logger{50}?-?%msg%n</pattern><charset>UTF-8</charset>?</encoder><rollingPolicy?class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><fileNamePattern>${log.path}/web-warn-%d{yyyy-MM-dd}.%i.log</fileNamePattern><timeBasedFileNamingAndTriggeringPolicy?class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"><maxFileSize>100MB</maxFileSize></timeBasedFileNamingAndTriggeringPolicy><maxHistory>15</maxHistory></rollingPolicy><filter?class="ch.qos.logback.classic.filter.LevelFilter"><level>warn</level><onMatch>ACCEPT</onMatch><onMismatch>DENY</onMismatch></filter></appender><appender?name="ERROR_FILE"?class="ch.qos.logback.core.rolling.RollingFileAppender"><file>${log.path}/edu_error.log</file><encoder><pattern>%d{yyyy-MM-dd?HH:mm:ss.SSS}?[%thread]?%-5level?%logger{50}?-?%msg%n</pattern><charset>UTF-8</charset>?</encoder><rollingPolicy?class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><fileNamePattern>${log.path}/web-error-%d{yyyy-MM-dd}.%i.log</fileNamePattern><timeBasedFileNamingAndTriggeringPolicy?class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"><maxFileSize>100MB</maxFileSize></timeBasedFileNamingAndTriggeringPolicy><maxHistory>15</maxHistory></rollingPolicy><filter?class="ch.qos.logback.classic.filter.LevelFilter"><level>ERROR</level><onMatch>ACCEPT</onMatch><onMismatch>DENY</onMismatch></filter></appender>????<springProfile?name="dev"><logger?name="com.cms"?level="info"/><root?level="info"><appender-ref?ref="CONSOLE"?/><appender-ref?ref="DEBUG_FILE"?/><appender-ref?ref="INFO_FILE"?/><appender-ref?ref="WARN_FILE"?/><appender-ref?ref="ERROR_FILE"?/></root></springProfile><springProfile?name="pro"><logger?name="com.cms"?level="warn"/><root?level="info"><appender-ref?ref="ERROR_FILE"?/><appender-ref?ref="WARN_FILE"?/></root></springProfile></configuration>


日志收集異常信息

日志信息往往伴隨著異常信息的輸出,因此,我們需要修改統一異常的處理器,將異常信息以流的方式寫到日志文件中

異常信息文件工具類

@Slf4j public?class?ExceptionUtil?{/***?打印異常信息*/public?static?String?getMessage(Exception?e)?{String?swStr?=?null;try?(StringWriter?sw?=?new?StringWriter();?PrintWriter?pw?=?new?PrintWriter(sw))?{e.printStackTrace(pw);pw.flush();sw.flush();swStr?=?sw.toString();}?catch?(IOException?ex)?{ex.printStackTrace();log.error(ex.getMessage());}return?swStr;} }

修改統一異常處理器,將異常方法中的直接打印改為日志輸入并打印

//?... import?lombok.extern.slf4j.Slf4j;@ControllerAdvice @Slf4j public?class?GlobalExceptionHandler?{/**--------?通用異常處理方法?--------**/@ExceptionHandler(Exception.class)@ResponseBodypublic?R?error(Exception?e)?{//?e.printStackTrace();log.error(ExceptionUtil.getMessage(e));return?R.error();}//?... }???

注意

  • 日志的環境即spring.profiles.acticve,跟隨項目啟動;

  • 啟動后,即可到自定目錄查找到生成的日志文件;

  • 本地idea調試時,推薦Grep Console插件可實現控制臺的自定義顏色輸出

詳細過程,可參考源代碼:

https://github.com/chetwhy/cloud-flow

作者:永動的圖靈機

juejin.im/post/5e073980f265da33f8653f2e

文章推薦程序員效率:畫流程圖常用的工具程序員效率:整理常用的在線筆記軟件遠程辦公:常用的遠程協助軟件,你都知道嗎?51單片機程序下載、ISP及串口基礎知識硬件:斷路器、接觸器、繼電器基礎知識

總結

以上是生活随笔為你收集整理的Java项目构建基础:统一结果,统一异常,统一日志的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。