Java | Spring Boot Swagger2 集成REST ful API 生成接口文档
Spring Boot Swagger2 集成REST ful API 生成接口文档
简介
由于Spring Boot 的特性,用来开发 REST ful 变得非常容易,并且结合 Swagger 来自动生成 REST ful API 文档变得方便快捷。
Swagger 是一个简单但功能强大的API表达工具。几乎所有的语言都可以找到与之对应的Swagger 版本。使用Swagger生成API,我们可以得到交互式文档。听过Spring Boot 与Swagger 的结合,生成更加完备的REST ful API 文档。通过在源码中添加部分内容,系统生成文档,大大提高工作效率,不用再花费大量时间来创建文档,同时由于同时是通过代码开生成文档,大大降低了维护成本
Swagger 不仅可以组织生成强大的 REST ful 文档,同时也提供了完备的测试功能,可以直接在文档页面测试接口功能。
接下来将基于 Spring Boot 与Swagger 2 搭建完整的API 文档系统。先来提前目睹下Swagger 生成的文档样式
实践
创建Spring Boot 工程
可以参考前文Spring Boot 初体验
在POM 文件中添加 Swagger2 包引用
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.7.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.7.0</version>
</dependency>
//导入测试需要的库
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.196</version>
<scope>runtime</scope>
</dependency>
本实例采用的是基于内存数据库H2 的JPA 形式
创建配置类
通过以上方式只能导入 Swagger2 需要的jar包,但当前并不能运行(虽然Spring boot 支持自动化配置)
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket api(){
return new Docket(DocumentationType.SWAGGER_2).select()
.apis(RequestHandlerSelectors.basePackage("com.springboot.demo"))
.paths(PathSelectors.any())
.build()
.apiInfo(apiInfo());
}
private ApiInfo apiInfo(){
return new ApiInfoBuilder()
.title("Spring Boot中使用Swagger2构建RESTful APIs")
.description("spring boot , swagger2")
.termsOfServiceUrl("http:github.com/zhuamaodeyu")
.contact("抓?的?")
.version("1.0")
.build();
}
}
说明:
@Configuration: 此注解是告诉Spring Boot这是一个配置类,需要在项目启动时加载该类@EnableSwagger2:Swagger2是通过此注解来启动的- 通过
api方法创建 Docket 对象,其中主要注意basePackage配置以及私有方法apiInfo方法创建的基本信息
通过指定扫描包来配置,以上配置 Swagger 会扫描整个项目工程
创建实体和respository
@Entity
@Table(name="user")
public class User implements Serializable {
// @ApiModelProperty(notes = "id")
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private String id;
@ApiModelProperty(notes = "uuid")
private UUID uuid;
@ApiModelProperty(notes = "用户名称")
private String name;
private String password;
@ApiModelProperty(notes = "用户地址")
private String address;
@ApiModelProperty(notes = "年龄")
private int age;
@ApiModelProperty(notes = "邮箱地址")
private String email;
@ApiModelProperty(notes = "描述")
private String desc;
// getter/ setter 方法
}
@Repository
public interface UserRepository extends CrudRepository<User,String> {
}
测试controller
@RestController
@Api(value = "product 商品操作API")
@RequestMapping("/product")
public class IndexController {
/**
* 1. 获取列表
* 2. 显示单个的信息
* 3. 添加
* 4. 更新
* 5. 删除
*/
@Autowired
private UserRepository userRepository;
@GetMapping("/")
@ApiOperation(value = "首页",notes = "测试代码")
public String index()
{
return "index";
}
@GetMapping("/list")
@ApiOperation(value = "获取全部数据列表", notes = "获取数据列表")
public Iterable list(Model model)
{
return userRepository.findAll();
}
@GetMapping("/get_user_message")
@ApiOperation(value = "获取用户详情信息")
@ApiImplicitParam(name = "userId",value = "用户ID",defaultValue = "",required = true,dataType = "String")
public User getUserMessage(String userId)
{
return userRepository.findOne(userId);
}
@PostMapping("/save")
@ApiOperation(value = "保存用户数据")
@ApiImplicitParam(name = "user", value = "用户对象",required = true, dataTypeClass = User.class)
public String save(@RequestBody User user)
{
if (user == null)
{
return "false";
}
userRepository.save(user);
return "true";
}
@PutMapping("/update/{userId}")
@ApiOperation(value = "更新用户数据")
@ApiImplicitParams({
@ApiImplicitParam(name = "userId", value = "用户的ID", required = true, dataTypeClass = String.class),
@ApiImplicitParam(name = "user", value = "用户对象", required = true, dataTypeClass = User.class)
})
public ResponseEntity updateUserMessage(@PathVariable String userId, @RequestBody User user)
{
User user1 = userRepository.findOne(userId);
user1.setAddress(user.getAddress());
userRepository.save(user1);
return new ResponseEntity("更新数据成功", HttpStatus.OK);
}
@DeleteMapping("/delete/{userId}")
@ApiOperation(value = "根据用户ID 删除用户数据")
@ApiImplicitParam(name = "删除用户数据",value = "",required = true, dataType = "String")
public ResponseEntity deleteUser(@PathVariable String userId)
{
userRepository.delete(userId);
return new ResponseEntity("删除用户数据", HttpStatus.OK);
}
}
测试
实现以上代码,启动项目 直接访问http://localhost:8080/swagger-ui.html
就能看到Swagger2 所生成的文档。可以操作每个请求,其下面是具体的描述和文档内容
接口调试
- Swagger 集成测试
前文提到 Swagger 也提供了 接口调试功能, 可以直接根据接口要求在图中标记处填写接口参数 - Postman 测试
通过以上方式可以得到接口文档,其包含了具体的内容,有了这些内容,就可以通过Postman 等专业的接口测试工具来进行接口的测试
Swagger2 常用配置详解
@Api@Api(value="onlinestore", description="当前控制器中的API 的描述信息")
@ApiOperation此注解是对当前 API 接口的描述,主要是名称,详细描述,返回值类型等信息
@ApiOperation(value = "首页",notes = "测试代码", tags = {"测试服务是否正常"}, response = String.class)- value : API 的名称
- notes : API 详细描述信息
- response : 返回值类型
- tags : 默认的是以 类名为 标签的,此处可以自定义标签
@ApiResponses@ApiResponse此注解是对API 返回的结果进行描述
@ApiResponses(value = {
@ApiResponse(code = 200, message = "Successfully"),
@ApiResponse(code = 401, message = "You are not authorized to view the resource"),
@ApiResponse(code = 403, message = "Accessing the resource you were trying to reach is forbidden"),
@ApiResponse(code = 404, message = "The resource you were trying to reach is not found")
}
)
@ApiImplicitParams@ApiImplicitParam这两个注解是对API 请求参数的描述
@ApiImplicitParams({
@ApiImplicitParam(name = "userId", value = "用户的ID", required = true, dataTypeClass = String.class),
@ApiImplicitParam(name = "user", value = "用户对象", required = true, dataTypeClass = User.class)
})@ApiModelProperty
实体类属性添加描述信息,在接口文档中可针对类属性具体含义进行查看@GeneratedValue(strategy = GenerationType.AUTO)
private String id;
@ApiModelProperty(notes = "uuid")
private UUID uuid;
@ApiModelProperty(notes = "用户名称")
private String name;
private String password;
@ApiModelProperty(notes = "用户地址")
private String address;
@ApiModelProperty(notes = "年龄")
private int age;
@ApiModelProperty(notes = "邮箱地址")
private String email;
@ApiModelProperty(notes = "描述")
private String desc;通过以上配置,可以文档中进行查看
扩展知识
Mock 系统
在现如今的开发中,一个由于项目需求紧,开发周期短,通常涉及到后端以及前端协同工作;一个由于现在大多采用的是前后端分离的开发形式,前后端交互只是通过 REST ful 接口形式来实现的,前后端各自分工工作,所以就存在一个现象就是前端做的快,后端无法及时的给出接口实现并且开发阶段没有数据支撑而造成前端必须等待后端。
现在可以通过先定义接口文档,生成 Mock 数据的形式来进行前后端分离开发。前端通过调用定义的 Mock 数据来进行前端调试和开发。不需要等待后端的数据
接下来将通过集成 easy-Mock 系统来实现协同开发
easy Mock
easy-mock 是大搜车公司开源的一套 mock 工具,是一个可视化,并且能快速生成 模拟数据 的持久化服务. 下面将 easy-mock 与 Swagger 结合进行协同工作
搭建easy-mock
- 下载源码
easy-mock是一套开源系统,其托管在 github 上,可以通过一下方式获取源码git clone https://github.com/easy-mock/easy-mock.git 修改配置
easy-mock 是使用MongoDB数据的,所以需要配置数据库
进入config文件夹,修改default.json文件{
"port": 7300,
"pageSize": 30,
"routerPrefix": {
"mock": "/mock",
"api": "/api"
},
"db": "mongodb://192.168.99.100:32773/easy-mock_",
"unsplashClientId": "",修改
db添加一个可以用的 数据库- 启动
npm run dev
默认的监听7300端口,可以通过localhost:7300访问系统
- 下载源码
导入 Swagger
进入系统创建项目并根据以下方式导入 Swagger- 获取 Swagger 地址
- easy-mock创建项目
- 通过
- 获取 Swagger 地址
参考
Java | Spring Boot Swagger2 集成REST ful API 生成接口文档的更多相关文章
- spring boot 中使用swagger 来自动生成接口文档
1.依赖包 <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swa ...
- spring boot 2 集成JWT实现api接口认证
JSON Web Token(JWT)是目前流行的跨域身份验证解决方案.官网:https://jwt.io/本文使用spring boot 2 集成JWT实现api接口验证. 一.JWT的数据结构 J ...
- Spring Boot(九)Swagger2自动生成接口文档和Mock模拟数据
一.简介 在当下这个前后端分离的技术趋势下,前端工程师过度依赖后端工程师的接口和数据,给开发带来了两大问题: 问题一.后端接口查看难:要怎么调用?参数怎么传递?有几个参数?参数都代表什么含义? 问题二 ...
- Spring Boot Swagger2自动生成接口文档
一.简介 在当下这个前后端分离的技术趋势下,前端工程师过度依赖后端工程师的接口和数据,给开发带来了两大问题: 1.问题一.后端接口查看难:要怎么调用?参数怎么传递?有几个参数?参数都代表什么含义? 2 ...
- Springboot集成swagger2生成接口文档
[转载请注明]: 原文出处:https://www.cnblogs.com/jstarseven/p/11509884.html 作者:jstarseven 码字挺辛苦的..... 一 ...
- Spring boot 添加日志 和 生成接口文档
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring- ...
- SpringBoot集成Swagger(Swagger的使用),生成接口文档,方便前后端分离开发
首先上一张成果图. 1.Maven依赖 <dependency> <groupId>io.springfox</groupId> <artifactId&g ...
- asp.net core web api 生成 swagger 文档
asp.net core web api 生成 swagger 文档 Intro 在前后端分离的开发模式下,文档就显得比较重要,哪个接口要传哪些参数,如果一两个接口还好,口头上直接沟通好就可以了,如果 ...
- 作为Java开发工程师,如何高效优雅地编写接口文档
作为一名优秀的Java开发工程师,编写接口文档向来是一件很头疼的事情.本来就被bug纠缠的很累了,你还让我干这? 其实,你可以试试ApiPost. ApiPost的定位是Postman+Swagger ...
随机推荐
- 关于C++中使用++it还是it++的问题
我们经常使用for循环来遍历东西,循环变量可以前自增也可以后自增,发现对遍历结果没啥影响,但是该如何选择呢? 我们应该尽量使用前自增运算符而不是后自增运算符,即用 ++ Iter 代替 Iter++ ...
- RMAN笔记
Rman常用命令 Preview选项 1) 显示用于还原system表空间数据文件的备份文件 RMAN> restore datafile 2 preview; 2) 显示用于还原特 ...
- SQOOP的使用方法
Sqoop是个命令行工具,用来在Hadoop和rdbms之间传输数据. 以Hadoop的角度看待数据流向,从rdbms往Hadoop是导入用sqoop import命令,反之从hadoop往rdbms ...
- 一文搞定PGA_LGA_BGA
概述 什么是LGA.PGA.BGA类型的封装?众所周知,CPU封装的类型主要为三种:LGA,PGA,BGA,其中LGA封装是最常见的,intel处理器都是采用这种类型的封装,而PGA封装则是AMD常用 ...
- 蓝色映象 幻舞少女之剑 BLUE REFLECTION 后感
到底是看片收获多还是游戏收获多?在刷蓝色反射的时候刷了2部番.所以,我到底是为了什么在玩游戏呢? 岸田メル的人设,毋庸置疑,唯美想舔,且总能给人一种绝无杂质,纯洁治愈的感觉,再加上浅野隼人的配乐,恰如 ...
- python数据类型之三
字典 字典的基本结构 # 字典, 键值对 dict类# 字典的基本结构# 字典的值可以是任何值# 字典的键不能是列表,字典, 最好也不要用布尔值(可能会和1和0重复)# 字典无序, my_dict = ...
- bootstrap基础自我总结
*今天自学了一些封装的css,看起来官网很强大,但是因为源码备注都是英文的情况下,还是感觉想深入有点力不从心,发现度娘没有中文手册,无奈,不过还好代码无国界,基本都是能看懂的,备注也影响不大(安慰自己 ...
- Pandas | 25 文件读写
Pandas I/O API是一套像pd.read_csv()一样返回Pandas对象的顶级读取器函数. 读取文本文件(或平面文件)的两个主要功能是read_csv()和read_table().它们 ...
- vue响应数据的原理
vue最大的特点就是数据驱动视图. vue的数据改变,页面一定发生改变?不一定. 当操作引用类型的数据,动态添加属性时,页面不会发生改变. vue响应式数据原理(也叫数据绑定原理.双向数据绑定原理): ...
- selenium--更改标签的属性值
前戏 在进行web自动化的时候,我们有时需要获取元素的属性,有时需要添加,有时需要删除,这时候就要通过js来进行操作了 实战 from selenium import webdriver import ...