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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【金融项目】尚融宝项目(二)

發(fā)布時間:2023/12/16 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【金融项目】尚融宝项目(二) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

4、后端接口工程搭建

4.1、創(chuàng)建尚融寶接口工程

4.1.1、需求

積分等級CRUD列表和表單

4.1.2、創(chuàng)建父工程srb

4.1.2.1、創(chuàng)建SpringBoot項目

Group:com.atguigu

Artifact:srb

4.1.2.2、刪除src目錄

4.1.2.3、配置SpringBoot版本

<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.4.RELEASE</version> </parent>

4.1.2.4、配置pom依賴版本號

<properties><java.version>1.8</java.version><spring-cloud-alibaba.version>2.2.2.RELEASE</spring-cloud-alibaba.version><spring-cloud.version>Hoxton.SR8</spring-cloud.version><mybatis-plus.version>3.4.1</mybatis-plus.version><velocity.version>2.0</velocity.version><swagger.version>2.9.2</swagger.version><swagger-bootstrap-ui.version>1.9.2</swagger-bootstrap-ui.version><commons-lang3.version>3.9</commons-lang3.version><commons-fileupload.version>1.3.1</commons-fileupload.version><commons-io.version>2.6</commons-io.version><alibaba.easyexcel.version>2.1.1</alibaba.easyexcel.version><apache.xmlbeans.version>3.1.0</apache.xmlbeans.version><fastjson.version>1.2.28</fastjson.version><gson.version>2.8.2</gson.version><json.version>20170516</json.version><aliyun-java-sdk-core.version>4.3.3</aliyun-java-sdk-core.version><aliyun-sdk-oss.version>3.10.2</aliyun-sdk-oss.version><jodatime.version>2.10.1</jodatime.version><jwt.version>0.7.0</jwt.version><httpclient.version>4.5.1</httpclient.version> </properties>

4.1.2.5、配置pom依賴

<dependencyManagement><dependencies><!--Spring Cloud--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>${spring-cloud.version}</version><type>pom</type><scope>import</scope></dependency><!--Spring Cloud Alibaba--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-dependencies</artifactId><version>${spring-cloud-alibaba.version}</version><type>pom</type><scope>import</scope></dependency><!--mybatis-plus--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>${mybatis-plus.version}</version></dependency><!--mybatis-plus 代碼生成器--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-generator</artifactId><version>${mybatis-plus.version}</version></dependency><!-- Mybatis Plus 代碼生成器模板引擎, --><dependency><groupId>org.apache.velocity</groupId><artifactId>velocity-engine-core</artifactId><version>${velocity.version}</version></dependency><!--swagger--><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId><version>${swagger.version}</version></dependency><!--swagger ui--><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger-ui</artifactId><version>${swagger.version}</version></dependency><!--swagger-bootstrap-ui--><dependency><groupId>com.github.xiaoymin</groupId><artifactId>swagger-bootstrap-ui</artifactId><version>${swagger-bootstrap-ui.version}</version></dependency><!--commons-lang3--><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>${commons-lang3.version}</version></dependency><!--文件上傳--><dependency><groupId>commons-fileupload</groupId><artifactId>commons-fileupload</artifactId><version>${commons-fileupload.version}</version></dependency><!--commons-io--><dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>${commons-io.version}</version></dependency><!--excel解析--><dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>${alibaba.easyexcel.version}</version></dependency><!--excel解析依賴--><dependency><groupId>org.apache.xmlbeans</groupId><artifactId>xmlbeans</artifactId><version>${apache.xmlbeans.version}</version></dependency><!--json--><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>${fastjson.version}</version></dependency><dependency><groupId>org.json</groupId><artifactId>json</artifactId><version>${json.version}</version></dependency><dependency><groupId>com.google.code.gson</groupId><artifactId>gson</artifactId><version>${gson.version}</version></dependency><!--阿里云SDK遠程調(diào)用--><dependency><groupId>com.aliyun</groupId><artifactId>aliyun-java-sdk-core</artifactId><version>${aliyun-java-sdk-core.version}</version></dependency><!--阿里云文件管理--><dependency><groupId>com.aliyun.oss</groupId><artifactId>aliyun-sdk-oss</artifactId><version>${aliyun-sdk-oss.version}</version></dependency><!--日期時間工具--><dependency><groupId>joda-time</groupId><artifactId>joda-time</artifactId><version>${jodatime.version}</version></dependency><!--jwt工具--><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>${jwt.version}</version></dependency><!--httpclient--><dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId><version>${httpclient.version}</version></dependency></dependencies> </dependencyManagement> <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency> </dependencies>

