百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程字典 > 正文

"丝袜哥"Swagger来了(整合SpringBoot)

toyiye 2024-06-21 12:36 11 浏览 0 评论


  • 了解Swagger的作用和概念
  • 了解前后端分离
  • SpringBoot继承Swagger

一、Swagger简介

1. 前后端分离

后端时代:前端只用管理静态页面;html等静态资源交给后端通过模板引擎进行渲染

前后端分离时代

  • 后端:控制层controller、服务层service、数据访问层dao
  • 前端:前端控制层、视图层
  • 前后端交互:通过API接口
  • 前后端相对独立,松耦合,甚至可以部署在不同的服务器上

随之产生的问题:前后端联调,前端人员和后端人员无法做到及时协商,尽早解决

解决方案

  • 首先指定schema,实时更新最新的API,降低集成风险
  • 早些年:指定word计划文档
  • 前后端分离:
    • 前端测试后端接口数据是否正确:postman
    • 后端提供接口,需要实时更新最新的消息和改动

于是Swagger应运而生

2. Swagger引入

  • 号称历史上最流行的api框架
  • RestFul Api文档在线生成工具=》Api文档与Api定义同步更新
  • 直接运行,可以在线测试Api接口
  • 支持多种语言

官网:https://swagger.io/

二、SpringBoot集成Swagger

1. 新建springboot项目

首先新建一个spirngboot项目,勾选组件时勾选Spring-Web



2. 导入Swagger依赖

springfox-swagger2

<!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger2 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>3.0.0</version>
</dependency>

springfox-swagger-ui

<!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger-ui -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>3.0.0</version>
</dependency>


3. 编写HelloController测试

我们编写一个controller来测试一下项目是否搭建成功,在主程序同级目录下新建controller包,其中新建HelloController

package com.zsr.controller;

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

@RestController
public class HelloController {
@RequestMapping(
"/hello")
public String
hello() {
return "hello";
}
}

然后启动主程序,访问localhost:8080/hello,出现如下结果即成功



4. 编写Swagger配置类

在主程序同级目录下新建config包,其中新建SwaggerConfig配置类

记住用@Configuration注解注明这是配置类

同时用@EnableSwagger2注解开启Swagger2

package com.zsr.config;

import org.springframework.context.annotation.Configuration;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

@Configuration
@EnableSwagger2//开启Swagger2
public class SwaggerConfig {

}



5. 测试进入Sawgger页面

重启主程序,访问localhost:8080/swagger-ui.html

启动报错:@EnableSwagger2注解找不到,但是已经导入了对应的jar包

这时候降级为2.9.2即可使用

<!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger2 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>

<!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger-ui -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>

再次启动主程序即可成功,然后访问localhost:8080/swagger-ui.html,即可进入到以下界面

这个界面是Swagger为我们提供的ui界面,我们可以在源码中找到它



6. 配置Swagger API信息

在Swagger提供的ui界面,其中的Swagger信息模块我们可以自定义信息内容

我们只需要在Swagger配置类SwaggerConfig中实例化Docket类队对象的bean实例,通过配置ApiInfo类的信息然后传入Docket的bean实例即可

package com.zsr.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.service.VendorExtension;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

import java.util.ArrayList;

@Configuration
@EnableSwagger2//开启Swagger2
public class SwaggerConfig {
//配置Swagger的Docket的bean实例
@Bean
public Docket
docket() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo());//配置Swagger信息
}

//配置Swagger信息
private ApiInfo
apiInfo() {
return new ApiInfo(
"Baret-H",
"我的Swagger API文档",
"1.0",
"https://bareth.blog.csdn.net/",
new Contact(
"Baret-H", "https://bareth.blog.csdn.net/", "1412578784@qq.com"),//作者信息
"Apache 2.0",
"http://www.apache.org/licenses/LICENSE-2.0",
new ArrayList<VendorExtension>());
}
}

重启主程序测试,可以看到Swagger信息已经变更成我们定义的信息



7. 配置Swagger自定义扫描接口

我们在这个ui界面中,可以看到扫描了两个controller接口

  • 一个是默认的/error请求,也就是我们启动springboot主程序未加配置默认访问8080端口的默认controller
  • 另一个是我们自己写的/hello请求,对应着HelloController,由于我们用的@RequsetMapping注解,所以请求的方式有以上的六种

