Spring Boot 优雅实现统一数据返回格式+统一异常处理+统一日志处理

        在我们的项目开发中,我们都会对数据返回格式进行统一的处理,这样可以方便前端人员取数据,当然除了正常流程的数据返回格式需要统一以外,我们也需要对异常的情况进行统一的处理,以及项目必备的日志。

1. 统一返回格式

        在项目开发中返回的是json格式的数据,也就是统一json数据返回格式,一般情况下返回数据的基本格式包含是否成功、响应状态码、返回的消息、以及返回的数据。格式如下:

{"success": 布尔,      // 是否成功"code": 数字,         // 响应状态码"message": 字符串,    // 返回的消息"data": {}           //  放置响应的数据
}

1.1 添加枚举类

        该类定义了以上统一格式的前三部分:是否成功、响应状态码、返回的消息;可自行根据项目需要进行后续的添加或者删改。

创建一个result包,下面放置ResultCodeEnum枚举类

/*** 状态码**/
public enum ResultCodeEnum {SUCCESS(true, 20000, "成功"),UNKNOWN_REASON(false, 20001, "未知错误");private final Boolean success;private final Integer code;private final String message;ResultCodeEnum(Boolean success, Integer code, String message) {this.success = success;this.code = code;this.message = message;}public Boolean getSuccess() {return success;}public Integer getCode() {return code;}public String getMessage() {return message;}@Overridepublic String toString() {return "ResultCodeEnum{" + "success=" + success + ", code=" + code + ", message='" + message + '\'' + '}';}
}

1.2 添加统一返回格式的类

该类是用来和前端交互的类,定义的就是本文开头所说的格式

在result包下创建一个统一返回格式的类R

/*** 统一返回格式类**/
public class R {/*** 是否成功*/private Boolean success;/*** 状态码*/private Integer code;/*** 返回的消息*/private String message;/*** 放置响应的数据*/private Map<String, Object> data = new HashMap<>();public 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_REASON.getSuccess());r.setCode(ResultCodeEnum.UNKNOWN_REASON.getCode());r.setMessage(ResultCodeEnum.UNKNOWN_REASON.getMessage());return r;}public static R setResult(ResultCodeEnum resultCodeEnum) {R r = new R();r.setSuccess(resultCodeEnum.getSuccess());r.setCode(resultCodeEnum.getCode());r.setMessage(resultCodeEnum.getMessage());return r;}public R success(Boolean success) {this.setSuccess(success);return this;}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;}/** 以下是get/set方法,如果项目有集成lombok可以使用@Data注解代替 */public Boolean getSuccess() {return success;}public void setSuccess(Boolean success) {this.success = success;}public Integer getCode() {return code;}public void setCode(Integer code) {this.code = code;}public String getMessage() {return message;}public void setMessage(String message) {this.message = message;}public Map<String, Object> getData() {return data;}public void setData(Map<String, Object> data) {this.data = data;}
}

 1.3 测试

/*** 测试控制器**/
@RestController
@RequestMapping("testR")
public class TestController {@GetMapping("ok")public R testOk() {Map<String, Object> data = new HashMap<>();data.put("name", "李太白");return R.ok().data(data);}
}

        可以看到格式是正确的,只要我们返回数据的时候使用R这个类返回就行了,不过有一种情况,就是当我们代码中抛出异常之后返回的格式就不是这样子了,下面我演示一下在代码中添加int a = 1/0的语句,肯定导致抛异常的; 

/*** 测试控制器**/
@RestController
@RequestMapping("testR")
public class TestController {@GetMapping("ok")public R testOk() {int a = 1/0;Map<String, Object> data = new HashMap<>();data.put("name", "李太白");return R.ok().data(data);}
}

        可以发现返回的格式已经不是我们所需要的格式了,这种情况会给前端人员带来不必要的麻烦,所以我们也需要对异常情况进行统一的格式处理; 

2. 统一异常处理

        经过上面的演示,相信你已经明白我们为什么需要进行统一的异常处理了,当然处理统一的异常处理以外我们在开发项目中也会主动的抛出异常,像这种情况我们需要配合自定义异常来完成;

2.1 添加统一异常处理器

创建一个handler包,在该包下面添加GlobalExceptionHandler类

/*** 统一异常处理* ControllerAdvice注解的含义是当异常抛到controller层时会拦截下来*/
@ControllerAdvice
public class GlobalExceptionHandler {/*** 使用ExceptionHandler注解声明处理Exception异常**/@ResponseBody@ExceptionHandler(Exception.class)public R exception(Exception e) {// 控制台打印异常e.printStackTrace();// 返回错误格式信息return R.error();}}

2.2 测试统一异常处理

