当前位置: 首页 > news >正文

3.微服务架构编码Base工程模块构建

目录

一、业务需求

二、约定|配置|编码

Maven父工程步骤

1.New Project

2.聚合总父工程名字

3.字符编码

4.注解生效激活

5.java编译版本选17

6.File Type过滤

7.父工程POM文件内容

Maven工程落地细节复习

Maven中的DependencyManagement和Dependencies

maven中跳过单元测试

mysql驱动说明

Mysql5配置与驱动

Mysql8配置与驱动

三、Mapper4之一键生成

一键生成步骤

1.SQL

2.Module

3.POM

4.配置路径

config.properties

generatorConfig.xml 配置内容

一键生成

四、Rest通用Base工程构建

基础工程

1.cloud-provider-payment8001微服务提供者支付Module模块

微服务口诀

实现步骤

1.建module

2.改POM

3.写YML

4.主启动(修改Main类名Main8001)

5.业务类

代码测试

PostMan

Swagger3

工程代码优化

解决:时间格式问题

解决:统一返回值

思路

步骤

1.新建枚举类ReturnCodeEnum

2.新建统一定义返回对象ResultData

3.修改PayController

测试

结论

查询方法写个bug

解决:全局异常接入返回的标准格式

1.新建全局异常类GlobalExceptionHandler

2.添加全局异常进行测试

3.单独异常抛出处理

4.访问地址:http://localhost:8001/pay/error

5.修改Controller

6.基础项目优化结束以下是工程目录

五、引入微服务理念,从这里开始

cloud-consumer-order80微服务调用者订单Module模块

1.建模块 cloud-consumer-order80

2.修改POM

3. 编写YML

4.主启动类编写

5.业务类

5.1 entities-传递数值PayDTO 

5.2 ResultData同意返回值从8001拷贝即可

5.3 RestTemplate

5.4 config 配置类

5.5 controller(参数可以不添加@RequestBody)

6. postman测试

7. 多模块启动类切换设置

工程重构

1.系统中有重复部分,重构

2.新建 cloud-api-commons Module

3.修改 cloud-api-commons模块POM

4.公用代码统一管理

5.cloud-api-commons模块打包

6.订单80和支付8001模块分别改造

7.重构后的工程目录


一、业务需求

业务需求说明:下订单,调用支付

1 先做一个通用boot微服务

2 逐步挨个引入cloud组件纳入微服务支撑体系

二、约定|配置|编码

IDEA新建Project和Maven父工程

微服务cloud整体聚合Maven父工程Project

Maven父工程步骤

1.New Project

2.聚合总父工程名字

3.字符编码

4.注解生效激活

5.java编译版本选17

6.File Type过滤

*.idea
*.iml
*.pyc
*.pyo
*.rbc
*.yarb
*~
.DS_Store
.git
.hg
.mvn
.svn
CVS
HELP.md
_pycache_
_svn
mvnw
mvnw.cmd
vssver.scc
vssver2.scc
7.父工程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.kylin.cloud</groupId><artifactId>cloud2024</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>--><!--仅为了整合openfeign + alibaba sentinel的案例,降低版本处理下--><!--<spring.boot.version>3.0.9</spring.boot.version><spring.cloud.version>2022.0.2</spring.cloud.version>--><!--仅为了整合openfeign + alibaba seata的案例,降低版本处理下--><spring.boot.version>3.1.7</spring.boot.version><spring.cloud.version>2022.0.4</spring.cloud.version><spring.cloud.alibaba.version>2022.0.0.0-RC2</spring.cloud.alibaba.version><micrometer-tracing.version>1.2.0</micrometer-tracing.version><micrometer-observation.version>1.12.0</micrometer-observation.version><feign-micrometer.version>12.5</feign-micrometer.version><zipkin-reporter-brave.version>2.17.0</zipkin-reporter-brave.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><!--micrometer-tracing-bom导入链路追踪版本中心  1--><dependency><groupId>io.micrometer</groupId><artifactId>micrometer-tracing-bom</artifactId><version>${micrometer-tracing.version}</version><type>pom</type><scope>import</scope></dependency><!--micrometer-tracing指标追踪  2--><dependency><groupId>io.micrometer</groupId><artifactId>micrometer-tracing</artifactId><version>${micrometer-tracing.version}</version></dependency><!--micrometer-tracing-bridge-brave适配zipkin的桥接包 3--><dependency><groupId>io.micrometer</groupId><artifactId>micrometer-tracing-bridge-brave</artifactId><version>${micrometer-tracing.version}</version></dependency><!--micrometer-observation 4--><dependency><groupId>io.micrometer</groupId><artifactId>micrometer-observation</artifactId><version>${micrometer-observation.version}</version></dependency><!--feign-micrometer 5--><dependency><groupId>io.github.openfeign</groupId><artifactId>feign-micrometer</artifactId><version>${feign-micrometer.version}</version></dependency><!--zipkin-reporter-brave 6--><dependency><groupId>io.zipkin.reporter2</groupId><artifactId>zipkin-reporter-brave</artifactId><version>${zipkin-reporter-brave.version}</version></dependency></dependencies></dependencyManagement>
</project>