接下来我们自己配置以下要扫描的接口

@Bean
public Docket
docket() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())//配置Swagger信息
.select()
/**
* apis():指定扫描的接口
* RequestHandlerSelectors:配置要扫描接口的方式
* basePackage:指定要扫描的包
* any:扫面全部
* none:不扫描
* withClassAnnotation:扫描类上的注解(参数是类上注解的class对象)
* withMethodAnnotation:扫描方法上的注解(参数是方法上的注解的class对象)
*/
.apis(RequestHandlerSelectors.basePackage(
"com.zsr.controller"))
/**
* paths():过滤路径
* PathSelectors:配置过滤的路径
* any:过滤全部路径
* none:不过滤路径
* ant:过滤指定路径:按照按照Spring的AntPathMatcher提供的match方法进行匹配
* regex:过滤指定路径:按照String的matches方法进行匹配
*/
.paths(PathSelectors.ant(
"/zsr/**"))
.build();
}

其中.select().apis.paths.build是一套组合进行使用

然后我们启动主程序访问localhost:8080/swagger-ui.html进行测试

可以发现No opertations defined in spec,这是因为我们过滤了/zsr下的所有controller

我们将过滤条件更改为过滤全部路径

.paths(PathSelectors.any)

再次启动主程序访问localhost:8080/swagger-ui.html

可以看到只显示了我们上述自定义的com.zsr.controller下的接口HelloController

.apis(RequestHandlerSelectors.basePackage("com.zsr.controller"))



8. 配置是否启动Swagger

我么通过Docket对象的.enable方法来配置swagger是否启动

@Bean
public Docket
docket() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())//配置Swagger信息
.
enable(false)//配置是否启动swagger,默认为true
.select()
.apis(RequestHandlerSelectors.basePackage(
"com.zsr.controller"))
.paths(PathSelectors.ant(
"/zsr/**"))
.build();
}

更改为false后启动测试一下,查看控制台,无法进入到swagger页面

如果我们有这样一个需求:希望Swagger在开发环境中,在正式环境时不能使用

首先要判断是不是开发环境,可以设置一个flag表示用来表示:flag=1即表示生产环境

然后将flag的值传给enable(flag)

首先在resources目录下新建两种springboot配置文件:

  • 开发环境:application-dev.properties
  • server.port=8081
  • 正式环境:application-pro.properties
  • server.port=8082

然后在主配置文件application.properties中激活开发环境

spring.profiles.active=dev

然后我们到SwaggerConfig中的docket()方法中添加代码:

  • 首先给该方法传一个参数Environment的实例

Environment environment

  • 首先设置药配置的Swagger环境:这里可以添加多个环境
  • Profiles profiles = Profiles.of("dev", "test");
  • 然后通过environment.acceptsProfiles方法判断是否处在上一步设定的dev/test环境中,返回一个boolean的值,我们用flag接收
  • boolean flag = environment.acceptsProfiles(profiles);
  • 然后修改enable中的参数为flag,即通过flag来判断是否开启Swagger
  • .enable(flag)//通过flag判断是否开启

完整代码

@Configuration
@EnableSwagger2//开启Swagger2
public class SwaggerConfig {
//配置Swagger的Docket的bean实例
@Bean
public Docket docket(Environment environment) {
//设置要配置的Swagger环境
Profiles profiles = Profiles.of(
"dev", "test");
//通过environment.acceptsProfiles判断是否处在自己设定的环境中
boolean flag = environment.acceptsProfiles(profiles);

return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())//配置Swagger信息
.
enable(flag)//通过flag判断是否开启
.select()
.apis(RequestHandlerSelectors.basePackage(
"com.zsr.controller"))
.paths(PathSelectors.ant(
"/zsr/**"))
.build();
}

//配置Swagger信息
private ApiInfo
apiInfo() {
return new ApiInfo(
"Baret-H",
"我的Swagger API文档",
"1.0",
"https://bareth.blog.csdn.net/",
new Contact(
"Baret-H", "https://bareth.blog.csdn.net/", "1412578784@qq.com"),//作者信息
"Apache 2.0",
"http://www.apache.org/licenses/LICENSE-2.0",
new ArrayList<VendorExtension>());
}
}