4.1.3、創(chuàng)建模塊guigu-common

4.1.3.1、創(chuàng)建Maven模塊

在srb下創(chuàng)建普通maven模塊

Group:com.atguigu

Artifact:guigu-common

4.1.3.2、配置pom

<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--lombok用來簡化實體類:需要安裝lombok插件--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency> </dependencies>

4.1.4、創(chuàng)建模塊service-base

4.1.4.1、創(chuàng)建Maven模塊

在srb下創(chuàng)建普通maven模塊

Group:com.atguigu

Artifact:service-base

4.1.4.2、配置pom

注意:依賴guigu-common

<dependencies><dependency><groupId>com.atguigu</groupId><artifactId>guigu-common</artifactId><version>0.0.1-SNAPSHOT</version></dependency><!--swagger--><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId></dependency><!--swagger ui--><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger-ui</artifactId></dependency> </dependencies>

4.1.5、創(chuàng)建模塊service-core

4.1.5.1、創(chuàng)建Maven模塊

在srb下創(chuàng)建普通maven模塊

Group:com.atguigu

Artifact:service-core

4.1.5.2、配置pom

注意:依賴service-base

<dependencies><dependency><groupId>com.atguigu</groupId><artifactId>service-base</artifactId><version>0.0.1-SNAPSHOT</version></dependency><!--mysql--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><!--mybatis-plus--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId></dependency><!--mybatis-plus 代碼生成器--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-generator</artifactId></dependency><!-- Mybatis Plus 代碼生成器模板引擎, --><dependency><groupId>org.apache.velocity</groupId><artifactId>velocity-engine-core</artifactId></dependency> </dependencies>

4.1.6、代碼生成器

4.1.6.1、創(chuàng)建數(shù)據(jù)庫

創(chuàng)建數(shù)據(jù)庫srb_core

并執(zhí)行sql腳本初始化數(shù)據(jù)結(jié)構(gòu)和數(shù)據(jù)

4.1.6.2、創(chuàng)建代碼生成器

在test目錄中創(chuàng)建測試用例,并執(zhí)行