Maven工程落地细节复习

Maven中的DependencyManagement和Dependencies

dependencyManagement 

Maven 使用dependencyManagement 元素来提供了一种管理依赖版本号的方式。

通常会在一个组织或者项目的最顶层的父POM 中看到dependencyManagement 元素。 

使用pom.xml 中的dependencyManagement 元素能让所有在子项目中引用一个依赖而不用显式的列出版本号。

Maven会沿着父子层次向上走,直到找到一个拥有dependencyManagement 元素的项目,然后它就会使用这个dependencyManagement 元素中指定的版本号。 

 这样做的好处就是:如果有多个子项目都引用同一样依赖,则可以避免在每个使用的子项目里都声明一个版本号,优势:

  1. 这样当想升级或切换到另一个版本时,只需要在顶层父容器里更新,而不需要一个一个子项目的修改 ;
  2. 另外如果某个子项目需要另外的一个版本,只需要声明version就可。

 * dependencyManagement里只是声明依赖,并不实现引入,因此子项目需要显示的声明需要用的依赖。 

*  如果不在子项目中声明依赖,是不会从父项目中继承下来的,只有在子项目中写了该依赖项并且没有指定具体版本,才会从父项目中继承该项且version和scope都读取自父pom; 

*  如果子项目中指定了版本号,那么会使用子项目中指定的jar版本。

maven中跳过单元测试

1  配置

<build><!-- maven中跳过单元测试 --><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-surefire-plugin</artifactId><configuration><skip>true</skip></configuration></plugin></plugins>
</build>

2  IDEA工具支持(推荐)

mysql驱动说明

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>

三、Mapper4之一键生成

mybatis-generator:http://mybatis.org/generator/

MyBatis通用Mapper4官网:https://github.com/abel533/Mapper

本次使用Mapper4

下一代:MyBatis 通用 Mapper5官网:GitHub - mybatis-mapper/mapper: MyBatis Mapper

一键生成步骤

1.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;
2.Module
  • 普通Maven工程
  • mybatis_generator2024

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.kylin.cloud</groupId><artifactId>mscloudV5</artifactId><version>1.0-SNAPSHOT</version></parent><!--我自己独一份,只是一个普通Maven工程,与boot和cloud无关--><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><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>
4.配置路径

src\main\resources路径下新建

config.properties

mysql5

#User表包名
package.name=com.atguigu.cloud
# mysql5.7
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

mysql8

#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 generatorConfigurationPUBLIC "-//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>
一键生成

双击插件mybatis-generator:gererate一键生成

生成entity+mapper接口+xml实现SQL

四、Rest通用Base工程构建

基础工程

1.cloud-provider-payment8001微服务提供者支付Module模块
微服务口诀

1.建module

2.改POM

3.写YML

4.主启动

5.业务类

实现步骤
1.建module

建普通Maven模块cloud-provider-payment8001

创建完成后请回到父工程查看pom文件变化

<modules><module>mybatis_generator2024</module><module>cloud-provider-payment8001</module>
</modules>
2.改POM

通过dependencies 标签,将启动类使用的依赖包从父类引入子模块

<?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></plugin></plugins></build></project>
3.写YML

application.yml

