天天看點

Mr. Cappuccino的第11杯咖啡——冒泡APP(更新版)之項目初始化

冒泡APP(更新版)之項目初始化

      • 1. 整體項目結構
      • 2. 建立父工程(bubble-parent):進行版本控制
      • 3. 建立公共依賴工程(bubble-common-lib):管理公共依賴
      • 4. 建立會員服務(bubble-member):管理使用者資訊
      • 5. 建立日記服務(bubble-diary):管理日記資訊
      • 6. 搭建網關(bubble-gateway):項目統一入口
      • 7. 項目啟動時遇到的一些問題
      • 8. 測試內建功能點
前言:心血來潮,打算将大學期間做的一些項目進行整合更新改造,出來工作已經将近兩年了,現在每天的生活無一不是在為公司的事業奮鬥着,殊不知自己對于這一行業的興趣也正在慢慢地被消磨着。在大學期間,對這行業的興趣十分濃厚,那時候自己就是整個項目的項目經理兼産品經理,完全可以去做着自己想要做的事情,而且通過自己的努力把整個項目給搗鼓起來了,那絕對是一件非常有成就感的事兒,在我看來這些就是讓興趣之火得以燃燒的主要原因。希望通過這個項目能讓自己找到之前的那份初心與熱愛,這個項目我會一直疊代下去的。加油!一起進步!一起成長!

話不多說,咱們先看一下之前寫的那些項目。

  1. 冒泡交友APP:這是大二期間模仿QQ寫的一款聊天交友的APP。主要使用了SpringBoot、Mybatis、MySQL等技術。

    項目結構:

    Mr. Cappuccino的第11杯咖啡——冒泡APP(更新版)之項目初始化
  2. 鐘意日記APP:這是去年上半年送給女朋友的一份禮物,主要是為了彼此之間能夠更加友善的交換日記進行閱讀而開發的一款應用。
    Mr. Cappuccino的第11杯咖啡——冒泡APP(更新版)之項目初始化
    可見這兩款應用都是非常傳統的單體項目,技術棧偏于老舊,準備此次對它進行更新改造。

在寫這篇博文之前,項目結構以及項目啟動的一些問題已經得以解決,這篇博文主要用于記錄分享。

1. 整體項目結構

Mr. Cappuccino的第11杯咖啡——冒泡APP(更新版)之項目初始化

2. 建立父工程(bubble-parent):進行版本控制

目前項目是基于JDK11+spring-cloud:2020.0.1+spring-cloud-alibaba:2021.1+spring-boot:2.4.2進行搭建。

Mr. Cappuccino的第11杯咖啡——冒泡APP(更新版)之項目初始化

pom.xml

