SpringCloud——环境搭建
一、从Boot和Cloud版本选型开始说起
(1)无伤速通版
(2)详细推演版
1.2.1SpringCloud 分为上下两场
- 上篇SpringCloud
- 下篇SpringCloud Alibaba
- 上下篇没有严格的顺序要求,各自独立,截然不同
1.2.2SpringBoot 版本选择
- git源码地址:
- 官网看Boot版本:
- SpringBoot3官网:
- 通过上面官网发现,Boot官方强烈建议你使用Java17+升级到3.X以上版本
1.2.3SpringCloud 版本选择
- git源码地址:
- Cloud命名规则:
- springcloud(截至2023.12.12):
- 演变:
1.2.4SpringCloud Alibaba 版本选择
- 不要在Spring官网看SpringCloud Alibaba版本,因为Spring官网有延后情况,非SpringCloud Alibaba的最新版
- SpringCloud Alibaba官网GitHub说明:
- 毕业版本依赖关系(推荐使用):https://github.com/alibaba/spring-cloud-alibaba/wiki/%E7%89%88%E6%9C%AC%E8%AF%B4%E6%98%8E
- 版本选择:
- SpringCloud Alibaba版本:Spring Cloud Alibaba 参考文档
1.2.5本次讲解定稿版
- 版本适配匹配度,请严格依照官网
- 若同时用boot和cloud,由话事人cloud决定boot版本
二、关于Cloud各种组件的停更/升级/替换
(1)SpringCloud是什么?能干嘛?产生背景?
(2)速通版
三、微服务架构编码Base工程模块构建
(1)订单→支付,业务需求说明
(2)约定>配置>编码
(3)IDEA新建Project和Maven父工程
3.3.1微服务cloud整体聚合Maven父工程Project
(1)New Project
(2)聚合总父工程名字
(3)字符编码
(4)注解生效激活