server:port: 8001# ==========applicationName + druid-mysql8 driver===================
spring:application:name: cloud-payment-servicedatasource:type: com.alibaba.druid.pool.DruidDataSourcedriver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/db2024?characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8&rewriteBatchedStatements=true&allowPublicKeyRetrieval=trueusername: rootpassword: 123456# ========================mybatis===================
mybatis:mapper-locations: classpath:mapper/*.xmltype-aliases-package: com.atguigu.cloud.entitiesconfiguration:map-underscore-to-camel-case: true
4.主启动(修改Main类名Main8001)
package com.atguigu.cloud;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import tk.mybatis.spring.annotation.MapperScan;@SpringBootApplication
@MapperScan("com.atguigu.cloud.mapper") //import tk.mybatis.spring.annotation.MapperScan;
public class Main8001
{public static void main(String[] args){SpringApplication.run(Main8001.class,args);}
}
5.业务类

5.1 将之前一键生成的代码直接拷贝进8001模块

5.2 entities

主实体Pay

package com.atguigu.cloud.entities;import java.math.BigDecimal;
import java.util.Date;
import javax.persistence.*;/*** 表名:t_pay* 表注释:支付交易表
*/
@Table(name = "t_pay")
public class Pay {@Id@GeneratedValue(generator = "JDBC")private Integer id;/*** 支付流水号*/@Column(name = "pay_no")private String payNo;/*** 订单流水号*/@Column(name = "order_no")private String orderNo;/*** 用户账号ID*/@Column(name = "user_id")private Integer userId;/*** 交易金额*/private BigDecimal amount;/*** 删除标志,默认0不删除,1删除*/private Byte deleted;/*** 创建时间*/@Column(name = "create_time")private Date createTime;/*** 更新时间*/@Column(name = "update_time")private Date updateTime;/*** @return id*/public Integer getId() {return id;}/*** @param id*/public void setId(Integer id) {this.id = id;}/*** 获取支付流水号** @return payNo - 支付流水号*/public String getPayNo() {return payNo;}/*** 设置支付流水号** @param payNo 支付流水号*/public void setPayNo(String payNo) {this.payNo = payNo;}/*** 获取订单流水号** @return orderNo - 订单流水号*/public String getOrderNo() {return orderNo;}/*** 设置订单流水号** @param orderNo 订单流水号*/public void setOrderNo(String orderNo) {this.orderNo = orderNo;}/*** 获取用户账号ID** @return userId - 用户账号ID*/public Integer getUserId() {return userId;}/*** 设置用户账号ID** @param userId 用户账号ID*/public void setUserId(Integer userId) {this.userId = userId;}/*** 获取交易金额** @return amount - 交易金额*/public BigDecimal getAmount() {return amount;}/*** 设置交易金额** @param amount 交易金额*/public void setAmount(BigDecimal amount) {this.amount = amount;}/*** 获取删除标志,默认0不删除,1删除** @return deleted - 删除标志,默认0不删除,1删除*/public Byte getDeleted() {return deleted;}/*** 设置删除标志,默认0不删除,1删除** @param deleted 删除标志,默认0不删除,1删除*/public void setDeleted(Byte deleted) {this.deleted = deleted;}/*** 获取创建时间** @return createTime - 创建时间*/public Date getCreateTime() {return createTime;}/*** 设置创建时间** @param createTime 创建时间*/public void setCreateTime(Date createTime) {this.createTime = createTime;}/*** 获取更新时间** @return updateTime - 更新时间*/public Date getUpdateTime() {return updateTime;}/*** 设置更新时间** @param updateTime 更新时间*/public void setUpdateTime(Date updateTime) {this.updateTime = updateTime;}
}

传递数值PayDTO

package com.atguigu.cloud.entities;import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;import java.io.Serializable;
import java.math.BigDecimal;@Data
@AllArgsConstructor
@NoArgsConstructor
public class PayDTO implements Serializable
{private Integer id;//支付流水号private String payNo;//订单流水号private String orderNo;//用户账号IDprivate Integer userId;//交易金额private BigDecimal amount;
}

5.3 mapper

Mapper接口PayMapper

package com.atguigu.cloud.mapper;import com.atguigu.cloud.entities.Pay;
import tk.mybatis.mapper.common.Mapper;public interface PayMapper extends Mapper<Pay> {
}

映射文件PayMapper.xml

src\main\resources路径下,新建文件夹mapper

拷贝PayMapper.xml进上一步的mapper文件夹

PayMapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.atguigu.cloud.mapper.PayMapper"><resultMap id="BaseResultMap" type="com.atguigu.cloud.entities.Pay"><!--WARNING - @mbg.generated--><id column="id" jdbcType="INTEGER" property="id" /><result column="pay_no" jdbcType="VARCHAR" property="payNo" /><result column="order_no" jdbcType="VARCHAR" property="orderNo" /><result column="user_id" jdbcType="INTEGER" property="userId" /><result column="amount" jdbcType="DECIMAL" property="amount" /><result column="deleted" jdbcType="TINYINT" property="deleted" /><result column="create_time" jdbcType="TIMESTAMP" property="createTime" /><result column="update_time" jdbcType="TIMESTAMP" property="updateTime" /></resultMap>
</mapper>