<?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.bubble</groupId>
    <artifactId>bubble-parent</artifactId>
    <version>1.0-RELEASE</version>

    <packaging>pom</packaging>

    <properties>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
        <boot.version>2.4.2</boot.version>
        <mybatis.plus.starter.version>3.4.1</mybatis.plus.starter.version>
        <swagger.starter.version>1.7.0.RELEASE</swagger.starter.version>
        <cloud.version>2020.0.1</cloud.version>
        <cloud.alibaba.version>2021.1</cloud.alibaba.version>
    </properties>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.4.2</version>
        <relativePath/>
    </parent>

    <dependencies>
        <!-- lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <!-- commons-lang3 -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
        </dependency>
        <!-- 解決最新版cloud bootstrap.yml不生效的問題 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bootstrap</artifactId>
        </dependency>
        <!-- 解決網關無法轉發的問題 503 Service Unavailable -->
        <!-- 解決OpenFeign無法遠端調用的問題 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-loadbalancer</artifactId>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>${cloud.alibaba.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <!-- 解決 spring-boot jar 包下載下傳問題 -->
    <repositories>
        <repository>
            <id>spring-snapshots</id>
            <url>https://repo.spring.io/libs-snapshot</url>
        </repository>
    </repositories>
    <pluginRepositories>
        <pluginRepository>
            <id>spring-snapshots</id>
            <url>https://repo.spring.io/libs-snapshot</url>
        </pluginRepository>
    </pluginRepositories>

</project>
           

版本組合關系

Mr. Cappuccino的第11杯咖啡——冒泡APP(更新版)之項目初始化

3. 建立公共依賴工程(bubble-common-lib):管理公共依賴

Mr. Cappuccino的第11杯咖啡——冒泡APP(更新版)之項目初始化

pom.xml

<?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>bubble-common</artifactId>
        <groupId>com.bubble</groupId>
        <version>1.0-RELEASE</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>bubble-common-lib</artifactId>

    <packaging>jar</packaging>

    <dependencies>
        <!-- springboot-web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- mybatis-plus -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>${mybatis.plus.starter.version}</version>
        </dependency>
        <!-- mysql -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <!-- swagger -->
        <dependency>
            <groupId>com.spring4all</groupId>
            <artifactId>swagger-spring-boot-starter</artifactId>
            <version>${swagger.starter.version}</version>
        </dependency>
        <!-- nacos -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!-- nacos-config -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>
        <!-- openfeign -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <!-- 解決jdk11啟動異常 Spring BeanCreationException "xmlModelPlugin" -->
        <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
        </dependency>
        <!-- spring-boot 2.3.0.RELEASE 沒有自動引入validation對應的包 -->
        <!-- java.lang.NoClassDefFoundError: javax/validation/constraints/Min -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>
    </dependencies>

</project>
           
其中:bubble-common-base用于封裝統一傳回格式、bubble-common-cache用于封裝緩存工具類(如redis)、bubble-common-core用于封裝常用工具類(如MD5Util、SpringContextUtil)、bubble-common-log用于封裝統一日志輸出。

4. 建立會員服務(bubble-member):管理使用者資訊

Mr. Cappuccino的第11杯咖啡——冒泡APP(更新版)之項目初始化

boostrap.yml(配置注冊中心、配置中心)

server:
  port: 8070
spring:
  application:
    name: bubble-member
  cloud:
    nacos:
      discovery:
        server-addr: X.X.X.X:8848
      # 分布式配置中心相關配置
      config:
        server-addr: X.X.X.X:8848
        file-extension: yml
  # 指定版本
  profiles:
    active: dev
           

application.yml(配置Swagger、資料庫連接配接、Redis連接配接)

# swagger相關配置
swagger:
  base-package: com.bubble.member.service.impl
  title: 冒泡APP-會員服務接口
  description: 冒泡APP
  version: 1.1
  terms-of-service-url: https://honeyyxk.com
  contact:
    name: 袁小康
    email: [email protected]
    url: https://honeyyxk.com
  enabled: true

# 資料庫相關配置
spring:
  datasource:
    username: honey
    password: [email protected]
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://X.X.X.X.com:3306/bubble_member?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai
  redis:
    host: X.X.X.X.com
    password: [email protected]
    port: 6379
    database: 0
           

AppMember.java(啟動類,開啟Swagger)

package com.bubble.member;

import com.spring4all.swagger.EnableSwagger2Doc;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * @author honey
 * @date 2021-09-07 12:55:09
 */
@EnableSwagger2Doc
@SpringBootApplication
public class AppMember {

    public static void main(String[] args) {
        SpringApplication.run(AppMember.class);
    }
}

           

bubble-member子產品pom.xml(引入父工程及公共依賴)

<?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>

    <artifactId>bubble-member</artifactId>
    <packaging>pom</packaging>
    <version>1.0-RELEASE</version>
    <modules>
        <module>bubble-member-service</module>
        <module>bubble-member-api</module>
    </modules>

    <parent>
        <groupId>com.bubble</groupId>
        <artifactId>bubble-parent</artifactId>
        <version>1.0-RELEASE</version>
    </parent>
    <dependencies>
        <dependency>
            <groupId>com.bubble</groupId>
            <artifactId>bubble-common-lib</artifactId>
            <version>1.0-RELEASE</version>
        </dependency>
    </dependencies>

</project>
           

bubble-member-api子產品pom.xml

<?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>bubble-member</artifactId>
        <groupId>com.bubble</groupId>
        <version>1.0-RELEASE</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>bubble-member-api</artifactId>

    <packaging>jar</packaging>

</project>
           

bubble-member-service子產品pom.xml

<?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>bubble-member</artifactId>
        <groupId>com.bubble</groupId>
        <version>1.0-RELEASE</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>bubble-member-service</artifactId>

    <packaging>jar</packaging>

    <dependencies>
        <dependency>
            <groupId>com.bubble</groupId>
            <artifactId>bubble-member-api</artifactId>
            <version>1.0-RELEASE</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>
           

5. 建立日記服務(bubble-diary):管理日記資訊

Mr. Cappuccino的第11杯咖啡——冒泡APP(更新版)之項目初始化

boostrap.yml(配置注冊中心、配置中心)

server:
  port: 8060
spring:
  application:
    name: bubble-diary
  cloud:
    nacos:
      discovery:
        server-addr: X.X.X.X:8848
      # 分布式配置中心相關配置
      config:
        server-addr: X.X.X.X:8848
        file-extension: yml
  # 指定版本
  profiles:
    active: dev
           

application.yml(配置Swagger、資料庫連接配接、Redis連接配接)

# swagger相關配置
swagger:
  base-package: com.bubble.diary.service.impl
  title: 冒泡APP-日記服務接口
  description: 冒泡APP
  version: 1.1
  terms-of-service-url: https://honeyyxk.com
  contact:
    name: 袁小康
    email: [email protected]
    url: https://honeyyxk.com
  enabled: true

# 資料庫相關配置
spring:
  datasource:
    username: honey
    password: [email protected]
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://X.X.X.X.com:3306/bubble_diary?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai
  redis:
    host: X.X.X.X.com
    password: [email protected]
    port: 6379
    database: 1
           

AppDiary.java(啟動類,開啟Swagger、Feign用戶端)

package com.bubble.diary;

import com.spring4all.swagger.EnableSwagger2Doc;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;

/**
 * @author honey
 * @date 2021-09-07 23:15:09
 */
@EnableFeignClients
@EnableSwagger2Doc
@SpringBootApplication
public class AppDiary {

    public static void main(String[] args) {
        SpringApplication.run(AppDiary.class);
    }
}

           

bubble-diary子產品pom.xml(引入父工程及公共依賴)

<?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>

    <artifactId>bubble-diary</artifactId>
    <packaging>pom</packaging>
    <version>1.0-RELEASE</version>
    <modules>
        <module>bubble-diary-api</module>
        <module>bubble-diary-service</module>
    </modules>

    <parent>
        <groupId>com.bubble</groupId>
        <artifactId>bubble-parent</artifactId>
        <version>1.0-RELEASE</version>
    </parent>
    <dependencies>
        <dependency>
            <groupId>com.bubble</groupId>
            <artifactId>bubble-common-lib</artifactId>
            <version>1.0-RELEASE</version>
        </dependency>
    </dependencies>

</project>
           

bubble-diary-api子產品pom.xml

<?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>bubble-diary</artifactId>
        <groupId>com.bubble</groupId>
        <version>1.0-RELEASE</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>bubble-diary-api</artifactId>

    <packaging>jar</packaging>

</project>
           

bubble-diary-service子產品pom.xml

<?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>bubble-diary</artifactId>
        <groupId>com.bubble</groupId>
        <version>1.0-RELEASE</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>bubble-diary-service</artifactId>

    <packaging>jar</packaging>

    <dependencies>
        <dependency>
            <groupId>com.bubble</groupId>
            <artifactId>bubble-diary-api</artifactId>
            <version>1.0-RELEASE</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>
           

6. 搭建網關(bubble-gateway):項目統一入口

Mr. Cappuccino的第11杯咖啡——冒泡APP(更新版)之項目初始化

pom.xml

<?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>

    <artifactId>bubble-gateway</artifactId>
    <version>1.0-RELEASE</version>

    <packaging>jar</packaging>

    <parent>
        <groupId>com.bubble</groupId>
        <artifactId>bubble-parent</artifactId>
        <version>1.0-RELEASE</version>
    </parent>
    <dependencies>
        <!-- gateway -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        <!-- swagger -->
        <dependency>
            <groupId>com.spring4all</groupId>
            <artifactId>swagger-spring-boot-starter</artifactId>
            <version>${swagger.starter.version}</version>
        </dependency>
        <!-- nacos -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>
           

boostrap.yml(配置注冊中心、轉發路由)

server:
  port: 81
spring:
  application:
    name: bubble-gateway
  cloud:
    gateway:
      routes:
        - id: member
          uri: lb://bubble-member
          predicates:
            - Path=/bubble-member/**
          filters:
            - SwaggerHeaderFilter
            - StripPrefix=1
        - id: diary
          uri: lb://bubble-diary
          predicates:
            - Path=/bubble-diary/**
          filters:
            - SwaggerHeaderFilter
            - StripPrefix=1
      x-forwarded:
        enabled: false
    nacos:
      discovery:
        server-addr: X.X.X.X:8848
           

AppGateway.java

package com.bubble.gateway;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * @author honey
 * @date 2021-09-07 12:55:09
 */
@SpringBootApplication
public class AppGateway {

    public static void main(String[] args) {
        SpringApplication.run(AppGateway.class);
    }
}

           

7. 項目啟動時遇到的一些問題

Error creating bean with name 'xmlModelPlugin’

解決方案:引入jaxb-api依賴

<!-- 解決jdk11啟動異常 Spring BeanCreationException "xmlModelPlugin" -->
<dependency>
    <groupId>javax.xml.bind</groupId>
    <artifactId>jaxb-api</artifactId>
</dependency>
           

java.lang.NoClassDefFoundError: javax/validation/constraints/Min

解決方案:引入validation依賴

<!-- spring-boot 2.3.0.RELEASE 沒有自動引入validation對應的包 -->
<!-- java.lang.NoClassDefFoundError: javax/validation/constraints/Min -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
</dependency>
           

SpringCloud 2020.x.x工程bootstrap引導配置不生效

解決方案:引入boostrap依賴

<!-- 解決最新版cloud bootstrap.yml不生效的問題 -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
           

網關無法轉發/OpenFeign無法遠端調用

解決方案:引入loadbalancer依賴

<!-- 解決網關無法轉發的問題 503 Service Unavailable -->
<!-- 解決OpenFeign無法遠端調用的問題 -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-loadbalancer</artifactId>
</dependency>
           

8. 測試內建功能點

注冊中心

Mr. Cappuccino的第11杯咖啡——冒泡APP(更新版)之項目初始化

如何內建?

  1. 引入nacos-discovery的依賴;
  2. boostrap.yml配置注冊中心位址;

配置中心

在會員服務進行功能點測試,新增測試接口用于測試

MemberService.java

package com.bubble.member.service;

import io.swagger.annotations.*;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * @author honey
 * @date 2021-09-07 12:55:09
 */
@Api(tags = "會員資訊服務接口")
@RequestMapping(value = "/member")
public interface MemberService {

    /**
     * 根據令牌查詢使用者基本資訊接口
     *
     * @param loginToken 登入令牌
     * @return String
     */
    @GetMapping(value = "/getUserInfo")
    @ApiOperation("根據令牌查詢使用者基本資訊接口")
    @ApiImplicitParam(name = "loginToken", value = "登入令牌", required = true)
    @ApiResponses({@ApiResponse(code = 200, message = "成功"), @ApiResponse(code = 500, message = "失敗")})
    String getUserInfo(String loginToken);
}

           

MemberServiceImpl.java

package com.bubble.member.service.impl;

import com.bubble.member.service.MemberService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author honey
 * @date 2021-09-07 12:55:09
 */
@RestController
public class MemberServiceImpl implements MemberService {

    @Value("${test}")
    private String test;

    @Override
    public String getUserInfo(String loginToken) {
        return "資訊" + test;
    }
}

           

nacos新增配置檔案

Mr. Cappuccino的第11杯咖啡——冒泡APP(更新版)之項目初始化

請求接口能達到預期則說明內建成功

Mr. Cappuccino的第11杯咖啡——冒泡APP(更新版)之項目初始化

如何內建?

  1. 引入nacos-config依賴
  2. boostrap.yml配置配置中心位址;

注意:nacos新增配置檔案名稱bubble-member-dev.yml需要和boostrap.yml中的配置保持一緻。

openfeign

在日記服務進行功能點測試,新增測試接口用于測試

DiaryService.java

package com.bubble.diary.service;

import io.swagger.annotations.*;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * @author honey
 * @date 2021-09-07 12:55:09
 */
@Api(tags = "日記資訊服務接口")
@RequestMapping(value = "/diary")
public interface DiaryService {

    /**
     * 根據令牌查詢日記基本資訊接口
     *
     * @param loginToken 登入令牌
     * @return String
     */
    @GetMapping(value = "/getDiaryInfo")
    @ApiOperation("根據令牌查詢日記基本資訊接口")
    @ApiImplicitParam(name = "loginToken", value = "登入令牌", required = true)
    @ApiResponses({@ApiResponse(code = 200, message = "成功"), @ApiResponse(code = 500, message = "失敗")})
    String getDiaryInfo(String loginToken);
}

           

DiaryServiceImpl.java

package com.bubble.diary.service.impl;

import com.bubble.diary.feign.MemberFeignService;
import com.bubble.diary.service.DiaryService;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

/**
 * @author honey
 * @date 2021-09-07 23:15:09
 */
@RestController
public class DiaryServiceImpl implements DiaryService {

    @Resource
    private MemberFeignService memberFeignService;

    @Override
    public String getDiaryInfo(String loginToken) {
        return memberFeignService.getUserInfo(loginToken);
    }
}

           

MemberFeignService.java

package com.bubble.diary.feign;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;

/**
 * @author honey
 * @date 2021-09-07 23:15:09
 */
@FeignClient(name = "bubble-member", path = "/member")
public interface MemberFeignService {

    /**
     * 擷取使用者資訊
     *
     * @param loginToken 令牌
     * @return String
     */
    @GetMapping(value = "/getUserInfo")
    String getUserInfo(@RequestParam("loginToken") String loginToken);
}

           

請求接口能達到預期則說明內建成功

Mr. Cappuccino的第11杯咖啡——冒泡APP(更新版)之項目初始化

如何內建?

  1. 引入openfeign、loadbalancer依賴;
  2. 啟動類開啟Feign用戶端,加上@EnableFeignClients;
  3. 調用類加上@FeignClient(name = “bubble-member”, path = “/member”)

網關轉發

請求接口能達到預期則說明內建成功

Mr. Cappuccino的第11杯咖啡——冒泡APP(更新版)之項目初始化

如何內建?

  1. 引入gateway、loadbalancer依賴;
  2. boostrap.yml配置轉發路由;

網關swagger統一入口

請求網關整合的swagger頁面,能實作服務之間來回切換并成功請求服務的接口則說明內建成功

Mr. Cappuccino的第11杯咖啡——冒泡APP(更新版)之項目初始化

如何內建?

新增swagger配置類

Mr. Cappuccino的第11杯咖啡——冒泡APP(更新版)之項目初始化

SwaggerProvider.java

package com.bubble.gateway.swagger.config;

import lombok.AllArgsConstructor;
import org.springframework.cloud.gateway.config.GatewayProperties;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.support.NameUtils;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;
import springfox.documentation.swagger.web.SwaggerResource;
import springfox.documentation.swagger.web.SwaggerResourcesProvider;

import java.util.ArrayList;
import java.util.List;

/**
 * @author honey
 * @date 2021-09-07 12:55:09
 */
@Component
@Primary
@AllArgsConstructor
public class SwaggerProvider implements SwaggerResourcesProvider {

    public static final String API_URI = "/v2/api-docs";
    private final RouteLocator routeLocator;
    private final GatewayProperties gatewayProperties;


    @Override
    public List<SwaggerResource> get() {
        List<SwaggerResource> resources = new ArrayList<>();
        List<String> routes = new ArrayList<>();
        routeLocator.getRoutes().subscribe(route -> routes.add(route.getId()));
        gatewayProperties.getRoutes().stream().filter(routeDefinition -> routes.contains(routeDefinition.getId()))
                .forEach(routeDefinition -> routeDefinition.getPredicates().stream()
                        .filter(predicateDefinition -> ("Path").equalsIgnoreCase(predicateDefinition.getName()))
                        .forEach(predicateDefinition -> resources.add(swaggerResource(routeDefinition.getId(),
                                predicateDefinition.getArgs().get(NameUtils.GENERATED_NAME_PREFIX + "0")
                                        .replace("/**", API_URI)))));
        return resources;
    }

    private SwaggerResource swaggerResource(String name, String location) {
        SwaggerResource swaggerResource = new SwaggerResource();
        swaggerResource.setName(name);
        swaggerResource.setLocation(location);
        swaggerResource.setSwaggerVersion("2.0");
        return swaggerResource;
    }
}

           

SwaggerHeaderFilter.java

package com.bubble.gateway.swagger.filter;

import com.bubble.gateway.swagger.config.SwaggerProvider;
import org.apache.commons.lang3.StringUtils;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;

/**
 * @author honey
 * @date 2021-09-07 12:55:09
 */
@Component
public class SwaggerHeaderFilter extends AbstractGatewayFilterFactory<Object> {

    private static final String HEADER_NAME = "X-Forwarded-Prefix";

    @Override
    public GatewayFilter apply(Object config) {
        return (exchange, chain) -> {
            ServerHttpRequest request = exchange.getRequest();
            String path = request.getURI().getPath();
            if (!StringUtils.endsWithIgnoreCase(path, SwaggerProvider.API_URI)) {
                return chain.filter(exchange);
            }
            String basePath = path.substring(0, path.lastIndexOf(SwaggerProvider.API_URI));
            ServerHttpRequest newRequest = request.mutate().header(HEADER_NAME, basePath).build();
            ServerWebExchange newExchange = exchange.mutate().request(newRequest).build();
            return chain.filter(newExchange);
        };
    }
}

           

SwaggerHandler.java

package com.bubble.gateway.swagger.handler;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;
import springfox.documentation.swagger.web.*;

import java.util.Optional;

/**
 * @author honey
 * @date 2021-09-07 12:55:09
 */
@RestController
@RequestMapping("/swagger-resources")
public class SwaggerHandler {


    private SecurityConfiguration securityConfiguration;

    private UiConfiguration uiConfiguration;

    private final SwaggerResourcesProvider swaggerResources;

    @Autowired
    public SwaggerHandler(SwaggerResourcesProvider swaggerResources) {
        this.swaggerResources = swaggerResources;
    }


    @GetMapping("/configuration/security")
    public Mono<ResponseEntity<SecurityConfiguration>> securityConfiguration() {
        return Mono.just(new ResponseEntity<>(Optional.ofNullable(securityConfiguration).orElse(SecurityConfigurationBuilder.builder().build()), HttpStatus.OK));
    }

    @GetMapping("/configuration/ui")
    public Mono<ResponseEntity<UiConfiguration>> uiConfiguration() {
        return Mono.just(new ResponseEntity<>(Optional.ofNullable(uiConfiguration).orElse(UiConfigurationBuilder.builder().build()), HttpStatus.OK));
    }

    @GetMapping("")
    public Mono<ResponseEntity<Object>> swaggerResources() {
        return Mono.just((new ResponseEntity<>(swaggerResources.get(), HttpStatus.OK)));
    }
}

           

注意:boostrap.yml檔案中需要加入配置點

Mr. Cappuccino的第11杯咖啡——冒泡APP(更新版)之項目初始化

好啦,到這裡項目初始化就已經結束啦,小夥伴們有什麼疑問可以咨詢小主喲

逆境總是有的,人生總要進擊。願你不要屈從于命運的安排,堅韌不拔,锲而不舍!做永遠的生活強者!

繼續閱讀