Springboot3 – 整合各类系统查询
整合 Swagger 3
Swagger 可以快速生成实时接口文档,方便前后开发人员进行协调沟通。遵循 OpenAPI 规范。
文档:https://springdoc.org/v2/
OpenAPI 3 架构
整合 Swigger
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>2.1.0</version>
</dependency>
配置 Swigger
详细配置可以找到 AutoConfiguration 类中引入的properties
# /api-docs endpoint custom path 默认 /v3/api-docs
springdoc.api-docs.path=/api-docs
# swagger 相关配置在 springdoc.swagger-ui
# swagger-ui custom path
springdoc.swagger-ui.path=/swagger-ui.html
springdoc.show-actuator=true
Swigger 常用注解使用
注解 |
标注位置 |
作用 |
@Tag |
controller 类 |
标识 controller 作用 |
@Parameter |
参数 |
标识参数作用 |
@Parameters |
参数 |
参数多重说明 |
@Schema |
model 层的 JavaBean |
描述模型作用及每个属性 |
@Operation |
方法 |
描述方法作用 |
@ApiResponse |
方法 |
描述响应状态码等 |
Docket配置
Docket 是用于配置总体Swigger文档信息的类,我们可以通过配置Docket来自定义Swigger进行文档管理分组功能
// 设置分组
@Bean
public GroupedOpenApi publicApi() {
return GroupedOpenApi.builder()
.group("员工管理组")
.pathsToMatch("/dept/**")
.build();
}
@Bean
public GroupedOpenApi adminApi() {
return GroupedOpenApi.builder()
.group("管理组")
.pathsToMatch("/admin/**")
.addMethodFilter(method -> method.isAnnotationPresent(Admin.class))
.build();
}
对整个Doc文档进行设置
@Bean
public OpenAPI springShopOpenAPI() {
return new OpenAPI()
.info(new Info().title("SpringShop API") // 文档标题
.description("Spring shop sample application") // 文档详细说明
.version("v0.0.1") // 文档版本
.license(new License().name("Apache 2.0").url("http://springdoc.org"))) // 文档协议
.externalDocs(new ExternalDocumentation()
.description("SpringShop Wiki Documentation") // 次详细说明
.url("https://springshop.wiki.github.org/docs"));
}
Springfox 迁移
注解变化
原注解 |
现注解 |
作用 |
@Api |
@Tag |
描述Controller |
@ApiIgnore |
@Parameter(hidden = true) |
描述忽略操作 |
@ApiImplicitParam |
@Parameter |
描述参数 |
@ApiImplicitParams |
@Parameters |
描述参数 |
@ApiModel |
@Schema |
描述对象 |
@ApiModelProperty(hidden = true) |
@Schema(accessMode = READ_ONLY) |
描述对象属性 |
@ApiModelProperty |
@Schema |
描述对象属性 |
@ApiOperation(value = "foo", notes = "bar") |
@Operation(summary = "foo", description = "bar") |
描述方法 |
@ApiParam |
@Parameter |
描述参数 |
@ApiResponse(code = 404, message = "foo") |
@ApiResponse(responseCode = "404", description = "foo") |
描述响应 |
Docket配置
以前写法:
@Bean
public Docket publicApi() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.basePackage("org.github.springshop.web.public"))
.paths(PathSelectors.regex("/public.*"))
.build()
.groupName("springshop-public")
.apiInfo(apiInfo());
}
@Bean
public Docket adminApi() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.basePackage("org.github.springshop.web.admin"))
.paths(PathSelectors.regex("/admin.*"))
.apis(RequestHandlerSelectors.withMethodAnnotation(Admin.class))
.build()
.groupName("springshop-admin")
.apiInfo(apiInfo());
}
新写法:
@Bean
public GroupedOpenApi publicApi() {
return GroupedOpenApi.builder()
.group("springshop-public")
.pathsToMatch("/public/**")
.build();
}
@Bean
public GroupedOpenApi adminApi() {
return GroupedOpenApi.builder()
.group("springshop-admin")
.pathsToMatch("/admin/**")
.addOpenApiMethodFilter(method -> method.isAnnotationPresent(Admin.class))
.build();
}
OpenAPI组件
@Bean
public OpenAPI springShopOpenAPI() {
return new OpenAPI()
.info(new Info().title("SpringShop API")
.description("Spring shop sample application")
.version("v0.0.1")
.license(new License().name("Apache 2.0").url("http://springdoc.org")))
.externalDocs(new ExternalDocumentation()
.description("SpringShop Wiki Documentation")
.url("https://springshop.wiki.github.org/docs"));
}
远程调用 RPC
WebClient 响应式编程开发
WebClient 是一个非阻塞、响应式HTTP客户端
使用 WebClient 非常简单
步骤:
- 1.创建WebClient对象
-
//获取响应完整信息 WebClient client = WebClient.create("https://example.org");
- 2.如果希望使用get方式请求api的,则使用 client.get()即可,使用链式调用设置header或param 参数等,使用 retrieve() 方法来发送请求,接收数据可以使用 toEntity来封装成对象,也可以使用 bodyToMono()接收,Mono 是一个非阻塞式的响应对象
-
//获取响应完整信息 WebClient client = WebClient.create("https://example.org"); Mono<ResponseEntity<Person>> result = client.get() .uri("/persons/{id}", id).accept(MediaType.APPLICATION_JSON) .retrieve() .toEntity(Person.class); //只获取body WebClient client = WebClient.create("https://example.org"); Mono<Person> result = client.get() .uri("/persons/{id}", id).accept(MediaType.APPLICATION_JSON) .retrieve() .bodyToMono(Person.class); //stream数据 Flux<Quote> result = client.get() .uri("/quotes").accept(MediaType.TEXT_EVENT_STREAM) .retrieve() .bodyToFlux(Quote.class); //定义错误处理 Mono<Person> result = client.get() .uri("/persons/{id}", id).accept(MediaType.APPLICATION_JSON) .retrieve() .onStatus(HttpStatus::is4xxClientError, response -> ...) .onStatus(HttpStatus::is5xxServerError, response -> ...) .bodyToMono(Person.class);
创建 WebClient 非常简单:
● WebClient.create()
● WebClient.create(String baseUrl)
还可以使用 WebClient.builder() 配置更多参数项:
● uriBuilderFactory: 自定义UriBuilderFactory ,定义 baseurl.
● defaultUriVariables: 默认 uri 变量.
● defaultHeader: 每个请求默认头.
● defaultCookie: 每个请求默认 cookie.
● defaultRequest: Consumer 自定义每个请求.
● filter: 过滤 client 发送的每个请求
● exchangeStrategies: HTTP 消息 reader/writer 自定义.
● clientConnector: HTTP client 库设置.
Http Interface 声明式编程
Spring 允许我们通过定义接口的方式,给任意位置发送 http 请求,实现远程调用,可以用来简化 HTTP 远程访问。需要webflux场景才可
导入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
定义接口
Http Interface 是使用了类似 OpenFeign 的接口式请求方式,通过定义一个接口,其接口方法中定义请求的url连接,和需要提交的参数或头信息,通过WebClient来创建代理对象
public interface BingService {
@GetExchange(url = "/search")
String search(@RequestParam("q") String keyword); // 需要提交什么参数或头信息则在形参中定义
}
创建代理工厂
配置好Web请求的代理工厂,这个工厂是用于创建请求接口的代理对象,通过工厂创建出来的代理对象,可以实现请求转发功能
@SpringBootTest
class Boot05TaskApplicationTests {
@Test
void contextLoads() throws InterruptedException {
//1、创建客户端,可以把这个创建过程提取为一个 Bean,然后我们就可以在Ioc中取得这个工厂创建器来创建不同url的接口代理对象了
WebClient client = WebClient.builder()
.baseUrl("https://cn.bing.com") // 如果有多个不同的url 这里可以不设置,而是在接口的 @GetExchange 这类注解上设置全url地址
.defaultHeader("Auth","xxxx") // 如果每一个不同url 都是使用相同的头信息进行认证配置的,可以在这里直接设置统一的头信息,就不需要接口中定义了
.codecs(clientCodecConfigurer -> {
clientCodecConfigurer
.defaultCodecs()
.maxInMemorySize(256*1024*1024);
//响应数据量太大有可能会超出BufferSize,所以这里设置的大一点
})
.build();
//2、创建工厂
HttpServiceProxyFactory factory = HttpServiceProxyFactory
.builder(WebClientAdapter.forClient(client)).build();
//3、获取代理对象
BingService bingService = factory.createClient(BingService.class);
//4、测试调用
Mono<String> search = bingService.search("尚硅谷");
System.out.println("==========");
search.subscribe(str -> System.out.println(str));
Thread.sleep(100000);
}
}
共有 0 条评论