5.4 service

服务接口PayService

package com.atguigu.cloud.service;import com.atguigu.cloud.entities.Pay;import java.util.List;public interface PayService
{public int add(Pay pay);public int delete(Integer id);public int update(Pay pay);public Pay   getById(Integer id);public List<Pay> getAll();
}

实现类PayServicelmpl

package com.atguigu.cloud.service.impl;import com.atguigu.cloud.entities.Pay;
import com.atguigu.cloud.mapper.PayMapper;
import com.atguigu.cloud.service.PayService;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;import java.util.List;@Service
public class PayServiceImpl implements PayService{@ResourcePayMapper payMapper;@Overridepublic int add(Pay pay){return payMapper.insertSelective(pay);}@Overridepublic int delete(Integer id){return payMapper.deleteByPrimaryKey(id);}@Overridepublic int update(Pay pay){return payMapper.updateByPrimaryKeySelective(pay);}@Overridepublic Pay getById(Integer id){return payMapper.selectByPrimaryKey(id);}@Overridepublic List<Pay> getAll(){return payMapper.selectAll();}
}

5.5 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 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
public class PayController{@Resource 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);}//全部查询getall作为家庭作业
}
代码测试
PostMan

add

{"payNo": "17204076","orderNo": "6544de1c424a","userId": "2","amount": "19.90"
}

delete

update

select

Swagger3

常用注解

1. 注解列表

2. Controller

@Tag

修改PayController

package com.atguigu.cloud.controller;import com.atguigu.cloud.entities.Pay;
import com.atguigu.cloud.entities.PayDTO;
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
{@ResourcePayService payService;@PostMapping(value = "/pay/add")@Operation(summary = "新增",description = "新增支付流水方法,json串做参数")public String addPay(@RequestBody Pay pay){System.out.println(pay.toString());int i = payService.add(pay);return "成功插入记录,返回值:"+i;}@DeleteMapping(value = "/pay/del/{id}")@Operation(summary = "删除",description = "删除支付流水方法")public Integer deletePay(@PathVariable("id") Integer id) {return payService.delete(id);}@PutMapping(value = "/pay/update")@Operation(summary = "修改",description = "修改支付流水方法")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}")@Operation(summary = "按照ID查流水",description = "查询支付流水方法")public Pay getById(@PathVariable("id") Integer id){return payService.getById(id);}//全部查询getall作为家庭作业
}

3. 方法

@Operation

4.entity或者DTO

@Schema

含分组迭代的Config配置类

Swagger3Config.java

package com.atguigu.cloud.config;import io.swagger.v3.oas.models.ExternalDocumentation;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Info;
import org.springdoc.core.models.GroupedOpenApi;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class Swagger3Config
{@Beanpublic GroupedOpenApi PayApi(){return GroupedOpenApi.builder().group("支付微服务模块").pathsToMatch("/pay/**").build();}@Beanpublic GroupedOpenApi OtherApi(){return GroupedOpenApi.builder().group("其它微服务模块").pathsToMatch("/other/**", "/others").build();}/*@Beanpublic GroupedOpenApi CustomerApi(){return GroupedOpenApi.builder().group("客户微服务模块").pathsToMatch("/customer/**", "/customers").build();}*/@Beanpublic OpenAPI docsOpenApi(){return new OpenAPI().info(new Info().title("cloud2024").description("通用设计rest").version("v1.0")).externalDocs(new ExternalDocumentation().description("www.atguigu.com").url("https://yiyan.baidu.com/"));}
}

调用方式

http://localhost:8001/swagger-ui/index.html

测试接口通过try it out 进行测试

工程代码优化

解决:时间格式问题

解决:统一返回值

解决:全局异常接入返回的标准格式

...

解决:时间格式问题

/*** 创建时间*/
@Column(name = "create_time")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date createTime;/*** 更新时间*/
@Column(name = "update_time")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date updateTime;
解决:统一返回值
思路
定义返回标准格式,3大标配
  • code状态值:由后端统一定义各种返回结果的状态码
  • message描述:本次接口调用的结果描述
  • data数据:本次返回的数据