        可以看到现在出现异常之后返回的格式已经是我们所需要的格式了,如果我们想让这个错误信息更加明确,我们可以通过添加自定义异常来实现。

2.3 添加自定义异常类

新建exception包,在该包下添加自定义异常类

/*** 测试自定义异常类* 需要继承运行时异常RuntimeException*/
public class TestException extends RuntimeException {private Integer code;public TestException(ResultCodeEnum resultCodeEnum) {// 调用父类的方法添加信息super(resultCodeEnum.getMessage());this.code = resultCodeEnum.getCode();}public Integer getCode() {return code;}
}

 2.4 在统一异常处理类GlobalExceptionHandler中添加一个自定义异常的处理

/*** 统一异常处理* ControllerAdvice注解的含义是当异常抛到controller层时会拦截下来*/
@ControllerAdvice
public class GlobalExceptionHandler {/*** 使用ExceptionHandler注解声明处理Exception异常**/@ResponseBody@ExceptionHandler(Exception.class)public R exception(Exception e) {// 控制台打印异常e.printStackTrace();// 返回错误格式信息return R.error();}/*** 使用ExceptionHandler注解声明处理TestException异常**/@ResponseBody@ExceptionHandler(TestException.class)public R exception(TestException e) {// 控制台打印异常e.printStackTrace();// 返回错误格式信息return R.error().message(e.getMessage()).code(e.getCode());}}

