# 系统接口

# 基本介绍

参考系统接口实现

# 如何使用

1、添加依赖

<!-- SpringBoot Web -->
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<!-- Swagger -->
<dependency>
	<groupId>io.springfox</groupId>
	<artifactId>springfox-swagger2</artifactId>
	<version>${swagger.fox.version}</version>
</dependency>

<!-- Swagger UI -->
<dependency>
	<groupId>io.springfox</groupId>
	<artifactId>springfox-swagger-ui</artifactId>
	<version>${swagger.fox.version}</version>
</dependency>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

2、在application.yml添加服务配置

server:
  port: 6666

spring:
  application:
    name: ruoyi-xxxx
1
2
3
4
5
6

3、在Application启动类加入注解@SpringBootApplication

@EnableSwagger2
@SpringBootApplication
public class RuoYiSwaggerApplication
{
    public static void main(String[] args)
    {
        SpringApplication.run(RuoYiSwaggerApplication.class, args);
        System.out.println("(♥◠‿◠)ノ゙  Swagger启动成功   ლ(´ڡ`ლ)゙  \n" +
                " .-------.       ____     __        \n" +
                " |  _ _   \\      \\   \\   /  /    \n" +
                " | ( ' )  |       \\  _. /  '       \n" +
                " |(_ o _) /        _( )_ .'         \n" +
                " | (_,_).' __  ___(_ o _)'          \n" +
                " |  |\\ \\  |  ||   |(_,_)'         \n" +
                " |  | \\ `'   /|   `-'  /           \n" +
                " |  |  \\    /  \\      /           \n" +
                " ''-'   `'-'    `-..-'              ");
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

4、添加TestUserController.java,模拟接口返回用户信息。

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TestUserController
{
    @GetMapping("/user/info")
    public Object info()
    {
        return "{\"username\":\"admin\",\"password\":\"admin123\"}";
    }
}
1
2
3
4
5
6
7
8
9
10
11
12

5、访问http://localhost:6666/swagger-ui/index.html,测试验证接口返回正确数据表示测试通过。

# 接口模块

项目中存在ruoyi-common-swagger模块,可以直接依赖后使用。

1、业务模块添加依赖

<!-- ruoyi common swagger -->
<dependency>
	<groupId>com.ruoyi</groupId>
	<artifactId>ruoyi-common-swagger</artifactId>
</dependency>
1
2
3
4
5

2、在ruoyi-xxxx-dev.yml添加swagger配置

# swagger配置
swagger:
  title: 系统模块接口文档
  license: Powered By ruoyi
  licenseUrl: https://ruoyi.vip
1
2
3
4
5

3、在Application启动类加入系统接口注解@EnableCustomSwagger2


 




















@EnableCustomConfig
@EnableCustomSwagger2
@EnableRyFeignClients
@SpringCloudApplication
public class RuoYiSystemApplication
{
    public static void main(String[] args)
    {
        SpringApplication.run(RuoYiSystemApplication.class, args);
        System.out.println("(♥◠‿◠)ノ゙  系统模块启动成功   ლ(´ڡ`ლ)゙  \n" +
                " .-------.       ____     __        \n" +
                " |  _ _   \\      \\   \\   /  /    \n" +
                " | ( ' )  |       \\  _. /  '       \n" +
                " |(_ o _) /        _( )_ .'         \n" +
                " | (_,_).' __  ___(_ o _)'          \n" +
                " |  |\\ \\  |  ||   |(_,_)'         \n" +
                " |  | \\ `'   /|   `-'  /           \n" +
                " |  |  \\    /  \\      /           \n" +
                " ''-'   `'-'    `-..-'              ");
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

4、测试验证

访问http://{ip}:{port}/swagger-ui/index.html地址,出现如下图表示成功。

swagger

# 接口聚合

访问swagger-ui.html的时候会发现右上角的Select a spec这个下拉选项

swagger

当启动一个springboot项目的时候会发现这个下拉选项毫无用处,不过它的强大是在于这个下拉可以用来切换不同项目的swagger接口地址,这就实现了使用一个网关的url访问所有的项目接口。

1、网关模块添加依赖

<!-- SpringCloud Gateway -->
<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>

<!-- SpringCloud Alibaba Nacos -->
<dependency>
	<groupId>com.alibaba.cloud</groupId>
	<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
		
<!-- Swagger UI -->
<dependency>
	<groupId>io.springfox</groupId>
	<artifactId>springfox-swagger-ui</artifactId>
	<version>${swagger.fox.version}</version>
</dependency>

<!-- Swagger -->
<dependency>
	<groupId>io.springfox</groupId>
	<artifactId>springfox-swagger2</artifactId>
	<version>${swagger.fox.version}</version>
</dependency>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

2、网关服务创建一个类SwaggerProvider.java实现SwaggerResourcesProvider

package com.ruoyi.gateway.config;

import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.config.GatewayProperties;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.support.NameUtils;
import org.springframework.stereotype.Component;
import springfox.documentation.swagger.web.SwaggerResource;
import springfox.documentation.swagger.web.SwaggerResourcesProvider;

/**
 * 聚合系统接口
 * 
 * @author ruoyi
 */
@Component
public class SwaggerProvider implements SwaggerResourcesProvider
{
    /**
     * Swagger2默认的url后缀
     */
    public static final String SWAGGER2URL = "/v2/api-docs";
    /**
     * 网关路由
     */
    @Autowired
    private RouteLocator routeLocator;

    @Autowired
    private GatewayProperties gatewayProperties;

    /**
     * 聚合其他服务接口
     * 
     * @return
     */
    @Override
    public List<SwaggerResource> get()
    {
        List<SwaggerResource> resourceList = new ArrayList<>();
        List<String> routes = new ArrayList<>();
        // 获取网关中配置的route
        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()))
                        .filter(predicateDefinition -> !"ruoyi-auth".equalsIgnoreCase(routeDefinition.getId()))
                        .forEach(predicateDefinition -> resourceList
                                .add(swaggerResource(routeDefinition.getId(), predicateDefinition.getArgs()
                                        .get(NameUtils.GENERATED_NAME_PREFIX + "0").replace("/**", SWAGGER2URL)))));
        return resourceList;
    }

    private SwaggerResource swaggerResource(String name, String location)
    {
        SwaggerResource swaggerResource = new SwaggerResource();
        swaggerResource.setName(name);
        swaggerResource.setLocation(location);
        swaggerResource.setSwaggerVersion("2.0");
        return swaggerResource;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66

3、创建一个聚合接口类SwaggerHandler.java

package com.ruoyi.gateway.handler;

import java.util.Optional;
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.SecurityConfiguration;
import springfox.documentation.swagger.web.SecurityConfigurationBuilder;
import springfox.documentation.swagger.web.SwaggerResourcesProvider;
import springfox.documentation.swagger.web.UiConfiguration;
import springfox.documentation.swagger.web.UiConfigurationBuilder;

@RestController
@RequestMapping("/swagger-resources")
public class SwaggerHandler
{
    @Autowired(required = false)
    private SecurityConfiguration securityConfiguration;

    @Autowired(required = false)
    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));
    }

