Spring 5 中一个非常重要的更新就是增加了响应式web开发WebFlux,并且推荐使用函数式风格(RouterFunctionHandlerFunction)来开发WebFlux。对于之前主流的MVC开发模式,Spring也顺道给它提供了和WebFlux函数式开发几乎一致的方式(见上文《Spring 5 MVC 中的 Router Function 使用》)。这样,响应式WebFlux和非响应式MVC都可以通过Controller来实现,也都可以通过RouterFunction来实现。

但是Spring推荐使用函数式方式;而且听说在所有场景也推荐使用WebFlux,后续有可能废弃掉非响应式MVC

对于通过Controller来实现的接口,swagger可以直接扫描处理。使用了RouterFunction的怎么办呢?这篇文章我们来看一下如果通过springdoc这个项目来实现函数式接口的文档生成。

pom依赖

假设你使用的是maven。如果使用gradle我估计也差不多

要使用springdoc-openapi,需要添加它的依赖。一般需要两个,第一个是基础公共依赖:

<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>1.5.9</version>
</dependency>

另一个根据对象不同需要引入的也不同。我们这里先处理非响应式MVC的接口,需要依赖

<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-webmvc-core</artifactId>
<version>1.5.9</version>
</dependency>

依赖的版本号可以自己去查一下最新的

RouterOperation

接下来需要去RouterFunction上面定义swagger的显示信息,在controller中使用的注解是io.swagger.v3.oas.annotations.Operation(如果是版本2使用的注解是io.swagger.annotations.ApiOperation),现在需要使用org.springdoc.core.annotations.RouterOperation。以《Spring 5 MVC 中的 Router Function 使用》中的接口为例,需要这样写

@Configuration
public class RoutingConfig { @Bean
@RouterOperations({
@RouterOperation(
path = "/model/building/{entId}/stations",
beanClass = ModelBuildingHandler.class,
beanMethod = "getStations",
method = RequestMethod.GET,
operation = @Operation(
operationId = "getStations",
parameters = @Parameter(
name = "entId",
in = ParameterIn.PATH,
required = true,
description = "企业ID"
)
)
)
})
public RouterFunction<ServerResponse> getModelBuildingRouters(ModelBuildingHandler modelBuildingHandler) {
return RouterFunctions.nest(path("/model/building"),
RouterFunctions.route(GET("/{entId}/stations"), modelBuildingHandler::getStations)
.andRoute(GET("/{stationId}/device-types"), modelBuildingHandler::getDeviceTypes)
);
}
}

不同于Controller中的接口会被自动发现,这里虽然有两个方法但是我们只定义了一个RouterOperation操作,会导致看不到第二个方法。

我们修改一下application.properties就能看到效果了:

springdoc.packagesToScan=要扫描的包
springdoc.pathsToMatch=/**

注意springdoc.packagesToScan这里,需要写一个包含了RouterFunctionHandlerFunction实现的包。我当时只写了RouterFunction所在的包,一直不成功

再响应增加一个RouterOperation即可:

@RouterOperations({
@RouterOperation(
path = "/model/building/{entId}/stations",
beanClass = ModelBuildingHandler.class,
beanMethod = "getStations",
method = RequestMethod.GET,
operation = @Operation(
operationId = "getStations",
parameters = @Parameter(
name = "entId",
in = ParameterIn.PATH,
required = true,
description = "企业ID"
)
)
),
@RouterOperation( // 这里我省略了一些属性配置
path = "/model/building/{stationId}/device-types",
beanClass = ModelBuildingHandler.class,
beanMethod = "getDeviceTypes"
)
})

RequestBody

上面讲的都是GET的请求,如果需要设置请求体格式怎么办呢?

在RouterFunction中增加一个POST请求(下面最后一个url):

public RouterFunction<ServerResponse> getModelBuildingRouters(ModelBuildingHandler modelBuildingHandler) {
return RouterFunctions.nest(
path("/model/building"),
RouterFunctions.route(GET("/{entId}/stations"), modelBuildingHandler::getStations)
.andRoute(GET("/{stationId}/device-types"), modelBuildingHandler::getDeviceTypes)
.andRoute(POST("/devices/points/real-time-data"), modelBuildingHandler::getRealTimeData)
);
}

它对应的RouterOperation如下:

@RouterOperation(
path = "/model/building/devices/points/real-time-data",
beanClass = ModelBuildingHandler.class,
beanMethod = "getRealTimeData",
operation = @Operation(
operationId = "getRealTimeData",
requestBody = @RequestBody(
required = true,
description = "请求体",
content = @Content(
schema = @Schema(implementation = RealTimeDataQueryVO.class)
)
)
)
)

要在Handler中拿到请求参数,使用body方法:RealTimeDataQueryVO queryVo = req.body(RealTimeDataQueryVO.class);

public ServerResponse getRealTimeData(ServerRequest req) {
RealTimeDataQueryVO queryVo;
try {
queryVo = req.body(RealTimeDataQueryVO.class);
log.info("请求参数{}", queryVo);
} catch (Exception e) {
throw new RuntimeException(e);
}
RealTimeDataResultBO resultBo = modelBuildingService.getRealTimeData(transferRealTimeDataQueryParam(queryVo));
return body(RdfaResult.success(transferRealTimeDataResult(resultBo)));
}

上面就是如何在函数式MVC编程中使用swagger。可以看到比较繁琐,3行代码对应了差不多30行swagger配置。

从swagger v2 迁移

如果之前的项目使用的是springfox之类的swagger版本2,需要将其依赖移除,并修改类上的注解。

如何修改可以参考 https://springdoc.org/#migrating-from-springfox

主要的变更点如下图:

Swagger配置

这一步是可选的,几乎没什么必要。

可以像之前一样定义文档的归属、协议、版本等等:

@Configuration
public class DocConfig {
@Bean
public OpenAPI springShopOpenApi() {
return new OpenAPI()
.info(new Info().title("测试 API")
.description("样例程序")
.version("v0.0.1")
.license(new License()
.name("Apache 2.0我的协议")
.url("http://springdoc.org")))
.externalDocs(new ExternalDocumentation()
.description("外部文档链接")
.url("https://springshop.wiki.github.org/docs"));
}
}

WebFlux 中的文档

如果项目不是mvc的而是webFlux的,相应的Maven依赖改成下面的即可:

<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-webflux-ui</artifactId>
<version>1.5.12</version>
</dependency>

其他类似。

Spring 5 中函数式web开发中的swagger文档的更多相关文章

  1. SpringBoot+SpringCloud+vue+Element开发项目——集成Swagger文档

    在pom.xml文件中添加Maven依赖 <!--swagger--> <dependency> <groupId>io.springfox</groupId ...

  2. Spring在web开发中的应用

    (1)在 web 项目中要使用 spring 需要导入一个 jar 包: spring-web-4.2.4.jar包 (2)在 web.xml 文件中配置 Listener <listener& ...

  3. MVC已经是现代Web开发中的一个很重要的部分,下面介绍一下Spring MVC的一些使用心得。

    MVC已经是现代Web开发中的一个很重要的部分,下面介绍一下Spring MVC的一些使用心得. 之前的项目比较简单,多是用JSP .Servlet + JDBC 直接搞定,在项目中尝试用 Strut ...

  4. 依赖注入及AOP简述(十)——Web开发中常用Scope简介 .

    1.2.    Web开发中常用Scope简介 这里主要介绍基于Servlet的Web开发中常用的Scope. l        第一个比较常用的就是Application级Scope,通常我们会将一 ...

  5. Web开发中Listener、Filter、Servlet的初始化及调用

    我们在使用Spring+SpringMVC开发项目中,web.xml中一般的配置如下: <?xml version="1.0" encoding="UTF-8&qu ...

  6. SpringBoot学习(七)-->SpringBoot在web开发中的配置

    SpringBoot在web开发中的配置 Web开发的自动配置类:在Maven Dependencies-->spring-boot-1.5.2.RELEASE.jar-->org.spr ...

  7. 【初码干货】使用阿里云对Web开发中的资源文件进行CDN加速的深入研究和实践

    提示:阅读本文需提前了解的相关知识 1.阿里云(https://www.aliyun.com) 2.阿里云CDN(https://www.aliyun.com/product/cdn) 3.阿里云OS ...

  8. Web 开发中很实用的10个效果【附源码下载】

    在工作中,我们可能会用到各种交互效果.而这些效果在平常翻看文章的时候碰到很多,但是一时半会又想不起来在哪,所以养成知识整理的习惯是很有必要的.这篇文章给大家推荐10个在 Web 开发中很有用的效果,记 ...

  9. WEB开发中的字符集和编码

    html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,bi ...

随机推荐

  1. CodeForce-807C Success Rate(二分数学)

    Success Rate CodeForces - 807C 给你4个数字 x y p q ,要求让你求最小的非负整数b,使得 (x+a)/(y+b)==p/q,同时a为一个整数且0<=a< ...

  2. 反转链表middle

    eg: 输入:head = [1,2,3,4,5], left = 2, right = 4 输出:[1,4,3,2,5]相关解法:图解: /** * Definition for singly-li ...

  3. TP5路由的位置导致错误

    // 测试 '[js]' => [ ':id' => ['test/test/js', ['method' => 'get'], ['id' => '\d+']], ':id/ ...

  4. Linux下Nodejs安装(完整详细)转

    Linux下安装有两种方式,一个是下载源码make编译安装. 另外一种是比较推荐的,直接下载编译好的二进制,官方比较推荐后者. //Linux 64bit version wget --no-chec ...

  5. Jmeter系列(13)- 数据库操作之JDBC Connection Configuration配置元件、JDBC Request取样器

    Jmeter常见操作数据库场景 准备.制造测试数据 获取.查询测试数据 数据库数据作为参数引用 清理测试环境.删除过程数据 数据库压测 Jmeter操作数据库环境准备 已经安装好的数据库,比如MySq ...

  6. jenkins+requests+pytest+allure持续集成

    环境搭建参考:https://www.jianshu.com/p/fc39030d057f 总体流程:

  7. 自动化测试报告----allure2(一)

    以前都是使用TestNG自带的报告.jenkins中的报告等但没有个性化装饰报告,然而接触过allure2后发现原来报告还可以这么酷,接下来就带大家一起看一下allure2 报告炫在哪里? 我们先看如 ...

  8. 入坑Java的自学之路

    # 入坑Java的自学之路 ## 基础知识 - 编程语言:Java python c- 基本算法- 基本网络知识 tcp/ip http/https- 基本的设计模式 ------ ## 工具方面 - ...

  9. 修改为阿里的yum源

    如果没有wget,先安装一个.(如果有请蹦过) yum install wget -y 备份本地yum源 mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.r ...

  10. mybatis多条件多值批量更新

    mysql并没有提供直接的方法来实现批量更新,但是可以用点小技巧来实现. 这里使用了case when 这个小技巧来实现批量更新. 举个例子: UPDATE 表名 SET    display_ord ...