扩展-接口调用时间之类
  • timestamp: 接口调用时间
步骤
1.新建枚举类ReturnCodeEnum
HTTP请求返回的状态码

ReturnCodeEnum

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","无访问权限,请联系管理员授予权限"),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传统   根据输入的code返回相应的ReturnCodeEnum 一组枚举参数public static ReturnCodeEnum getReturnCodeEnuV1(String code){for (ReturnCodeEnum element : ReturnCodeEnum.values()) {if(element.getCode().equalsIgnoreCase(code)){return  element;}}return null;}//3.2 Stream流式计算版public static ReturnCodeEnum getReturnCodeEnuV2(String code){return Arrays.stream(ReturnCodeEnum.values()).filter(x -> x.getCode().equalsIgnoreCase(code)).findFirst().orElse(null);}public static void main(String[] args) {System.out.println(getReturnCodeEnuV1("200"));System.out.println(getReturnCodeEnuV1("200").getCode());System.out.println(getReturnCodeEnuV1("200").getMessage());System.out.println("----------------");System.out.println(getReturnCodeEnuV2("404"));System.out.println(getReturnCodeEnuV2("404").getCode());System.out.println(getReturnCodeEnuV2("404").getMessage());}//枚举编写口诀:1.举值-2.构造-3.遍历
}
2.新建统一定义返回对象ResultData

ResultData

package com.atguigu.cloud.resp;import lombok.Data;
import lombok.experimental.Accessors;@Data
@Accessors(chain = true)
public class ResultData <T>{private String code;/** 结果状态 ,具体状态码参见枚举类ReturnCodeEnum.java*/private String message;private T data;private long timestamp;//接口返回数据的时间public ResultData() {this.timestamp = System.currentTimeMillis();}//接口返回的参数值-成功 successpublic static<T> ResultData<T> success(T data){ResultData resultData= new ResultData();resultData.setCode(ReturnCodeEnum.RC200.getCode());resultData.setMessage(ReturnCodeEnum.RC200.getMessage());resultData.setData(data);return resultData;}//接口返回的参数值-失败 failpublic static<T> ResultData<T> fail(String code,String message){ResultData 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
{@ResourcePayService 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);}//全部查询getall作为家庭作业
}
测试

http://localhost:8001/pay/get/1

结论

通过ResultData.success()对返回结果进行包装后返回给前端

查询方法写个bug

if(id == -4) throw new RuntimeException("id不能为负数");

解决:全局异常接入返回的标准格式

为什么需要全局异常处理器

解決不在手写try...catch的问题

1.新建全局异常类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
//@Slf4j注解的主要作用包括简化日志记录器的创建、提供不同日志级别的记录方法、自动添加类名和行号信息,以及简化日志配置的切换。
@RestControllerAdvice
// @RestControllerAdvice是 Spring Boot 提供的注解,用于实现全局范围内的异常处理和数据绑定设置。它基于 Spring MVC 的HandlerExceptionResolver和HandlerMethodReturnValueHandler实现,并通过 AOP 和事件机制来拦截和处理异常。这种机制使得全局异常处理和数据绑定可以集中管理,并提供了灵活性和扩展性。
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("全局异常信息:{}",e.getMessage(),e);return ResultData.fail(ReturnCodeEnum.RC500.getCode(), e.getMessage());}
}
2.添加全局异常进行测试

测试地址:http://localhost:8001/pay/get/-4

{"code": "500","message": "id不能为负数","data": null,"timestamp": 1721723040483
}
3.单独异常抛出处理
@GetMapping(value = "/pay/error")
public ResultData<Integer> getPayError(){Integer integer = Integer.valueOf(200);try{System.out.println("come in payerror test");int age =100/0;}catch (Exception e){e.printStackTrace();return ResultData.fail(ReturnCodeEnum.RC500.getCode(), e.getMessage());}return ResultData.success(integer);
}
4.访问地址:http://localhost:8001/pay/error

返回参数:

{"code": "500","message": "/ by zero","data": null,"timestamp": 1721723853568
}
5.修改Controller
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.resp.ReturnCodeEnum;
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
{@ResourcePayService 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){if(id == -4) throw new RuntimeException("id不能为负数");Pay pay = payService.getById(id);return ResultData.success(pay);}//全部查询getall作为家庭作业@RequestMapping(value = "/pay/error",method = RequestMethod.GET)public ResultData<Integer> getPayError(){Integer i = Integer.valueOf(200);try{System.out.println("--------come here");int data = 10/0;}catch (Exception e){e.printStackTrace();return ResultData.fail(ReturnCodeEnum.RC500.getCode(),e.getMessage());}return ResultData.success(i);}
}
6.基础项目优化结束以下是工程目录