 2.5 测试自定义异常

在枚举类中添加一个状态信息

TEST_NUMBER(false, 500, "计算错误");
/*** 测试控制器**/
@RestController
@RequestMapping("testR")
public class TestController {@GetMapping("ok")public R testOk() {try{int a = 1/0;}catch{throw new TestException(ResultCodeEnum.TEST_NUMBER);    }Map<String, Object> data = new HashMap<>();data.put("name", "李太白");return R.ok().data(data);}
}

3. 统一日志处理 

为了更方便我们进行错误的调式,一般会在项目中集成日志。

3.1 添加日志配置文件

在resources下添加日志的配置,文件名必须是logback-spring.xml

以下配置一般不需要修改,要改的话也只是修改日志的输出目录

<property name="log.path" value="D:/javaWeb/log" />

value就是日志的输出位置

<?xml version="1.0" encoding="UTF-8"?>
<configuration  scan="true" scanPeriod="10 seconds"><!-- 日志级别从低到高分为TRACE < DEBUG < INFO < WARN < ERROR < FATAL,如果设置为WARN,则低于WARN的信息都不会输出 --><!-- scan:当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true --><!-- scanPeriod:设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。 --><!-- debug:当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。 --><contextName>logback</contextName><!-- name的值是变量的名称,value的值时变量定义的值。通过定义的值会被插入到logger上下文中。定义变量后,可以使“${}”来使用变量。 --><property name="log.path" value="D:/javaWeb/log" /><!--控制台日志格式:彩色日志--><!-- magenta:洋红 --><!-- boldMagenta:粗红--><!-- cyan:青色 --><!-- white:白色 --><!-- magenta:洋红 --><property name="CONSOLE_LOG_PATTERN"value="%yellow(%date{yyyy-MM-dd HH:mm:ss}) |%highlight(%-5level) |%blue(%thread) |%blue(%file:%line) |%green(%logger) |%cyan(%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"><filter class="ch.qos.logback.classic.filter.ThresholdFilter"><!--日志级别--><level>DEBUG</level></filter><encoder><!--日志格式--><Pattern>${CONSOLE_LOG_PATTERN}</Pattern><!--日志字符集--><charset>${ENCODING}</charset></encoder></appender><!--输出到文件--><appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"><!--日志过滤器:此日志文件只记录INFO级别的--><filter class="ch.qos.logback.classic.filter.LevelFilter"><level>INFO</level><onMatch>ACCEPT</onMatch><onMismatch>DENY</onMismatch></filter><!-- 正在记录的日志文件的路径及文件名 --><file>${log.path}/log_info.log</file><encoder><pattern>${FILE_LOG_PATTERN}</pattern><charset>${ENCODING}</charset></encoder><!-- 日志记录器的滚动策略,按日期,按大小记录 --><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><!-- 每天日志归档路径以及格式 --><fileNamePattern>${log.path}/info/log-info-%d{yyyy-MM-dd}.%i.log</fileNamePattern><timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"><maxFileSize>500MB</maxFileSize></timeBasedFileNamingAndTriggeringPolicy><!--日志文件保留天数--><maxHistory>15</maxHistory></rollingPolicy></appender><appender name="WARN_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"><!-- 日志过滤器:此日志文件只记录WARN级别的 --><filter class="ch.qos.logback.classic.filter.LevelFilter"><level>WARN</level><onMatch>ACCEPT</onMatch><onMismatch>DENY</onMismatch></filter><!-- 正在记录的日志文件的路径及文件名 --><file>${log.path}/log_warn.log</file><encoder><pattern>${FILE_LOG_PATTERN}</pattern><charset>${ENCODING}</charset> <!-- 此处设置字符集 --></encoder><!-- 日志记录器的滚动策略,按日期,按大小记录 --><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><fileNamePattern>${log.path}/warn/log-warn-%d{yyyy-MM-dd}.%i.log</fileNamePattern><timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"><maxFileSize>100MB</maxFileSize></timeBasedFileNamingAndTriggeringPolicy><!--日志文件保留天数--><maxHistory>15</maxHistory></rollingPolicy></appender><appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"><!-- 日志过滤器:此日志文件只记录ERROR级别的 --><filter class="ch.qos.logback.classic.filter.LevelFilter"><level>ERROR</level><onMatch>ACCEPT</onMatch><onMismatch>DENY</onMismatch></filter><!-- 正在记录的日志文件的路径及文件名 --><file>${log.path}/log_error.log</file><encoder><pattern>${FILE_LOG_PATTERN}</pattern><charset>${ENCODING}</charset> <!-- 此处设置字符集 --></encoder><!-- 日志记录器的滚动策略,按日期,按大小记录 --><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><fileNamePattern>${log.path}/error/log-error-%d{yyyy-MM-dd}.%i.log</fileNamePattern><timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"><maxFileSize>100MB</maxFileSize></timeBasedFileNamingAndTriggeringPolicy><!--日志文件保留天数--><maxHistory>15</maxHistory></rollingPolicy></appender><!--开发环境--><springProfile name="dev"><!--可以灵活设置此处,从而控制日志的输出--><root level="INFO"><appender-ref ref="CONSOLE" /><appender-ref ref="INFO_FILE" /><appender-ref ref="WARN_FILE" /><appender-ref ref="ERROR_FILE" /></root></springProfile><!--生产环境--><springProfile name="pro"><root level="ERROR"><appender-ref ref="ERROR_FILE" /></root></springProfile></configuration>

3.2 添加application.properties配置

配置文件需要设置下环境,需要跟日志配置文件中的<springProfile name="dev">对应上,不然不生效

# 设置环境
spring.profiles.active=dev

3.3 修改GlobalExceptionHandler类

/*** 统一异常处理* ControllerAdvice注解的含义是当异常抛到controller层时会拦截下来*/
@ControllerAdvice
public class GlobalExceptionHandler {/*** 打印日志 * 如果项目有集成lombok可使用@Slf4j注解代替*/private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);/*** 使用ExceptionHandler注解声明处理Exception异常**/@ResponseBody@ExceptionHandler(Exception.class)public R exception(Exception e) {// 控制台打印异常log.error(e.getMessage());// 返回错误格式信息return R.error();}/*** 使用ExceptionHandler注解声明处理TestException异常**/@ResponseBody@ExceptionHandler(TestException.class)public R exception(TestException e) {// 控制台打印异常log.error(e.getMessage());// 返回错误格式信息return R.error().message(e.getMessage()).code(e.getCode());}}

3.4 测试效果

日志生效了,而且在我们的D盘javaWeb目录下也有对应的日志文件了

 我们可以进一步的完善下,将日志堆栈信息输出到文件

3.5 定义工具类