(5)Java编译版本选17
(6)File Type过滤
3.3.2父工程POM文件内容
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.atguigu.cloud</groupId>
<artifactId>mscloudV5</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<hutool.version>5.8.22</hutool.version>
<lombok.version>1.18.26</lombok.version>
<druid.version>1.1.20</druid.version>
<mybatis.springboot.version>3.0.2</mybatis.springboot.version>
<mysql.version>8.0.11</mysql.version>
<swagger3.version>2.2.0</swagger3.version>
<mapper.version>4.2.3</mapper.version>
<fastjson2.version>2.0.40</fastjson2.version>
<persistence-api.version>1.0.2</persistence-api.version>
<spring.boot.test.version>3.1.5</spring.boot.test.version>
<spring.boot.version>3.2.0</spring.boot.version>
<spring.cloud.version>2023.0.0</spring.cloud.version>
<spring.cloud.alibaba.version>2022.0.0.0-RC2</spring.cloud.alibaba.version>
</properties>
<dependencyManagement>
<dependencies>
<!--springboot 3.2.0-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>${spring.boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--springcloud 2023.0.0-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring.cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--springcloud alibaba 2022.0.0.0-RC2-->
<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>
<!--SpringBoot集成mybatis-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>${mybatis.springboot.version}</version>
</dependency>
<!--Mysql数据库驱动8 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<!--SpringBoot集成druid连接池-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>${druid.version}</version>
</dependency>
<!--通用Mapper4之tk.mybatis-->
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper</artifactId>
<version>${mapper.version}</version>
</dependency>
<!--persistence-->
<dependency>
<groupId>javax.persistence</groupId>
<artifactId>persistence-api</artifactId>
<version>${persistence-api.version}</version>
</dependency>
<!-- fastjson2 -->
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
<version>${fastjson2.version}</version>
</dependency>
<!-- swagger3 调用方式 http://你的主机IP地址:5555/swagger-ui/index.html -->
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>${swagger3.version}</version>
</dependency>
<!--hutool-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>${hutool.version}</version>
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<optional>true</optional>
</dependency>
<!-- spring-boot-starter-test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>${spring.boot.test.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
3.3.3Maven工程落地细节复习
- dependencyManagement 是 Maven 管理依赖版本号的方式
- 通常在组织或项目最顶层的父 POM 中会出现 dependencyManagement 元素
- 使用 dependencyManagement 可让子项目引用依赖时无需显式列出版本号
- Maven 会向上查找含 dependencyManagement 元素的项目,使用其中指定的版本号
- 统一版本管理优势:
- 多个子项目引用相同依赖时,避免在各子项目中重复声明版本号
- 升级或切换依赖版本时,只需在顶层父 POM 更新,无需逐个修改子项目
- 子项目若需不同版本,单独声明版本号即可
- dependencyManagement 特性:
- 仅声明依赖,不实际引入,子项目需显式声明要使用的依赖
- 子项目不声明依赖,不会从父项目继承;声明依赖且不指定版本,才从父项目继承版本和作用域
- 子项目指定版本号时,使用子项目指定的版本
- maven中跳过单元测试
<build><!-- maven中跳过单元测试 --> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <configuration> <skip>true</skip> </configuration> </plugin> </plugins> </build>
- IDEA工具支持(推荐)
3.3.4mysql驱动说明
- mysql5:
# mysql5.7---JDBC四件套 jdbc.driverClass = com.mysql.jdbc.Driver jdbc.url= jdbc:mysql://localhost:3306/db2024?useUnicode=true&characterEncoding=UTF-8&useSSL=false jdbc.user = root jdbc.password =123456 # Maven的POM文件处理 <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.47</version> </dependency>
- mysql8:
# mysql8.0---JDBC四件套 jdbc.driverClass = com.mysql.cj.jdbc.Driver jdbc.url= jdbc:mysql://localhost:3306/db2024?characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true jdbc.user = root jdbc.password =123456 # Maven的POM <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.11</version> </dependency>
(4)Mapper4之一键生成
(1)mybatis-generator
MyBatis Generator Core – Introduction to MyBatis Generator
(2)MyBatis通用Mapper4官网
- 本次使用Mapper4
- GitHub - abel533/Mapper: Mybatis Common Mapper - Easy to use
(3)下一代:MyBatis通用Mapper5官网
GitHub - mybatis-mapper/mapper: MyBatis Mapper
(4)一键生成步骤
- SQL(db2024库t_pay支付信息表SQL):
DROP TABLE IF EXISTS `t_pay`; CREATE TABLE `t_pay` ( `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, `pay_no` VARCHAR(50) NOT NULL COMMENT '支付流水号', `order_no` VARCHAR(50) NOT NULL COMMENT '订单流水号', `user_id` INT(10) DEFAULT '1' COMMENT '用户账号ID', `amount` DECIMAL(8,2) NOT NULL DEFAULT '9.9' COMMENT '交易金额', `deleted` TINYINT(4) UNSIGNED NOT NULL DEFAULT '0' COMMENT '删除标志,默认0不删除,1删除', `create_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `update_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', PRIMARY KEY (`id`) ) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='支付交易表'; INSERT INTO t_pay(pay_no,order_no) VALUES('pay17203699','6544bafb424a'); SELECT * FROM t_pay;
- Module:
- POM:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>com.atguigu.cloud</groupId> <artifactId>mscloudV5</artifactId> <version>1.0-SNAPSHOT</version> </parent> <artifactId>mybatis_generator2024</artifactId> <properties> <maven.compiler.source>17</maven.compiler.source> <maven.compiler.target>17</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <!--Mybatis 通用mapper tk单独使用,自己独有+自带版本号--> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.13</version> </dependency> <!-- Mybatis Generator 自己独有+自带版本号--> <dependency> <groupId>org.mybatis.generator</groupId> <artifactId>mybatis-generator-core</artifactId> <version>1.4.2</version> </dependency> <!--通用Mapper--> <dependency> <groupId>tk.mybatis</groupId> <artifactId>mapper</artifactId> </dependency> <!--mysql8.0--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <!--persistence--> <dependency> <groupId>javax.persistence</groupId> <artifactId>persistence-api</artifactId> </dependency> <!--hutool--> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> </dependency> <!--lombok--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> </dependencies> <build> <resources> <resource> <directory>${basedir}/src/main/java</directory> <includes> <include>**/*.xml</include> </includes> </resource> <resource> <directory>${basedir}/src/main/resources</directory> </resource> </resources> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>3.2.0</version> <configuration> <excludes> <exclude> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </exclude> </excludes> </configuration> </plugin> <plugin> <groupId>org.mybatis.generator</groupId> <artifactId>mybatis-generator-maven-plugin</artifactId> <version>1.4.2</version> <configuration> <configurationFile>${basedir}/src/main/resources/generatorConfig.xml</configurationFile> <overwrite>true</overwrite> <verbose>true</verbose> </configuration> <dependencies> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.33</version> </dependency> <dependency> <groupId>tk.mybatis</groupId> <artifactId>mapper</artifactId> <version>4.2.3</version> </dependency> </dependencies> </plugin> </plugins> </build> </project>
- 配置:在src/main/resources路径下新建:
- config.properties
#t_pay表包名 package.name=com.atguigu.cloud # mysql8.0 jdbc.driverClass = com.mysql.cj.jdbc.Driver jdbc.url= jdbc:mysql://localhost:3306/db2024?characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true jdbc.user = root jdbc.password =123456
- generatorConfig.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd"> <generatorConfiguration> <properties resource="config.properties"/> <context id="Mysql" targetRuntime="MyBatis3Simple" defaultModelType="flat"> <property name="beginningDelimiter" value="`"/> <property name="endingDelimiter" value="`"/> <plugin type="tk.mybatis.mapper.generator.MapperPlugin"> <property name="mappers" value="tk.mybatis.mapper.common.Mapper"/> <property name="caseSensitive" value="true"/> </plugin> <jdbcConnection driverClass="${jdbc.driverClass}" connectionURL="${jdbc.url}" userId="${jdbc.user}" password="${jdbc.password}"> </jdbcConnection> <javaModelGenerator targetPackage="${package.name}.entities" targetProject="src/main/java"/> <sqlMapGenerator targetPackage="${package.name}.mapper" targetProject="src/main/java"/> <javaClientGenerator targetPackage="${package.name}.mapper" targetProject="src/main/java" type="XMLMAPPER"/> <table tableName="t_pay" domainObjectName="Pay"> <generatedKey column="id" sqlStatement="JDBC"/> </table> </context> </generatorConfiguration>
- config.properties
- 一键生成(双击插件 mybatis-generator:gererate,一键生成,生成 entity+mapper 接口 + xml 实现 SQL):
(5)Rest通用Base工程构建
3.5.1工程V1
(1)cloud-provider-payment8001微服务提供者支付Module模块
一、微服务小口诀
- 建module
- 改POM
- 写YML
- 主启动
- 业务类
二、步骤
- 建module
- 改POM
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>com.atguigu.cloud</groupId> <artifactId>mscloudV5</artifactId> <version>1.0-SNAPSHOT</version> </parent> <artifactId>cloud-provider-payment8001</artifactId> <properties> <maven.compiler.source>17</maven.compiler.source> <maven.compiler.target>17</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <!--SpringBoot通用依赖模块--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <!--SpringBoot集成druid连接池--> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> </dependency> <!-- Swagger3 调用方式 http://你的主机IP地址:5555/swagger-ui/index.html --> <dependency> <groupId>org.springdoc</groupId> <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId> </dependency> <!--mybatis和springboot整合--> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> </dependency> <!--Mysql数据库驱动8 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <!--persistence--> <dependency> <groupId>javax.persistence</groupId> <artifactId>persistence-api</artifactId> </dependency> <!--通用Mapper4--> <dependency> <groupId>tk.mybatis</groupId> <artifactId>mapper</artifactId> </dependency> <!--hutool--> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> </dependency> <!-- fastjson2 --> <dependency> <groupId>com.alibaba.fastjson2</groupId> <artifactId>fastjson2</artifactId> </dependency> <!--lombok--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.28</version> <scope>provided</scope> </dependency> <!--test--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>3.2.0</version> </plugin> </plugins> </build> </project>
- 写YML
server: port: 8001 # ==========applicationName + druid-mysql8 driver=================== spring: application: name: cloud-payment-service datasource: type: com.alibaba.druid.pool.DruidDataSource driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/db2024?characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true username: root password: 123456 # ========================mybatis=================== mybatis: mapper-locations: classpath:mapper/*.xml type-aliases-package: com.atguigu.cloud.entities configuration: map-underscore-to-camel-case: true
- 主启动(修改Main类名为Main8001)
- 业务类
- 将之前一键生成的代码直接拷贝进8001模块
- entities:
- 主实体Pay
- 传递数值PayDTO
- mapper:
- Mapper接口PayMapper
- 映射文件PayMapper.xml(第一步:src/main/resources路径下,新建文件夹mapper;第二步:拷贝PayMapper.xml进上一步的mapper文件夹)
- service:
- 服务接口PayService
- 实现类PayServiceImpl
package com.atguigu.cloud.service; import com.atguigu.cloud.entities.Pay; import com.atguigu.cloud.mapper.PayMapper; import jakarta.annotation.Resource; import org.springframework.stereotype.Service; import java.util.List; @Service public class PayServiceImpl implements PayService { @Resource private PayMapper payMapper; @Override public int add(Pay pay) { return payMapper.insertSelective(pay); } @Override public int delete(Integer id) { return payMapper.deleteByPrimaryKey(id); } @Override public int update(Pay pay) { return payMapper.updateByPrimaryKeySelective(pay); } @Override public Pay getById(Integer id) { return payMapper.selectByPrimaryKey(id); } @Override public List<Pay> getAll() { return payMapper.selectAll(); } }
- 服务接口PayService
- controller:
package com.atguigu.cloud.controller; import com.atguigu.cloud.entities.Pay; import com.atguigu.cloud.entities.PayDTO; import com.atguigu.cloud.service.PayService; import jakarta.annotation.Resource; import org.springframework.beans.BeanUtils; import org.springframework.web.bind.annotation.*; @RestController public class PayController { @Resource private PayService payService; @PostMapping(value = "/pay/add") public String addPay(@RequestBody Pay pay){ System.out.println(pay.toString()); int i = payService.add(pay); return "成功插入记录,返回值:" + i; } @DeleteMapping(value = "/pay/del/{id}") public Integer deletePay(@PathVariable("id") Integer id){ return payService.delete(id); } @PutMapping(value = "/pay/update") public String updatePay(@RequestBody PayDTO payDTO){ Pay pay = new Pay(); BeanUtils.copyProperties(payDTO,pay); int i = payService.update(pay); return "成功修改记录,返回值:" + i; } @GetMapping(value = "/pay/get/{id}") public Pay getById(@PathVariable("id") Integer id){ return payService.getById(id); } }
三、测试
- PostMan:
- Swagger:
- 常用注解:
- 注解列表:
- Controller:
- 方法:
- entity或DTO:
- 注解列表:
- 含分组迭代的Config配置类(Swagger3Config):
- 调用方式:
- 常用注解:
(2)上述模块还有哪些问题
一、时间格式问题
二、Java如何设计API接口实现统一格式返回
- 影响前端/小程序/app等交互体验和开发(1)void(2)数值(3)String(4)对象entity(5)Map
- 看看目前程序返回值情况:故意写了多种返回类值
三、全局异常接入返回的标准格式
有统一返回值+全局统一异常
3.5.2工程V2(cloud-provider-payment8001改进版)
一、解决:时间格式问题

二、解决:返回统一值
(1)思路
- 定义返回标准格式,3大标配
- code状态值:由后端同意定义各种返回结果的状态码
- message描述:本次接口调用的结果描述
- data数据:本次返回的数据
- 扩展:timestamp,接口调用时间
(2)步骤
- 新建枚举类ReturnCodeEnum(举值、构造、遍历)
- HTTP请求返回的状态码
- ReturnDodeEnum
package com.atguigu.cloud.resp; import lombok.Getter; import java.util.Arrays; @Getter public enum ReturnCodeEnum { //1.举值 /**操作失败**/ RC999("999","操作XXX失败"), /**操作成功**/ RC200("200","success"), /**服务降级**/ RC201("201","服务开启降级保护,请稍后再试!"), /**热点参数限流**/ RC202("202","热点参数限流,请稍后再试!"), /**系统规则不满足**/ RC203("203","系统规则不满足要求,请稍后再试!"), /**授权规则不通过**/ RC204("204","授权规则不通过,请稍后再试!"), /**access_denied**/ RC403("403","无访问权限,请联系管理员授予权限"), /**access_denied**/ RC401("401","匿名用户访问无权限资源时的异常"), RC404("404","404页面找不到的异常"), /**服务异常**/ RC500("500","系统异常,请稍后重试"), RC375("375","数学运算异常,请稍后重试"), INVALID_TOKEN("2001","访问令牌不合法"), ACCESS_DENIED("2003","没有权限访问该资源"), CLIENT_AUTHENTICATION_FAILED("1001","客户端认证失败"), USERNAME_OR_PASSWORD_ERROR("1002","用户名或密码错误"), BUSINESS_ERROR("1004","业务逻辑异常"), UNSUPPORTED_GRANT_TYPE("1003", "不支持的认证模式"); //2.构造 private final String code; private final String message; ReturnCodeEnum(String code, String message) { this.code = code; this.message = message; } //3.遍历 //3.1传统版 public static ReturnCodeEnum getReturnCodeEnumV1(String code){ for (ReturnCodeEnum element : ReturnCodeEnum.values()) { if (element.getCode().equalsIgnoreCase(code)) { return element; } } return null; } //3.2Stream流式计算版 public static ReturnCodeEnum getReturnCodeEnumV2(String code){ return Arrays.stream(ReturnCodeEnum.values()).filter(x -> x.getCode().equalsIgnoreCase(code)).findFirst().orElse(null); } }
- HTTP请求返回的状态码
- 新建统一定义返回对象ResultData
package com.atguigu.cloud.resp; import lombok.Data; import lombok.experimental.Accessors; @Data @Accessors(chain = true) public class ResultData<T> { private String code; private String message; private T data; private long timestamp; public ResultData() { this.timestamp = System.currentTimeMillis(); } public static <T> ResultData<T> success(T data){ ResultData<T> resultData = new ResultData<>(); resultData.setCode(ReturnCodeEnum.RC200.getCode()); resultData.setMessage(ReturnCodeEnum.RC200.getMessage()); resultData.setData(data); return resultData; } public static <T> ResultData<T> fail(String code,String message){ ResultData<T> resultData = new ResultData<>(); resultData.setCode(code); resultData.setMessage(message); resultData.setData(null); return resultData; } }
(3)修改PayController
package com.atguigu.cloud.controller;
import com.atguigu.cloud.entities.Pay;
import com.atguigu.cloud.entities.PayDTO;
import com.atguigu.cloud.resp.ResultData;
import com.atguigu.cloud.service.PayService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;
@RestController
@Tag(name = "支付微服务模块",description = "支付CRUD")
public class PayController {
@Resource
private PayService payService;
@PostMapping(value = "/pay/add")
@Operation(summary = "新增",description = "新增支付流水方法,json串做参数")
public ResultData<String> addPay(@RequestBody Pay pay){
System.out.println(pay.toString());
int i = payService.add(pay);
return ResultData.success("成功插入记录,返回值:"+i);
}
@DeleteMapping(value = "/pay/del/{id}")
@Operation(summary = "删除",description = "删除支付流水方法")
public ResultData<Integer> deletePay(@PathVariable("id") Integer id){
int i = payService.delete(id);
return ResultData.success(i);
}
@PutMapping(value = "/pay/update")
@Operation(summary = "修改",description = "修改支付流水方法")
public ResultData<String> updatePay(@RequestBody PayDTO payDTO){
Pay pay = new Pay();
BeanUtils.copyProperties(payDTO,pay);
int i = payService.update(pay);
return ResultData.success("成功插入记录,返回值:" + i);
}
@GetMapping(value = "/pay/get/{id}")
@Operation(summary = "按照ID查流水",description = "查询支付流水方法")
public ResultData<Pay> getById(@PathVariable("id") Integer id){
Pay pay = payService.getById(id);
return ResultData.success(pay);
}
}
(4)测试
(5)结论
通过ResultData.success()对返回结果进行包装后返回给前端
(6)查询方法写个bug
三、解决:全局异常接入返回的标注格式
(1)为什么需要全局异常处理器
- 不用再手写try...catch
- 当然,如果非要try...catch也是可以的
(2)新建全局异常类GlobalExceptionHandler
package com.atguigu.cloud.exp;
import com.atguigu.cloud.resp.ResultData;
import com.atguigu.cloud.resp.ReturnCodeEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(RuntimeException.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public ResultData<String> exception(Exception e){
System.out.println("----come in GlobalExceptionHandler");
log.error("全局异常信息exception:{}",e.getMessage(),e);
return ResultData.fail(ReturnCodeEnum.RC500.getCode(), e.getMessage());
}
}
(3)修改Controller


(6)引入微服务理念,从这里开始
3.6.1订单微服务80如何才能调用到支付微服务8001?
3.6.2cloud-consumer-order80微服务调用者订单Module模块
- 建cloud-consumer-order80
- 改POM
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>com.atguigu.cloud</groupId> <artifactId>mscloudV5</artifactId> <version>1.0-SNAPSHOT</version> </parent> <artifactId>cloud-consumer-order80</artifactId> <properties> <maven.compiler.source>17</maven.compiler.source> <maven.compiler.target>17</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <!--web + actuator--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <!--lombok--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <!--hutool-all--> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> </dependency> <!--fastjson2--> <dependency> <groupId>com.alibaba.fastjson2</groupId> <artifactId>fastjson2</artifactId> </dependency> <!-- swagger3 调用方式 http://你的主机IP地址:5555/swagger-ui/index.html --> <dependency> <groupId>org.springdoc</groupId> <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
- 写YML
server: port: 80
- 主启动(修改Main类名为Main80)
- 业务类
- entities:传递数值PayDTO
- ResultData统一返回值也从8001拷贝进来
- RestTemplate
RestTemplate (Spring Framework 6.0.11 API)
- config配置类
package com.com.atguigu.cloud.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.client.RestTemplate; @Configuration public class RestTemplateConfig { @Bean public RestTemplate restTemplate(){ return new RestTemplate(); } }
- controller
package com.atguigu.cloud.controller; import com.atguigu.cloud.entities.PayDTO; import com.atguigu.cloud.resp.ResultData; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.RestTemplate; @RestController public class OrderController { public static final String PaymentSrv_URL = "http://localhost:8001"; @Autowired private RestTemplate restTemplate; @GetMapping("/consumer/pay/add") public ResultData addOrder(PayDTO payDTO){ return restTemplate.postForObject(PaymentSrv_URL + "/pay/add", payDTO, ResultData.class); } @GetMapping("/consumer/pay/get/{id}") public ResultData getPayInfo(@PathVariable("id") Integer id){ return restTemplate.getForObject(PaymentSrv_URL + "/pay/get/" + id, ResultData.class); } }
- postman测试
- 关于RestTemplate:
- 使用说明:
- getForObject方法/getForEntity方法
- postForObject方法/postForEntity方法
- GET请求方法
- POST请求方法
- 使用说明:
3.6.3工程重构
(1)观察问题
(2)新建Module
- cloud-api-commons
- 对外暴露通用的组件/api/接口/工具类等
(3)改POM
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.atguigu.cloud</groupId>
<artifactId>mscloudV5</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>cloud-api-commons</artifactId>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!--SpringBoot通用依赖模块-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!--hutool-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
</dependency>
</dependencies>
</project>
(4)entities 
(5)全局异常类,可加可不加
(6)maven命令clean install
(7)订单80和支付8001分别改造
- 删除各自的原先有过的entities和统一返回体等内容
- 各自粘贴POM内容(在原来的POM文件的基础上,引入自己定义的api通用包)
- 80
- 8001
<!-- 引入自己定义的api通用包 --> <dependency> <groupId>com.atguigu.cloud</groupId> <artifactId>cloud-api-commons</artifactId> <version>1.0-SNAPSHOT</version> </dependency>
(8)postman测试
3.6.4目前工程样图
截止到目前,没有引入任何SpringCloud相关的内容