五、引入微服务理念,从这里开始

订单微服务80如何才能调用到支付微服务8001?

cloud-consumer-order80微服务调用者订单Module模块
1.建模块 cloud-consumer-order80
2.修改POM

通过dependencies标签将需要使用的依赖在pom中从父项目引入子模块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>
3. 编写YML

application.yml

server:port: 80
4.主启动类编写

备注:修改Main类名为Main80

package com.atguigu.cloud;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class Main80
{public static void main(String[] args){SpringApplication.run(Main80.class,args);}
}
5.业务类
5.1 entities-传递数值PayDTO 
package com.atguigu.cloud.entities;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;import java.io.Serializable;
import java.math.BigDecimal;/*** 一般而言,调用者不应该获悉服务提供者的entity资源并知道表结构关系,所以服务提供方给出的* 接口文档都都应成为DTO*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class PayDTO implements Serializable
{private Integer id;//支付流水号private String payNo;//订单流水号private String orderNo;//用户账号IDprivate Integer userId;//交易金额private BigDecimal amount;
}
5.2 ResultData同意返回值从8001拷贝即可
5.3 RestTemplate
RestTemplate简介
RestTemplate提供了多种便捷访问远程Http服务的方法, 是一种简单便捷的访问restful服务模板类,是Spring提供的用于访问Rest服务的客户端模板工具集
官网地址: RestTemplate (Spring Framework 6.0.11 API)
常用API使用说明
  • 使用说明
  • getForObject方法/getForEntity方法
  • postForObject/postForEntity
  • GET 请求方法 
  • POST 请求方法 
  • put 请求方法 
  • delete 请求方法 
  • 通用请求方法exchange方法
  • 使用说明

    使用restTemplate访问restful接口非常的简单粗暴无脑。

    (url, requestMap, ResponseBean.class)这三个参数分别代表 

    REST请求地址、请求参数、HTTP响应转换被转换成的对象类型。

    Entity Object两种方法

  • getForObject方法/getForEntity方法

    返回对象为响应体中数据转化成的对象,基本上可以理解为Json 

  • 返回对象为ResponseEntity对象,包含了响应中的一些重要信息,比如响应头、响应状态码、响应体等

  • postForObject/postForEntity

  • RestTemplate-GET 请求方法 

  • <T> T getForObject(String url, Class<T> responseType, Object... uriVariables); 
    <T> T getForObject(String url, Class<T> responseType, Map<String, ?> uriVariables);
    <T> T getForObject(URI url, Class<T> responseType);
    <T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Object... uriVariables);
    <T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Map<String, ?> uriVariables);
    <T> ResponseEntity<T> getForEntity(URI var1, Class<T> responseType);

    RestTemplate-POST 请求方法 

  • <T> T postForObject(String url, @Nullable Object request, Class<T> responseType, Object... uriVariables);
    <T> T postForObject(String url, @Nullable Object request, Class<T> responseType, Map<String, ?> uriVariables);
    <T> T postForObject(URI url, @Nullable Object request, Class<T> responseType);
    <T> ResponseEntity<T> postForEntity(String url, @Nullable Object request, Class<T> responseType, Object... uriVariables);
    <T> ResponseEntity<T> postForEntity(String url, @Nullable Object request, Class<T> responseType, Map<String, ?> uriVariables);
    <T> ResponseEntity<T> postForEntity(URI url, @Nullable Object request, Class<T> responseType);

    RestTemplate-put请求方法( 修改)一般不用

  • void        put(String url, Object request, Object... uriVariables)         Create or update a resource by PUTting the given object to the URI.
    void        put(String url, Object request, Map<String,?> uriVariables)     Creates a new resource by PUTting the given object to URI template.
    void        put(URI url, Object request) 

    delete使用案例

  • @PutMapping("/consumer/pay/update")
    public void updatePay(PayDTO payDTO)
    {restTemplate.put(PaymentSrv_URL + "/pay/update",payDTO,  ResultData.class);
    }

    RestTemplate-Exchange请求方法

    exchange通用协议请求方法,它可以发送GET、POST、DELETE、PUT、OPTIONS、PATCH等等HTTP方法请求。

  • <T> ResponseEntity<T>   exchange(String url, HttpMethod method, HttpEntity<?> requestEntity, Class<T> responseType, Object... uriVariables)                                 对给定的URI模板执行HTTP方法,将给定的请求实体写入请求,并将响应作为ResponseEntity返回。
    <T> ResponseEntity<T>   exchange(String url, HttpMethod method, HttpEntity<?> requestEntity, Class<T> responseType, Map<String,?> uriVariables)                             对给定的URI模板执行HTTP方法,将给定的请求实体写入请求,并将响应作为ResponseEntity返回。
    <T> ResponseEntity<T>   exchange(String url, HttpMethod method, HttpEntity<?> requestEntity, ParameterizedTypeReference<T> responseType, Object... uriVariables)            对给定的URI模板执行HTTP方法,将给定的请求实体写入请求,并将响应作为ResponseEntity返回。
    <T> ResponseEntity<T>   exchange(String url, HttpMethod method, HttpEntity<?> requestEntity, ParameterizedTypeReference<T> responseType, Map<String,?> uriVariables)        对给定的URI模板执行HTTP方法,将给定的请求实体写入请求,并将响应作为ResponseEntity返回。
    <T> ResponseEntity<T>   exchange(URI url, HttpMethod method, HttpEntity<?> requestEntity, Class<T> responseType)                                                            对给定的URI模板执行HTTP方法,将给定的请求实体写入请求,并将响应作为ResponseEntity返回。
    <T> ResponseEntity<T>   exchange(URI url, HttpMethod method, HttpEntity<?> requestEntity, ParameterizedTypeReference<T> responseType)                                       对给定的URI模板执行HTTP方法,将给定的请求实体写入请求,并将响应作为ResponseEntity返回。
    <T> ResponseEntity<T>   exchange(RequestEntity<?> entity, Class<T> responseType)                                                                                            执行给定RequestEntity中指定的请求,并将响应作为ResponseEntity返回。
    <T> ResponseEntity<T>   exchange(RequestEntity<?> entity, ParameterizedTypeReference<T> responseType)              

    Exchange使用案例

  • @DeleteMapping("/consumer/pay/del/{id}")
    public ResultData deletePay(@PathVariable("id") Integer id)
    {ResponseEntity<ResultData> result = restTemplate.exchange(PaymentSrv_URL + "/pay/del/" + id, HttpMethod.DELETE, null, ResultData.class);return result.getBody();
    }
    @PutMapping("/consumer/pay/update")
    public ResultData updatePay(PayDTO payDTO)
    {//请求头HttpHeaders headers  = new HttpHeaders();headers.setContentType(MediaType.APPLICATION_JSON);//发送请求HttpEntity<PayDTO> httpEntity = new HttpEntity<>(payDTO,headers);ResponseEntity<ResultData> result = restTemplate.exchange(PaymentSrv_URL + "/pay/update", HttpMethod.PUT, httpEntity, ResultData.class);return  result.getBody();
    }
    5.4 config 配置类
  • package 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
    {@Beanpublic RestTemplate restTemplate(){return new RestTemplate();}
    }
    5.5 controller(参数可以不添加@RequestBody)
  • package com.atguigu.cloud.controller;import com.atguigu.cloud.entities.PayDTO;
    import com.atguigu.cloud.resp.ResultData;
    import jakarta.annotation.Resource;
    import org.springframework.http.*;
    import org.springframework.web.bind.annotation.*;
    import org.springframework.web.client.RestTemplate;/*** 客户端订单通过RestTemple调用支付8001进行通信调用操作* 一般情况下,通过浏览器的地址栏输入url,发送的只能是get请求* 我们底层调用的是post方法,模拟消费者发送get请求,客户端消费者* 参数可以不添加@RequestBody* @return*/
    @RestController
    public class OrderController {public static final String PaymentSrv_URL="http://localhost:8001";//硬编码@Resourceprivate RestTemplate restTemplate;@PostMapping("/consumer/pay/add")public ResultData addOrder(PayDTO payDTO){return restTemplate.postForObject(PaymentSrv_URL+"/pay/add",payDTO,ResultData.class);}@DeleteMapping("/consumer/pay/del/{id}")public ResultData deletePay(@PathVariable("id") Integer id){// restTemplate.getForObject(PaymentSrv_URL+"/pay/del/"+id,ResultData.class);ResponseEntity<ResultData> result = restTemplate.exchange(PaymentSrv_URL + "/pay/del/" + id, HttpMethod.DELETE, null, ResultData.class);return result.getBody();}@PutMapping("/consumer/pay/update")public ResultData updatePay(PayDTO payDTO){//restTemplate.put(PaymentSrv_URL + "/pay/update",payDTO,  ResultData.class);//请求头HttpHeaders headers  = new HttpHeaders();headers.setContentType(MediaType.APPLICATION_JSON);//发送请求HttpEntity<PayDTO> httpEntity = new HttpEntity<>(payDTO,headers);ResponseEntity<ResultData> result = restTemplate.exchange(PaymentSrv_URL + "/pay/update", HttpMethod.PUT, httpEntity, ResultData.class);return  result.getBody();}@GetMapping("/consumer/pay/get/{id}")public ResultData getPayInfo(@PathVariable("id") Integer id){return restTemplate.getForObject(PaymentSrv_URL+"/pay/get/"+id,ResultData.class,id);}@GetMapping("/consumer/pay/list")public ResultData getPayInfo(){return restTemplate.getForObject(PaymentSrv_URL+"/pay/list",ResultData.class);}
    }
    6. postman测试

    http://localhost/consumer/pay/get/1

    http://localhost/consumer/pay/add?payNo=1213&orderNo=1213&userId=2&amount=3.33

  • 7. 多模块启动类切换设置

    idea设置services多启动,方便多模块启动类切换

    services点击+->Run Configuration Type->springboot

  • 工程重构
    1.系统中有重复部分,重构
  • 2.新建 cloud-api-commons Module

    cloud-api-commons

    对外暴露通用的组件/api/接口/工具类等

    3.修改 cloud-api-commons模块POM

    引入SpringBoot通用依赖模块、lombok、hutool

    <?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"><parent><artifactId>cloud2024</artifactId><groupId>com.atguigu.cloud</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><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通用依赖模块  actuator 是spring boot提供的对应用系统的自省和监控的集成功能,可以对应用系统进行配置查看、相关功能统计等--><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.公用代码统一管理

    提取各模块公用类放入cloud-api-commons模块