package com.atguigu.srb.core; public class CodeGenerator {@Testpublic void genCode() {// 1、創(chuàng)建代碼生成器AutoGenerator mpg = new AutoGenerator();// 2、全局配置GlobalConfig gc = new GlobalConfig();String projectPath = System.getProperty("user.dir");gc.setOutputDir(projectPath + "/src/main/java");gc.setAuthor("Helen");gc.setOpen(false); //生成后是否打開資源管理器gc.setServiceName("%sService"); //去掉Service接口的首字母Igc.setIdType(IdType.AUTO); //主鍵策略gc.setSwagger2(true);//開啟Swagger2模式mpg.setGlobalConfig(gc);// 3、數(shù)據(jù)源配置DataSourceConfig dsc = new DataSourceConfig();dsc.setUrl("jdbc:mysql://localhost:3306/srb_core?serverTimezone=GMT%2B8&characterEncoding=utf-8");dsc.setDriverName("com.mysql.cj.jdbc.Driver");dsc.setUsername("root");dsc.setPassword("123456");dsc.setDbType(DbType.MYSQL);mpg.setDataSource(dsc);// 4、包配置PackageConfig pc = new PackageConfig();pc.setParent("com.atguigu.srb.core");pc.setEntity("pojo.entity"); //此對象與數(shù)據(jù)庫表結(jié)構(gòu)一一對應(yīng),通過 DAO 層向上傳輸數(shù)據(jù)源對象。mpg.setPackageInfo(pc);// 5、策略配置StrategyConfig strategy = new StrategyConfig();strategy.setNaming(NamingStrategy.underline_to_camel);//數(shù)據(jù)庫表映射到實體的命名策略strategy.setColumnNaming(NamingStrategy.underline_to_camel);//數(shù)據(jù)庫表字段映射到實體的命名策略strategy.setEntityLombokModel(true); // lombokstrategy.setLogicDeleteFieldName("is_deleted");//邏輯刪除字段名strategy.setEntityBooleanColumnRemoveIsPrefix(true);//去掉布爾值的is_前綴(確保tinyint(1))strategy.setRestControllerStyle(true); //restful api風(fēng)格控制器mpg.setStrategy(strategy);// 6、執(zhí)行mpg.execute();} }

4.1.7、啟動應(yīng)用程序

4.1.7.1、創(chuàng)建application.yml

server:port: 8110 # 服務(wù)端口 spring:profiles:active: dev # 環(huán)境設(shè)置application:name: service-core # 服務(wù)名datasource: # mysql數(shù)據(jù)庫連接type: com.zaxxer.hikari.HikariDataSourcedriver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/srb_core?serverTimezone=GMT%2B8&characterEncoding=utf-8username: rootpassword: 123456 mybatis-plus: #mybatisconfiguration:log-impl: org.apache.ibatis.logging.stdout.StdOutImplmapper-locations: classpath:com/atguigu/srb/core/mapper/xml/*.xml

4.1.7.2、創(chuàng)建SpringBoot配置文件

在service-core中創(chuàng)建config包,創(chuàng)建MybatisPlusConfig類

package com.atguigu.srb.core.config; @Configuration @MapperScan("com.atguigu.srb.core.mapper") @EnableTransactionManagement //事務(wù)處理 public class MybatisPlusConfig {@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));//分頁return interceptor;} }

4.1.7.3、創(chuàng)建SpringBoot啟動類

注意:掃描com.atguigu.srb

package com.atguigu.srb.core; @SpringBootApplication @ComponentScan({"com.atguigu.srb"}) public class ServiceCoreApplication {public static void main(String[] args) {SpringApplication.run(ServiceCoreApplication.class, args);} }

4.1.7.4、運行啟動類

查看控制臺8110端口是否成功啟動

4.2、積分等級CRUD

4.2.1、積分等級列表接口

4.2.1.1、編寫積分等級管理接口

在controller中添加admin包,添加AdminIntegralGradeController類

package com.atguigu.srb.core.controller.admin; @CrossOrigin @RestController @RequestMapping("/admin/core/integralGrade") public class AdminIntegralGradeController {@Resourceprivate IntegralGradeService integralGradeService;@GetMapping("/list")public List<IntegralGrade> listAll(){return integralGradeService.list();} }

4.2.1.2、測試

重啟服務(wù),訪問: http://localhost:8110/admin/core/integralGrade/list 查看結(jié)果json數(shù)據(jù)

4.2.2、邏輯刪除接口

4.2.2.1、添加刪除方法

AdminIntegralGradeController添加removeById方法

@DeleteMapping("/remove/{id}") public boolean removeById(@PathVariable Long id){return integralGradeService.removeById(id); }

4.2.2.2、使用postman測試刪除

4.2.3、配置Swagger2

4.2.3.1、Swagger2配置文件

在service-base中創(chuàng)建Swagger2Config

package com.atguigu.srb.base.config; @Configuration @EnableSwagger2 public class Swagger2Config {@Beanpublic Docket adminApiConfig(){return new Docket(DocumentationType.SWAGGER_2).groupName("adminApi").apiInfo(adminApiInfo()).select()//只顯示admin路徑下的頁面.paths(Predicates.and(PathSelectors.regex("/admin/.*"))).build();}private ApiInfo adminApiInfo(){return new ApiInfoBuilder().title("尚融寶后臺管理系統(tǒng)-API文檔").description("本文檔描述了尚融寶后臺管理系統(tǒng)接口").version("1.0").contact(new Contact("Helen", "http://atguigu.com", "55317332@qq.com")).build();} }

4.2.3.2、查看Swagger文檔

重啟服務(wù)器查看接口文檔:http://localhost:8110/swagger-ui.html

4.2.3.3、常見注解

**實體類注解:**entity的實體類中可以添加一些自定義設(shè)置,例如:

@ApiModelProperty(value = "創(chuàng)建時間", example = "2019-01-01 8:00:00") private LocalDateTime createTime; @ApiModelProperty(value = "更新時間", example = "2019-01-01 8:00:00") private LocalDateTime updateTime;

controller注解:

定義在類上

@Api(tags = "積分等級管理")

定義在方法上

@ApiOperation("積分等級列表") @ApiOperation(value = "根據(jù)id刪除積分等級", notes = "邏輯刪除")

定義在參數(shù)上

@ApiParam(value = "數(shù)據(jù)id", required = true, example = "100")

4.3、統(tǒng)一返回結(jié)果

4.3.1、定義統(tǒng)一返回結(jié)果

4.3.1.1、數(shù)據(jù)格式的定義

項目中我們會將響應(yīng)封裝成json返回,一般我們會將所有接口的數(shù)據(jù)格式統(tǒng)一, 使前端對數(shù)據(jù)的操作更一致、輕松。

一般情況下,統(tǒng)一返回數(shù)據(jù)格式?jīng)]有固定的格式,只要能描述清楚返回的數(shù)據(jù)狀態(tài)以及要返回的具體數(shù)據(jù)就可以。但是一般會包含狀態(tài)碼、返回消息、數(shù)據(jù)這幾部分內(nèi)容

例如,我們的系統(tǒng)要求返回的基本數(shù)據(jù)格式如下:

成功:

{"code": 0,"message": "成功","data": 數(shù)據(jù)}

失敗:

{"code": -1,"message": "失敗","data": null }

因此,我們定義統(tǒng)一結(jié)果

{"code": 數(shù)字, //業(yè)務(wù)響應(yīng)碼"message": 字符串, //返回消息"data": 對象 //返回數(shù)據(jù) }

4.3.1.2、創(chuàng)建枚舉

在guigu-common中創(chuàng)建result包,創(chuàng)建枚舉 ResponseEnum

package com.atguigu.common.result; @Getter @AllArgsConstructor @ToString public enum ResponseEnum {SUCCESS(0, "成功"),ERROR(-1, "服務(wù)器內(nèi)部錯誤"),;// 響應(yīng)狀態(tài)碼private Integer code;// 響應(yīng)信息private String message; }

完整的枚舉源代碼:ResponseEnum.java

4.3.1.3、定義同統(tǒng)一結(jié)果類

package com.atguigu.common.result; @Data public class R {private Integer code;private String message;private Map<String, Object> data = new HashMap();/*** 構(gòu)造器私有*/private R(){}/*** 返回成功*/public static R ok(){R r = new R();r.setCode(ResponseEnum.SUCCESS.getCode());r.setMessage(ResponseEnum.SUCCESS.getMessage());return r;}/*** 返回失敗*/public static R error(){R r = new R();r.setCode(ResponseEnum.ERROR.getCode());r.setMessage(ResponseEnum.ERROR.getMessage());return r;}/*** 設(shè)置特定結(jié)果*/public static R setResult(ResponseEnum responseEnum){R r = new R();r.setCode(responseEnum.getCode());r.setMessage(responseEnum.getMessage());return r;}public R message(String message){this.setMessage(message);return this;}public R code(Integer code){this.setCode(code);return this;}public R data(String key, Object value){this.data.put(key, value);return this;}public R data(Map<String, Object> map){this.setData(map);return this;} }

4.3.2、使用統(tǒng)一返回結(jié)果

4.3.2.1、修改listAll

@ApiOperation("積分等級列表") @GetMapping("/list") public R listAll(){List<IntegralGrade> list = integralGradeService.list();return R.ok().data("list", list); }

4.3.2.2、修改removeById

@ApiOperation(value = "根據(jù)id刪除積分等級", notes="邏輯刪除") @DeleteMapping("/remove/{id}") public R removeById(@ApiParam(value = "數(shù)據(jù)id", required = true, example = "1")@PathVariable Long id){boolean result = integralGradeService.removeById(id);if(result){//return R.setResult(ResponseEnum.UPLOAD_ERROR);return R.ok().message("刪除成功");}else{return R.error().message("刪除失敗");} }

4.3.2.3、新增數(shù)據(jù)

@ApiOperation("新增積分等級") @PostMapping("/save") public R save(@ApiParam(value = "積分等級對象", required = true)@RequestBody IntegralGrade integralGrade){boolean result = integralGradeService.save(integralGrade);if (result) {return R.ok().message("保存成功");} else {return R.error().message("保存失敗");} }

4.3.2.4、根據(jù)id查詢

@ApiOperation("根據(jù)id獲取積分等級") @GetMapping("/get/{id}") public R getById(@ApiParam(value = "數(shù)據(jù)id", required = true, example = "1")@PathVariable Long id){IntegralGrade integralGrade = integralGradeService.getById(id);if(integralGrade != null){return R.ok().data("record", integralGrade);}else{return R.error().message("數(shù)據(jù)不存在");} }

4.3.2.5、根據(jù)id修改

@ApiOperation("更新積分等級") @PutMapping("/update") public R updateById(@ApiParam(value = "積分等級對象", required = true)@RequestBody IntegralGrade integralGrade){boolean result = integralGradeService.updateById(integralGrade);if(result){return R.ok().message("修改成功");}else{return R.error().message("修改失敗");} }

4.4、統(tǒng)一異常處理

4.4.1、項目中的異常

4.4.1.1、制造異常

屏蔽 IntegralGrade 中的 @TableField注解

@ApiModelProperty(value = "邏輯刪除(1:已刪除,0:未刪除)") //@TableField("is_deleted") @TableLogic private Boolean deleted;

4.4.1.2、Swagger中測試

測試列表查詢功能,查看結(jié)果,發(fā)生錯誤,顯示響應(yīng)失敗

4.4.2、統(tǒng)一異常處理

目標:我們想讓異常結(jié)果也顯示為統(tǒng)一的返回結(jié)果對象,并且統(tǒng)一處理系統(tǒng)的異常信息,那么需要進行統(tǒng)一異常處理。

4.4.2.1、創(chuàng)建統(tǒng)一異常處理器

guigu-common中創(chuàng)建exception包,創(chuàng)建統(tǒng)一異常處理器類UnifiedExceptionHandler

package com.atguigu.common.exception; @Slf4j @Component //Spring容易自動管理 @RestControllerAdvice //在controller層添加通知。如果使用@ControllerAdvice,則方法上需要添加@ResponseBody public class UnifiedExceptionHandler {/*** 未定義異常*/@ExceptionHandler(value = Exception.class) //當(dāng)controller中拋出Exception,則捕獲public R handleException(Exception e) {log.error(e.getMessage(), e);return R.error();} }

4.4.2.2、service-core添加掃描

添加 “com.atguigu.common”

@SpringBootApplication @ComponentScan({"com.atguigu.srb", "com.atguigu.common"}) public class ServiceCoreApplication {

4.4.2.3、測試

返回統(tǒng)一錯誤結(jié)果

4.4.3、處理特定異常

如果我們不想顯示統(tǒng)一的“服務(wù)器內(nèi)部錯誤”,需要個性化的顯示異常信息,那么需要針對特定的異常做處理

4.4.3.1、添加依賴

在guigu-common中添加jdbc依賴

<dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId> </dependency>

4.4.3.2、添加異常處理方法

在 UnifiedExceptionHandler 中添加

/** * 特定異常 */ @ExceptionHandler(BadSqlGrammarException.class) public R handleBadSqlGrammarException(BadSqlGrammarException e){log.error(e.getMessage(), e);return R.setResult(ResponseEnum.BAD_SQL_GRAMMAR_ERROR); }

4.4.3.3、測試

問題:上面的例子雖然針對特定的異常顯示個性化的錯誤信息,但是你會發(fā)現(xiàn),針對每個不同的異常我們都需要在項目中添加對應(yīng)的處理方法,并捕獲對應(yīng)的異常對象,可能還要針對這個異常添加額外的依賴。這顯然不是最好的方式。

方案:此類異常直接拋出,并且用Exception類捕獲就可以了。

4.4.3.4、恢復(fù)制造的異常

@TableField(value = "is_deleted")

4.4.4、自定義異常

目標:使用一個或較少的異常類,可以捕獲和顯示所有的異常信息。

方案:因此,我們可以創(chuàng)建一個自定義異常類(必須是運行時異常),在程序中拋出這個自定義異常對象,并在統(tǒng)一異常處理器中捕獲自定義異常對象

4.4.4.1、創(chuàng)建自定義異常類

package com.atguigu.common.exception; @Data @NoArgsConstructor public class BusinessException extends RuntimeException {//狀態(tài)碼private Integer code;//錯誤消息private String message; }

完整的源代碼:BusinessException.java

4.4.4.2、添加異常處理方法

UnifiedExceptionHandler類中添加

/** * 自定義異常 */ @ExceptionHandler(BusinessException.class) public R handleBusinessException(BusinessException e){log.error(e.getMessage(), e);return R.error().message(e.getMessage()).code(e.getCode()); }

4.4.4.3、修改Controller

在AdminIntegralGradeController的方法中添加異常處理,業(yè)務(wù)中需要的位置拋出BusinessException自定義異常。

@ApiOperation("新增積分等級") @PostMapping("/save") public R save(@ApiParam(value = "積分等級對象", required = true)@RequestBody IntegralGrade integralGrade){//如果借款額度為空就手動拋出一個自定義的異常!if(integralGrade.getBorrowAmount() == null){//BORROW_AMOUNT_NULL_ERROR(-201, "借款額度不能為空"),throw new BusinessException(ResponseEnum.BORROW_AMOUNT_NULL_ERROR);}boolean result = integrationService.save(integralGrade);if (result) {return R.ok().message("保存成功");} else {return R.error().message("保存失敗");} }

4.4.4.4、測試

測試

結(jié)果

4.4.5、異常處理優(yōu)化

目標:以優(yōu)雅的 Assert(斷言) 方式來校驗業(yè)務(wù)的異常情況,消除 if else

4.4.5.1、什么是斷言

package com.atguigu.srb.core; import org.junit.jupiter.api.Test; import org.springframework.util.Assert; public class AssertTests {//if else的用法@Testpublic void test1() {Object o = null;if (o == null) {throw new IllegalArgumentException("用戶不存在.");}}//斷言的用法:更為簡潔@Testpublic void test2() {// 另一種寫法Object o = null;Assert.notNull(o, "用戶不存在.");} }

4.4.5.2、自定義斷言

用斷言的方式封裝異常的拋出

package com.atguigu.common.exception; @Slf4j public abstract class Assert {/*** 斷言對象不為空* 如果對象obj為空,則拋出異常* @param obj 待判斷對象*/public static void notNull(Object obj, ResponseEnum responseEnum) {if (obj == null) {log.info("obj is null...............");throw new BusinessException(responseEnum);}} }

完整的源代碼:Assert.java

4.4.5.3、修改controller

在controller中用斷言替換if else

Assert.notNull(integralGrade.getBorrowAmount(), ResponseEnum.BORROW_AMOUNT_NULL_ERROR);

4.4.6、Controller上層異常

4.4.6.1、異常分類

對異常按階段進行分類,大體可以分成:進入Controller前的異常 和 業(yè)務(wù)層異常,具體可以參考下圖:

4.4.6.2、處理Controller上層異常

UnifiedExceptionHandler中添加

/*** Controller上一層相關(guān)異常*/ @ExceptionHandler({NoHandlerFoundException.class,HttpRequestMethodNotSupportedException.class,HttpMediaTypeNotSupportedException.class,MissingPathVariableException.class,MissingServletRequestParameterException.class,TypeMismatchException.class,HttpMessageNotReadableException.class,HttpMessageNotWritableException.class,MethodArgumentNotValidException.class,HttpMediaTypeNotAcceptableException.class,ServletRequestBindingException.class,ConversionNotSupportedException.class,MissingServletRequestPartException.class,AsyncRequestTimeoutException.class}) public R handleServletException(Exception e) {log.error(e.getMessage(), e);//SERVLET_ERROR(-102, "servlet請求異常"),return R.error().message(ResponseEnum.SERVLET_ERROR.getMessage()).code(ResponseEnum.SERVLET_ERROR.getCode()); }

4.4.6.3、測試

在save測試用例中輸入非法的json參數(shù),則得到下面的結(jié)果。我們可以在控制臺日志中查看具體的錯誤原因。前端只需要返回相對簡單友好的提示即可。

4.5、統(tǒng)一日志處理

4.5.1、Logback日志

4.5.1.1、什么是日志

通過日志查看程序的運行過程,運行信息,異常信息等

4.5.1.2、日志級別

日志記錄器(Logger)的行為是分等級的。如下表所示:

分為:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF

默認情況下,spring boot從控制臺打印出來的日志級別只有INFO及以上級別,可以配置日志級別

# 設(shè)置日志級別 logging:level:root: ERROR

這種方式能將ERROR級別以及以上級別的日志輸出到控制臺上,其他級別將不會輸出

4.5.1.3、創(chuàng)建日志文件

spring boot內(nèi)部使用Logback作為日志實現(xiàn)的框架。

先刪除前面在application.yml中的日志級別配置

resources 中創(chuàng)建 logback-spring.xml (默認日志文件的名字)

<?xml version="1.0" encoding="UTF-8"?> <configuration> </configuration>

4.5.1.4、創(chuàng)建測試日志輸出

將以下日志輸出到任意controller的方法中即可,例如list方法中

@ApiOperation("積分等級列表") @GetMapping("/list") public R listAll(){log.info("hi i'm helen");log.warn("warning!!!");log.error("it's a error");List<IntegralGrade> list = integrationService.list();return R.ok().data("list", list); }

4.5.2、基本配置說明

4.5.2.1、configuration

日志配置的根節(jié)點

<configuration></configuration>

4.5.2.2、contextName

是的子節(jié)點。

每個logger都關(guān)聯(lián)到logger上下文,默認上下文名稱為“default”。但可以使用設(shè)置成其他名字,用于區(qū)分不同的應(yīng)用程序。

<contextName>atguiguSrb</contextName>

4.5.2.3、property

是的子節(jié)點,用來定義變量。

有兩個屬性,name和value:name的值是變量的名稱,value是變量的值。

通過定義的值會被插入到logger上下文中。定義變量后,可以使“${}”來使用變量。

<!-- 日志的輸出目錄 --> <property name="log.path" value="D:/project/finance/srb_log/core" /> <!--控制臺日志格式:彩色日志--> <!-- magenta:洋紅 --> <!-- boldMagenta:粗紅--> <!-- cyan:青色 --> <!-- white:白色 --> <!-- magenta:洋紅 --> <property name="CONSOLE_LOG_PATTERN"value="%yellow(%date{yyyy-MM-dd HH:mm:ss}) %highlight([%-5level]) %green(%logger) %msg%n"/> <!--文件日志格式--> <property name="FILE_LOG_PATTERN"value="%date{yyyy-MM-dd HH:mm:ss} [%-5level] %thread %file:%line %logger %msg%n" /> <!--編碼--> <property name="ENCODING"value="UTF-8" />

4.5.2.4、appender

是的子節(jié)點,是負責(zé)寫日志的組件

有兩個必要屬性name和class:name指定appender名稱,class指定appender的全限定名

對日志進行格式化

定義日志的具體輸出格式

編碼方式

控制臺日志配置

<!-- 控制臺日志 --> <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"><encoder><pattern>${CONSOLE_LOG_PATTERN}</pattern><charset>${ENCODING}</charset></encoder> </appender>

**文件日志配置 **

表示日志文件的位置,如果上級目錄不存在會自動創(chuàng)建,沒有默認值。

默認 true,日志被追加到文件結(jié)尾,如果是 false,服務(wù)重啟后清空現(xiàn)存文件。

<!-- 文件日志 --> <appender name="FILE" class="ch.qos.logback.core.FileAppender"><file>${log.path}/log.log</file><append>true</append><encoder><pattern>${FILE_LOG_PATTERN}</pattern><charset>${ENCODING}</charset></encoder> </appender>

4.5.2.5、logger

可以是的子節(jié)點,用來設(shè)置某一個包或具體某一個類的日志打印級別、指定

name:用來指定受此logger約束的某一個包或者具體的某一個類

level:用來設(shè)置打印級別,大小寫無關(guān):TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF。默認繼承上級的級別

可以包含零個或多個元素,標識這個appender將會添加到這個logger

<!-- 日志記錄器 --> <logger name="com.atguigu" level="INFO"><appender-ref ref="CONSOLE" /><appender-ref ref="FILE" /> </logger>

4.5.2.6、測試

測試日志記錄的控制臺輸出、文件輸出、以及日志級別

4.5.3、多環(huán)境配置

springProfile

在一個基于Spring boot開發(fā)的項目里,常常需要有多套環(huán)境的配置:開發(fā),測試以及產(chǎn)品。使用springProfile 可以分別配置開發(fā)(dev),測試(test)以及生產(chǎn)(prod)等不同的環(huán)境

<!-- 開發(fā)環(huán)境和測試環(huán)境 --> <springProfile name="dev,test"><logger name="com.atguigu" level="INFO"><appender-ref ref="CONSOLE" /></logger> </springProfile> <!-- 生產(chǎn)環(huán)境 --> <springProfile name="prod"><logger name="com.atguigu" level="ERROR"><appender-ref ref="CONSOLE" /><appender-ref ref="FILE" /></logger> </springProfile>

4.5.4、滾動日志

問題:生產(chǎn)環(huán)境下,如果系統(tǒng)長時間運行,那么日志文件會變得越來越大,系統(tǒng)讀取和寫入日志的時間會越來越慢,嚴重的情況會耗盡系統(tǒng)內(nèi)存,導(dǎo)致系統(tǒng)宕機。

解決方案:可以設(shè)置滾動日志。

4.5.4.1、設(shè)置時間滾動策略

RollingFileAppender是Appender的另一個實現(xiàn),表示滾動記錄文件,先將日志記錄到指定文件,當(dāng)符合某個條件時,將舊日志備份到其他文件

是的子節(jié)點,用來定義滾動策略。

TimeBasedRollingPolicy:最常用的滾動策略,根據(jù)時間來制定滾動策略。

:包含文件名及轉(zhuǎn)換符, “%d”可以包含指定的時間格式,如:%d{yyyy-MM-dd}。如果直接使用 %d,默認格式是 yyyy-MM-dd。:可選節(jié)點,控制保留的歸檔文件的最大數(shù)量,超出數(shù)量就刪除舊文件。假設(shè)設(shè)置每個月滾動,且是6,則只保存最近6個月的文件,刪除之前的舊文件。注意,刪除舊文件是,那些為了歸檔而創(chuàng)建的目錄也會被刪除。

<appender name="ROLLING_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"><!-- 要區(qū)別于其他的appender中的文件名字 --><file>${log.path}/log-rolling.log</file><encoder><pattern>${FILE_LOG_PATTERN}</pattern><charset>${ENCODING}</charset></encoder><!-- 設(shè)置滾動日志記錄的滾動策略 --><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><!-- 日志歸檔路徑以及格式 --><fileNamePattern>${log.path}/info/log-rolling-%d{yyyy-MM-dd}.log</fileNamePattern><!--歸檔日志文件保留的最大數(shù)量--><maxHistory>15</maxHistory></rollingPolicy> </appender>

4.5.4.2、設(shè)置觸發(fā)滾動時機

放在的子節(jié)點的位置,基于實踐策略的觸發(fā)滾動策略

設(shè)置觸發(fā)滾動條件:單個文件大于100M時生成新的文件

注意:修改日志文件名 此時 ${log.path}/info/log-rolling-%d{yyyy-MM-dd}.%i.log

<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"><maxFileSize>1KB</maxFileSize> </timeBasedFileNamingAndTriggeringPolicy>

4.5.5、完整的日志配置文件

<?xml version="1.0" encoding="UTF-8"?> <configuration><contextName>atguiguSrb</contextName><!-- 日志的輸出目錄 --><property name="log.path" value="D:/project/test/srb_log/core" /><!--控制臺日志格式:彩色日志--><!-- magenta:洋紅 --><!-- boldMagenta:粗紅--><!-- cyan:青色 --><!-- white:白色 --><!-- magenta:洋紅 --><property name="CONSOLE_LOG_PATTERN"value="%yellow(%date{yyyy-MM-dd HH:mm:ss}) %highlight([%-5level]) %green(%logger) %msg%n"/><!--文件日志格式--><property name="FILE_LOG_PATTERN"value="%date{yyyy-MM-dd HH:mm:ss} [%-5level] %thread %file:%line %logger %msg%n" /><!--編碼--><property name="ENCODING"value="UTF-8" /><!-- 控制臺日志 --><appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"><encoder><pattern>${CONSOLE_LOG_PATTERN}</pattern><charset>${ENCODING}</charset></encoder></appender><!-- 文件日志 --><appender name="FILE" class="ch.qos.logback.core.FileAppender"><file>${log.path}/log.log</file><append>true</append><encoder><pattern>${FILE_LOG_PATTERN}</pattern><charset>${ENCODING}</charset></encoder></appender><appender name="ROLLING_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"><!-- 要區(qū)別于其他的appender中的文件名字 --><file>${log.path}/log-rolling.log</file><encoder><pattern>${FILE_LOG_PATTERN}</pattern><charset>${ENCODING}</charset></encoder><!-- 設(shè)置滾動日志記錄的滾動策略 --><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><!-- 日志歸檔路徑以及格式 --><fileNamePattern>${log.path}/info/log-rolling-%d{yyyy-MM-dd}.%i.log</fileNamePattern><!--歸檔日志文件保留的最大數(shù)量--><maxHistory>15</maxHistory><timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"><maxFileSize>1KB</maxFileSize></timeBasedFileNamingAndTriggeringPolicy></rollingPolicy></appender><!-- <logger name="com.atguigu" level="INFO">--><!-- <appender-ref ref="CONSOLE" />--><!-- <appender-ref ref="FILE" />--><!-- </logger>--><!-- 開發(fā)環(huán)境和測試環(huán)境 --><springProfile name="dev,test"><logger name="com.atguigu" level="INFO"><appender-ref ref="CONSOLE" /></logger></springProfile><!-- 生產(chǎn)環(huán)境 --><springProfile name="prod"><logger name="com.atguigu" level="ERROR"><appender-ref ref="CONSOLE" /><appender-ref ref="ROLLING_FILE" /></logger></springProfile> </configuration>

本文章參考B站 尚硅谷《尚融寶》Java微服務(wù)分布式金融項目,僅供個人學(xué)習(xí)使用,部分內(nèi)容為本人自己見解,與尚硅谷無關(guān)。

總結(jié)

以上是生活随笔為你收集整理的【金融项目】尚融宝项目(二)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。