然后启动主程序测试:由于激活了dev开发环境,所以访问localhost:8081/swagger-ui.html

成功开启swagger,如果我们修改主配置文件,激活pro正式发布环境

spring.profiles.active=pro

再次重启主程序测试,访问端口8082对应的地址localhost:8082/swagger-ui.html

无法进入,因为pro环境不在我们配置的test/dev环境中,所以无法开启



9. 配置API文档分组

1. 设置默认组名

可以看到,我们默认只有一个组且组名为default

我们可以在docket通过.groupName中设置组名

public Docket docket(Environment environment) {
//设置要配置的Swagger环境
Profiles profiles = Profiles.of(
"dev", "test");
//通过environment.acceptsProfiles判断是否处在自己设定的环境中
boolean flag = environment.acceptsProfiles(profiles);

return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())//配置Swagger信息
.groupName(
"zsr")
.
enable(true)//配置是否启动swagger,默认为true
.select()
.apis(RequestHandlerSelectors.basePackage(
"com.zsr.controller"))
.paths(PathSelectors.any())
.build();
}

重启测试,可以看到组名更改为zsr


2. 配置多个组

上述我们成功修改了组名,但是只有一个组,如果我们想要多个组呢?

观察代码可以知道,一个Docket实例就对应着一个组,因此我们配置多个docket就对应着多个组

我们新增两个Docket的bean实例

@Bean
public Docket
docket1() {
return new Docket(DocumentationType.SWAGGER_2).groupName("Baret-H");
}

@Bean
public Docket
docket2() {
return new Docket(DocumentationType.SWAGGER_2).groupName("钟");
}

再次重启测试,就可以看到多个组并选择



10. 配置Model实体类

1. 新建实体类

在主程序同级目录下新建pojo包,其中新建User实体类

package com.zsr.pojo;

public class User {
public String username;
public String password;
}

2. 编写对应请求接口

编写完实体类,我们在model中还是看不到的,我们还需在HelloController中新增一个方法返回实体类的实例对象即可映射到实体项中

@GetMapping("/getUser")
public User
getUser() {
return new User();
}

3. 启动测试

成功显示实体类User

4. 常用注解

我们可以在实体类上和其属性上添加注解来添加对应的注释

  • @ApiModel为类添加注释
  • @ApiModelProperty为类属性添加注释

package com.zsr.pojo;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;

@ApiModel(
"用户实体")
public class User {
@ApiModelProperty(
"用户名")
public String username;
@ApiModelProperty(
"密码")
public String password;
}

重启测试,即可以看到注释信息

我们同样可以在Controller类和其中的方法上添加相应的注解

@Api(tags = "Hello控制类")
@RestController
public class HelloController {
@RequestMapping(
"/hello")
public String
hello() {
return "hello";
}

@ApiOperation(
"hello控制类")
@GetMapping(
"/getUser")
public User
getUser() {
return new User();
}
}

重启即可看到对应的注解



11. 测试Swagger的使用

1. 测试传参

我们在HelloController中新增一个方法,参数为username,可以用@ApiParam给该参数添加注解

@GetMapping("/username")
public String getUserName(@ApiParam(
"用户名") String username) {
return username;
}

重启测试,可以看到我们添加的注释

我们可以简单测试一下,点击Try it out;然后以json的格式输入用户名,然后点击Execute执行

可以看到报错了,这是因为我们是使用的是Get方式:是通过URL的方式传递的,而不是通过请求体单独传参

我们将代码修改一下,将GetMapping改为PostMapping

@PostMapping("/username")
public String getUserName(@ApiParam(
"用户名") String username) {
return username;
}

再次以json的格式输入参数username,可以看到成功了

2. 测试错误

我们在HelloController中新增一个方法,参数为User,可以用@ApiParam给该参数添加注解

然后运行测试

找到对应的controller,点击Try it out测试,输入用户名和密码然后点击Excute

可以看到我们请求的URL完全正确,但是Response body相应体中用户名和密码都为空,这是因为我们的实体类没有添加对应的GET和SET方法,我们添加上去

package com.zsr.pojo;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;