5.cloud-api-commons模块打包

maven命令 clean install

6.订单80和支付8001模块分别改造

删除各自的原先有过的entities和统一返回体、全局异常等内容

将打包后,将cloud-api-commons模块引入到各模块POM

  • <!--将cloud-api-commons通用工具模块打包后引入-->
    <dependency><groupId>com.atguigu.cloud</groupId><artifactId>cloud-api-commons</artifactId><version>1.0-SNAPSHOT</version>
    </dependency>
    7.重构后的工程目录
http://www.xdnf.cn/news/665515.html

相关文章:

  • 【stm32开发板】产品设计流程及元件选型
  • 创业团队建设与管理(一)
  • 牛客round94E
  • 「Unity3D」TextMeshPro的TMP_InputField在改变高度时,其中textComponent移动的问题解决
  • VMware Live Recovery 和 VMware Data Recovery区别
  • python 报错记录-Linux 退出python环境
  • Python Day34
  • 聚合CPA/CPS拉新分销平台开发:2025年核心功能与未来趋势解析
  • HarmonyOS运动开发:如何绘制运动速度轨迹
  • day 22 练习——泰坦尼克号幸存者预测
  • Dify中的GoogleSearch工具插件开发例子
  • 华为OD机试真题——新工号中数字的最短长度(2025A卷:100分)Java/python/JavaScript/C/C++/GO最佳实现
  • 【AI论文】LLaDA-V:具备视觉指令微调能力的大型语言扩散模型
  • 基于 LoRA 和 GRPO 的 Qwen2.5-3B 数学推理模型微调示例
  • java学习日志——Spring Security介绍
  • 二维坐标变换、三维坐标变换、综合变换
  • 人工智能工程师学习路线总结(上)
  • MySQL的日志和备份
  • 热点数据的统计到应用
  • C 语言学习笔记二
  • 202505系分论文《论模型驱动分析方法及应用》
  • FallbackHome的启动流程(android11)
  • 泪滴攻击详解
  • MDM在智能健身设备管理中的技术应用分析
  • 计算机系统简介(二)
  • python打卡day36@浙大疏锦行
  • C++ STL Queue容器使用详解
  • SPL 轻量级多源混算实践 1 - 在 RDB 上跑 SQL
  • vue3 浮点数计算
  • 码蹄集——矩形相交