 新建utils包,在该包下添加ExceptionUtils类

/*** 日志堆栈信息输出到文件工具类**/
public class ExceptionUtils {public static String getMessage(Exception e) {StringWriter sw = null;PrintWriter pw = null;try {sw = new StringWriter();pw = new PrintWriter(sw);// 将出错的栈信息输出到printWriter中e.printStackTrace(pw);pw.flush();sw.flush();} finally {if (sw != null) {try {sw.close();} catch (IOException e1) {e1.printStackTrace();}}if (pw != null) {pw.close();}}return sw.toString();}
}

3.6 再修改GlobalExceptionHandler类

/*** 统一异常处理* ControllerAdvice注解的含义是当异常抛到controller层时会拦截下来*/
@ControllerAdvice
public class GlobalExceptionHandler {/*** 打印日志 如果项目有集成lombok可使用@Slf4j注解代替*/private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);/*** 使用ExceptionHandler注解声明处理Exception异常**/@ResponseBody@ExceptionHandler(Exception.class)public R exception(Exception e) {// 控制台打印异常  借助工具类将错误堆栈输出到文件log.error(ExceptionUtils.getMessage(e));// 返回错误格式信息return R.error();}/*** 使用ExceptionHandler注解声明处理TestException异常**/@ResponseBody@ExceptionHandler(TestException.class)public R exception(TestException e) {// 控制台打印异常   借助工具类将错误堆栈输出到文件log.error(ExceptionUtils.getMessage(e));// 返回错误格式信息return R.error().message(e.getMessage()).code(e.getCode());}}

以上是根据一位博主的文章编写的,现在找不到那篇文章了,还请见谅。

这篇文章就到这里了,下次见!

🥇原创不易,还希望各位大佬支持一下!

👍点赞,你的认可是我创作的动力 !

🌟收藏,你的青睐是我努力的方向!

✏️评论,你的意见是我进步的财富!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/632810.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux 安装ffmpeg

一、下载 ffmpeg-4.3.1 下载地址&#xff1a;链接&#xff1a;https://pan.baidu.com/s/1xbkpHDfIWSCbHFGJJHSQcA 提取码&#xff1a;3eil 二、上传到服务器root目录下 三、给ffmpeg-4.3.1 读写权限 chmod -R 777 /root/ffmpeg-4.3.1 四、创建软连接 1.进入/bin 目录 2.…

用js做个转盘

样式 <style>.wheel {position: relative;width: 400px;height: 400px;border: 1px solid black;border-radius: 50%;overflow: hidden;margin: auto;}.slice {position: absolute;left: 0;top: 0;width: 0;height: 0;border: 200px solid red;/* border-width: 100px 10…

Spring Boot整合Druid(druid 和 druid-spring-boot-starter)

引言 在现代的Web应用开发中&#xff0c;高性能的数据库连接池是确保应用稳定性和响应性的关键因素之一。Druid是一个开源的高性能数据库连接池&#xff0c;具有强大的监控和统计功能&#xff0c;能够在Spring Boot应用中提供出色的数据库连接管理。本文将研究在Spring Boot中…

Macos flatter(用于快速LLL)本地编译安装(解决安装过程各种疑难杂症)

flatter是一个开源项目&#xff0c;能大大提高LLL的速度&#xff0c;项目提供的安装文档适用于Ubuntu&#xff0c;但是在macos上安装&#xff0c;总会遇到各种各样的问题&#xff0c;这里记录下所踩坑&#xff0c;帮助大家快速在macos上安装flatter。 文章目录 1.安装依赖库&am…

Python使用HTTP代理进行网络测试和监控

在Python中&#xff0c;HTTP代理不仅可以用于网络爬虫&#xff0c;还可以用于网络测试和监控。通过使用HTTP代理&#xff0c;我们可以模拟不同的网络环境&#xff0c;测试应用程序在不同情况下的性能和稳定性。此外&#xff0c;我们还可以使用HTTP代理来监控网络流量和性能指标…

C语言编译和链接

翻译环境和运行环境 在ANSI C的任何一种实现中&#xff0c;存在两个不同的环境 .第一种是翻译环境&#xff0c;在这个环境中源代码被转换为可执行的机器指令 .第二种是执行环境&#xff0c;它用于实际执行代码 翻译环境 翻译环境是由编译和链接两个大过程组成&#xff0c;而…

npm run dev 启动vue的时候指定端口

使用的是 Vue CLI 来创建和管理 Vue 项目&#xff0c; 可以通过设置 --port 参数来指定启动的端口号。以下是具体的步骤&#xff1a; 打开命令行终端 进入您的 Vue 项目目录 运行以下命令&#xff0c;通过 --port 参数指定端口号&#xff08;例如&#xff0c;这里设置端口号…

mybatisPlus注解将List集合插入到数据库

1.maven引入依赖&#xff08;特别注意版本&#xff0c;3.1以下不支持&#xff09; <dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.4.3.1</version></dependency&g…

自建服务器如何备案?

随着互联网的普及和发展&#xff0c;越来越多的人开始考虑自建服务器。然而&#xff0c;在中国大陆地区&#xff0c;自建服务器需要进行备案。本文将介绍自建服务器备案的流程、所需材料以及注意事项。 一、备案流程 确定备案地区 根据《中华人民共和国计算机信息网络国际联网…

【python】—— 集合

目录 &#xff08;一&#xff09;集合的概念 &#xff08;二&#xff09;集合的使用 2.1 集合的创建 2.2 集合元素的唯一性 2.3 集合的操作 2.3.1 并集 2.3.2 交集 2.3.3 差集 2.3.4 补集 2.4 遍历集合 2.5 其他集合操作 2.5.1 添加元素 2.5.2 移除元素 2.5.3 清…

【Alibaba工具型技术系列】「EasyExcel技术专题」实战技术针对于项目中常用的Excel操作指南

这里写目录标题 EasyExcel教程Maven依赖 EasyExcel API分析介绍EasyExcel 注解通用参数ReadWorkbook&#xff08;理解成excel对象&#xff09;参数ReadSheet&#xff08;就是excel的一个Sheet&#xff09;参数注解参数通用参数 WriteWorkbook&#xff08;理解成excel对象&#…

冒泡排序-BubbleSort

1、基本思路 从数组的左边开始&#xff0c;比较两个元素的大小&#xff0c;当左边大于右边时&#xff0c;更换左右元素位置&#xff0c;否则不改变&#xff1b;接着向右移动一步&#xff0c;比较第二个元素和第三个元素的大小&#xff0c;重复上述操作&#xff0c;直到最后一个…

为什么 Golang Fasthttp 选择使用 slice 而非 map 存储请求数据

文章目录 Slice vs Map&#xff1a;基本概念内存分配和性能Fasthttp 中的 SliceMap性能优化的深层原因HTTP Headers 的特性CPU 预加载特性 结论 Fasthttp 是一个高性能的 Golang HTTP 框架&#xff0c;它在设计上做了许多优化以提高性能。其中一个显著的设计选择是使用 slice 而…

Ubuntu开机停在Grub命令行以及启动后进入emergency模式的解决方法

主机上两个硬盘&#xff0c;本来都是Ubutun系统&#xff0c;然后将其中一个重装为windows系统&#xff0c;结果另外一个硬盘的Ubutun启动不了 首先会卡在grub命令行界面&#xff0c;类似下面这样&#xff1a; 这种情况往往是 GRUB 的系统文件或者配置文件损坏了&#xff0c;但…

基于麻雀优化算法SSA的CEEMDAN-BiLSTM-Attention的预测模型

往期精彩内容&#xff1a; 时序预测&#xff1a;LSTM、ARIMA、Holt-Winters、SARIMA模型的分析与比较-CSDN博客 风速预测&#xff08;一&#xff09;数据集介绍和预处理-CSDN博客 风速预测&#xff08;二&#xff09;基于Pytorch的EMD-LSTM模型-CSDN博客 风速预测&#xff…

Android: alarm定时很短时,比如500ms,测试执行mPowerManager.forceSuspend()后,系统不会suspend

参考文档&#xff1a; https://blog.csdn.net/weixin_35691921/article/details/124961404 Android: alarm定时很短时&#xff0c;比如500ms&#xff0c;然后执行mPowerManager.forceSuspend()后&#xff0c;系统不会suspend&#xff0c;原因分析&#xff1a; static int ala…

【iOS】——基于Vision Kit框架实现图片文字识别

文章目录 前言一、文本识别的分类二、实现步骤1.导入Vision Kit框架2.创建请求处理器3.在请求处理器中设置文字识别功能4.将图片添加到请求处理器中5.发起文字识别请求6.处理识别结果 三、运行结果测试1.纯英文环境2.中英文混合环境 前言 根据苹果的官方文档&#xff0c;Visio…

【React】脚手架创建项目

文章目录 创建React项目目录结构分析了解PWA脚手架中的webpack 创建React项目 ◼ 创建React项目的命令如下&#xff1a; ​  注意&#xff1a;项目名称不能包含大写字母 ​  另外还有更多创建项目的方式&#xff0c;可以参考GitHub的readme 命令&#xff1a; create-rea…

NRF52832跟NRF52840性能区别 高端蓝牙智能手环穿戴应用

nRF52840可以说是nRF52832的超强升级版&#xff0c;虽然同样是蓝牙5.0&#xff0c;但是整体稳定性和性能上的提升却相差甚远&#xff0c;下面为大家简单讲解下NRF52832和NRF52840的性能上的区别&#xff01; 先说说共同点&#xff1a;这两款芯片都支持蓝牙5.0&#xff0c;MCU也…

谷粒商城篇章8 ---- P236-P247 ---- 购物车【分布式高级篇五】

目录 1 环境搭建 1.1 新建购物车服务模块gulimall-cart 1.2 购物车服务相关配置 1.2.1 pom.xml 1.2.2 yml配置 1.2.2.1 application.yml配置 1.2.2.2 bootstrap.yml配置 1.2.3 主类 1.3 SwitchHosts增加配置 1.4 网关配置 1.5 整合SpringSession 1.5.1 session数据…