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 ...
随机推荐
- 如何在相同的类名中单独为选中元素设置JS
很多时候,我发现对一个类名添加事件,每次都是所有同类名元素一起触发,使用 this可以仅对当前选中的元素应用事件 如 $('.guowai button').click(function() { /* ...
- wc.exe个人项目
1.GitHub项目 https://github.com/Littlehui3/wc 2.用时表格 PSP2.1 任务内容 计划完成需要的时间(min) 实际完成需要的时间(min) Plannin ...
- 搜索引擎框架之ElasticSearch基础详解(非原创)
文章大纲 一.搜索引擎框架基础介绍二.ElasticSearch的简介三.ElasticSearch安装(Windows版本)四.ElasticSearch操作客户端工具--Kibana五.ES的常用 ...
- Python之路(第四十七篇) 协程:greenlet模块\gevent模块\asyncio模块
一.协程介绍 协程:是单线程下的并发,又称微线程,纤程.英文名Coroutine.一句话说明什么是线程:协程是一种用户态的轻量级线程,即协程是由用户程序自己控制调度的. 协程相比于线程,最大的区别在于 ...
- java List一次性添加多个元素
(1)使用addAll方法 ArrayListExample.java public class ArrayListExample { public static void main(String[] ...
- Django Template语法中 OneToOne、ForeignKey 外键查询
主表的Models的结构 class A(models.Model): username = models.CharField(max_length=32, verbose_name='用户名称') ...
- 转载--从输入URL到页面展示到底发生了什么
最近我也在看http协议, tcp相关知识, 在吃饭时无意看到来一篇文章讲解“从输入URL到页面展示到底发生了什么”, 细细看完, 很值得回味, 所以转载, 以供日后在温习. (PS, 作者这篇文章发 ...
- UE4 Keynote 1
[UE4 Keynote 1] 1.U3D中的Project,在UE4中叫 ContentBrowser,中文名叫“内容浏览器” 最多可以打开4个ContentBrowser,通过 “窗口” -> ...
- [转]【会话技术】Cookie技术
建立时间:6.29 & 6.30 一.会话技术简介 1.存储客户端的状态 由一个问题引出今天的内容,例如网站的购物系统,用户将购买的商品信息存储到哪 里?因为Http协议是无状态的,也就是说 ...
- Linux下bash的一些总结
关于"交互式-非交互式"与"登录-非登陆"shell的总结 关于".bash_profile"和".bashrc"区别的 ...