@ApiModel(
"用户实体")
public class User {
@ApiModelProperty(
"用户名")
public String username;
@ApiModelProperty(
"密码")
public String password;

public String
getUsername() {
return username;
}

public void setUsername(String username) {
this.username = username;
}

public String
getPassword() {
return password;
}

public void setPassword(String password) {
this.password = password;
}
}

再次启动测试,成功!

如果我们修改一下代码

@PostMapping("/post")
private User postUser(User user) {
int i = 100 / 0;
return user;
}

此时测试肯定会报错,我们测试看看,可以看到500错误

由此可见,swagger可以让我们很容易的进行前后端的交互测试

相关推荐

为何越来越多的编程语言使用JSON(为什么编程)

JSON是JavascriptObjectNotation的缩写,意思是Javascript对象表示法,是一种易于人类阅读和对编程友好的文本数据传递方法,是JavaScript语言规范定义的一个子...

何时在数据库中使用 JSON(数据库用json格式存储)

在本文中,您将了解何时应考虑将JSON数据类型添加到表中以及何时应避免使用它们。每天?分享?最新?软件?开发?,Devops,敏捷?,测试?以及?项目?管理?最新?,最热门?的?文章?,每天?花?...

MySQL 从零开始:05 数据类型(mysql数据类型有哪些,并举例)

前面的讲解中已经接触到了表的创建,表的创建是对字段的声明,比如:上述语句声明了字段的名称、类型、所占空间、默认值和是否可以为空等信息。其中的int、varchar、char和decimal都...

JSON对象花样进阶(json格式对象)

一、引言在现代Web开发中,JSON(JavaScriptObjectNotation)已经成为数据交换的标准格式。无论是从前端向后端发送数据,还是从后端接收数据,JSON都是不可或缺的一部分。...

深入理解 JSON 和 Form-data(json和formdata提交区别)

在讨论现代网络开发与API设计的语境下,理解客户端和服务器间如何有效且可靠地交换数据变得尤为关键。这里,特别值得关注的是两种主流数据格式:...

JSON 语法(json 语法 priority)

JSON语法是JavaScript语法的子集。JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔花括号保存对象方括号保存数组JS...

JSON语法详解(json的语法规则)

JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔大括号保存对象中括号保存数组注意:json的key是字符串,且必须是双引号,不能是单引号...

MySQL JSON数据类型操作(mysql的json)

概述mysql自5.7.8版本开始,就支持了json结构的数据存储和查询,这表明了mysql也在不断的学习和增加nosql数据库的有点。但mysql毕竟是关系型数据库,在处理json这种非结构化的数据...

JSON的数据模式(json数据格式示例)

像XML模式一样,JSON数据格式也有Schema,这是一个基于JSON格式的规范。JSON模式也以JSON格式编写。它用于验证JSON数据。JSON模式示例以下代码显示了基本的JSON模式。{"...

前端学习——JSON格式详解(后端json格式)

JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于JavaScriptProgrammingLa...

什么是 JSON:详解 JSON 及其优势(什么叫json)

现在程序员还有谁不知道JSON吗?无论对于前端还是后端,JSON都是一种常见的数据格式。那么JSON到底是什么呢?JSON的定义...

PostgreSQL JSON 类型:处理结构化数据

PostgreSQL提供JSON类型,以存储结构化数据。JSON是一种开放的数据格式,可用于存储各种类型的值。什么是JSON类型?JSON类型表示JSON(JavaScriptO...

JavaScript:JSON、三种包装类(javascript 包)

JOSN:我们希望可以将一个对象在不同的语言中进行传递,以达到通信的目的,最佳方式就是将一个对象转换为字符串的形式JSON(JavaScriptObjectNotation)-JS的对象表示法...

Python数据分析 只要1分钟 教你玩转JSON 全程干货

Json简介:Json,全名JavaScriptObjectNotation,JSON(JavaScriptObjectNotation(记号、标记))是一种轻量级的数据交换格式。它基于J...

比较一下JSON与XML两种数据格式?(json和xml哪个好)

JSON(JavaScriptObjectNotation)和XML(eXtensibleMarkupLanguage)是在日常开发中比较常用的两种数据格式,它们主要的作用就是用来进行数据的传...

取消回复欢迎 发表评论:

请填写验证码