    @SuppressWarnings("rawtypes")
    @GetMapping("")
    public Mono<ResponseEntity> swaggerResources()
    {
        return Mono.just((new ResponseEntity<>(swaggerResources.get(), HttpStatus.OK)));
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56

4、配置注册中心及路由信息

spring:
  application:
    name: ruoyi-swagger-test
  cloud:
    nacos:
      discovery:
        # 服务注册地址
        server-addr: 127.0.0.1:8848
    gateway:
      routes:
        # 认证中心
        - id: ruoyi-auth
          uri: lb://ruoyi-auth
          predicates:
            - Path=/auth/**
          filters:
            - StripPrefix=1
        # 系统模块
        - id: ruoyi-system
          uri: lb://ruoyi-system
          predicates:
            - Path=/system/**
          filters:
            - StripPrefix=1
        # 代码生成
        - id: ruoyi-gen
          uri: lb://ruoyi-gen
          predicates:
            - Path=/code/**
          filters:
            - StripPrefix=1
        # 定时任务
        - id: ruoyi-job
          uri: lb://ruoyi-job
          predicates:
            - Path=/schedule/**
          filters:
            - StripPrefix=1
        # 文件服务
        - id: ruoyi-file
          uri: lb://ruoyi-file
          predicates:
            - Path=/file/**
          filters:
            - StripPrefix=1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45

5、测试验证

打开浏览器,输入:(http://localhost:8080/swagger-ui/index.html (opens new window))

swagger

选择切换不同服务的swagger接口

# 全局授权

在测试系统接口中可能存在一些接口用到用户信息或权限验证,此时需要添加全局的token参数。如图

swagger

token是在登录成功后返回的,可以在浏览器通过F12查看Network中的请求地址,对应参数Authorization。复制截图内容到swagger全局Authorization属性value参数中,点击Authorize,以后每次访问接口会携带此token信息。

swagger

# 整合knife4j

Spring Cloud的微服务架构下,每个微服务并不需要引入前端的ui资源,因此在每个微服务的Spring Boot项目下,引入ruoyi-common-swagger提供的starter即可。

1、在ruoyi-gateway网关模块下,把knife4j依赖资源引入

<!-- knife4j -->
<dependency>
	<groupId>com.github.xiaoymin</groupId>
	<artifactId>knife4j-spring-ui</artifactId>
	<version>3.0.3</version>
</dependency>
<dependency>
	<groupId>com.github.xiaoymin</groupId>
	<artifactId>knife4j-spring-boot-starter</artifactId>
	<version>3.0.3</version>
</dependency>
1
2
3
4
5
6
7
8
9
10
11

2、在ruoyi-common-swagger系统接口模块下,把knife4j依赖资源引入

<!-- knife4j -->
<dependency>
	<groupId>com.github.xiaoymin</groupId>
	<artifactId>knife4j-spring-boot-starter</artifactId>
	<version>3.0.3</version>
</dependency>
1
2
3
4
5
6

3、在其他ruoyi-xxxx-xxxx服务下,把ruoyi-common-swagger依赖资源引入

<!-- RuoYi Common Swagger -->
<dependency>
	<groupId>com.ruoyi</groupId>
	<artifactId>ruoyi-common-swagger</artifactId>
</dependency>
1
2
3
4
5

4、在SwaggerProvider.java的类注解追加@Primary

5、测试验证

访问http://{ip}:{port}/doc.html地址,出现如下图表示成功。

knife4j

重复swagger依赖剔除

ruoyi-common-swagger引用knife4j-spring-boot-starter依赖,其中的springfox-swagger2依赖可以删除。
ruoyi-gateway引用knife4j-spring-uiknife4j-spring-boot-starter依赖,其中的springfox-swagger-uispringfox-swagger2依赖可以删除。