前言
什么是Swagger?
Swagger是一种API设计工具,在API文档和代码之间建立了关系,并使API文档在不断更改的代码基础上保持最新、准确和可读性。它允许描述API的结构,以便机器可以读取它们,这就是Swagger的所有魅力的根源。通过读取API的结构,它可以自动构建漂亮和交互式的API文档。此外,Swagger还可以为您的API以多种语言自动生成客户端库,并探索其他可能性,如自动测试。
Swagger有什么用?
现在开发项目,大多数都是采用前后端开发,前后端交互都是通过API文档进行交流,前后端各自开发,互不干扰。
传统开发方式
传统的开发模式,后端写好API接口,生成文档,发给前端工程师,前端根据后端发过来的API文档进行开发,但这样做有个缺点 ,文档无法做到实时同步。
Swagger接口
在Java项目中,集成Swagger后,当我们编写出接口时,Swagger就会自动扫描我们的接口,通过Restful风格发布,每当后端的接口有更新,Swagger都会扫描到,并且更新,通过网页展示每个端接口的情况。
你甚至还能给每个接口添加注释,供前端工程师了解每个接口所需的参数,你甚至还能在Swagger集成的API文档在线调试。
Swagger优缺点
优点
可读性高
:Swagger通过自动生成API文档,使得API文档的可读性更高。
减少开发时间
:Swagger可以自动生成客户端代码,并自动测试API,从而减少了开发时间。
容易维护
:Swagger的描述方式使得API的修改变得相对容易,同时自动更新API文档,避免了文档与实际情况不匹配的问题。
支持多种语言
:Swagger支持许多编程语言,可以满足开发人员的需求。
缺点
自动化有限
:虽然Swagger可以自动生成客户端代码、测试API及生成API文档等功能,但其自动化程度还是有限的。
不支持所有HTTP方法
:Swagger不支持所有HTTP方法,需要使用特定的扩展进行描述。
入门案例
下面我们以一个SpringBoot项目演示一下Swagger的使用。
创建SpringBoot项目
创建项目
SpringBoot建议在2.6.0以下,Swagger版本小于3.0,其他版本可能存在不兼容问题
根据你的需求选择合适的版本,我这里选择JDK11
。(springboot 3.0以上需要JDK17以上)
勾选Java web
依赖。
修改SpringBoot版本
打开pom.xml文件,修改版本为3.0以下,如我这里修改为2.5.6
,Swagger 2.x
版本和SpringBoot2.6.0
以上的版本会有冲突,所以使用低版本的SpringBoot比较方便。
导入Swagger依赖
这里选择Swagger 2.9.2
版本,右键重新加载一下依赖。
1 2 3 4 5 6 7 8 9 10 11 <dependency > <groupId > io.springfox</groupId > <artifactId > springfox-swagger-ui</artifactId > <version > 2.9.2</version > </dependency > <dependency > <groupId > io.springfox</groupId > <artifactId > springfox-swagger2</artifactId > <version > 2.9.2</version > </dependency >
创建Swagger配置类
在config包下新建一个SwaggerConfig
配置类,用于编写Swagger的相关配置。
1 2 3 4 5 6 7 8 9 import org.springframework.context.annotation.Configuration;import springfox.documentation.swagger2.annotations.EnableSwagger2;@EnableSwagger2 @Configuration public class SwaggerConfig { }
Docket
Swagger的实例是Docket,我们需要通过Docket来配置Swagger,我们看看Docket有什么,方便我们后面配置。
我们继续看看这个DocumentationType
参数,可以看到,有1.2、2.0、1.0
,可以看出来这是版本。
创建一个实例Docket,下面我们创建两个Docket实例,我们在开发中,每个开发者都会有一个属于自己的实例,这样用于区分自己写的接口方法有哪些。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 @Bean Docket docket () { return new Docket (DocumentationType.SWAGGER_2) .groupName("小码同学" ) .apiInfo(apiInfo()) .enable(true ) .select() .apis(RequestHandlerSelectors.basePackage("site.hikki.controller" )) .build(); } @Bean Docket docketB () { return new Docket (DocumentationType.SWAGGER_2) .groupName("开发者B" ) .apiInfo(apiInfo()) .select() .build(); }
添加接口信息
在SwaggerConfig
配置类中添加接口信息,其中实例化Contact
的对象是个人信息。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 private ApiInfo apiInfo () { Contact contact = new Contact ("小码同学" , "https://blog.hikki.site" , "aa1341151056@163.com" ); return new ApiInfoBuilder () .title("小码博客接口测试" ) .description("喜欢的东西就努力去追求,万一成功了呢!" ) .version("1.0" ) .termsOfServiceUrl("https://blog.hikki.site" ) .contact(contact) .build(); }
演示效果
当我们编写完上面的配置类后,我们就可以查看一下这个接口的样子了,因为我们还没编写API接口,只是编写了一些接口的介绍,以及接口开发人员。
编写POJO
下面代码有两个注释:
@ApiModel
:描述类
@ApiModelProperty
:描述参数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 import io.swagger.annotations.ApiModel;import io.swagger.annotations.ApiModelProperty;@ApiModel("用户实体类") public class User { @ApiModelProperty("用户名") private String username; @ApiModelProperty("密码") private 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; } public User (String username, String password) { this .username = username; this .password = password; } }
编写Controller层
接下来是重点了
。我们一般在Controller层编写接口,这些接口需要给前端对接,自然API接口文档要写得好一点,不然前端不知道你需要什么参数,什么格式,乱传就容易打起来了。
@Api的description属性
:表示描述该类
@ApiOperation
:描述该接口
@ApiParam
:描述该参数
@ApiImplicitParams
:描述多个参数(多个可用数组)
@ApiImplicitParam
:单个参数,嵌套在@ApiImplicitParams
中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 import io.swagger.annotations.Api;import io.swagger.annotations.ApiOperation;import io.swagger.annotations.ApiParam;import org.springframework.web.bind.annotation.*;import site.hikki.pojo.User;import java.util.ArrayList;import java.util.List;@Api(description = "User控制层") @RestController @RequestMapping public class UserController { @ApiOperation("根据ID查询用户") @GetMapping("/user{id}") public String getUser (@ApiParam("用户ID") Integer id) { return "get userid = " +id; } @ApiOperation("查询全部用户") @GetMapping("user") public List<User> getAll () { User user = new User ("小码同学" , "123456" ); User user1 = new User ("吴小白" , "123456" ); ArrayList<User> list = new ArrayList <>(); list.add(user); list.add(user1); return list; } @ApiOperation("登录") @PostMapping("user") public String login (User user) { return "login su" ; } @ApiImplicitParams({ @ApiImplicitParam(name = "username", value = "用户名", required = true, paramType = "form"), @ApiImplicitParam(name = "password", value = "密码", required = true, paramType = "form"), @ApiImplicitParam(name = "mobile", value = "手机号", required = true, paramType = "form") }) @PostMapping("register") public String register (String username,String password,String mobile) { return "ok" ; } @ApiOperation("根据ID删除用户") @DeleteMapping("/user{id}") public String delUser (@ApiParam("用户ID") Integer id) { return "del user=" +id; } @ApiOperation("测试错误接口") @GetMapping("/geterror") public String error () { int i = 5 / 0 ; return "测试返回错误" ; } }
效果展示
POJO类
当在Controller引用到了POJO后,可用看到POJO类的相关描述。
API文档
测试错误接口
测试错误接口时,会返回错误码和错误信息。
参数描述
我们使用了@ApiImplicitParams
注释对参数进行了描述。
输入参数请求
我们在POJO的User实体类使用了@ApiModelProperty
注解对属性进行描述了,当我们在控制层调用为参数时则会在API文档上自动进行描述。
常用的注解
@Api
@ApiOperation
@ApiOperation
@ApiImplicitParams、@ApiImplicitParam
@ApiResponses、@ApiResponse
@ApiModel、@ApiModelProperty
@PathVariable
@RequestParam
@Api
@Api 注解用于标注一个Controller(Class)。在默认情况下,Swagger-Core只会扫描解析具有@Api注解的类,而会自动忽略其他类别资源(JAX-RS endpoints,Servlets等等)的注解。
主要属性如下:
属性
描述
value
url的路径值
tags
如果设置这个值、value的值会被覆盖
description
对api资源的描述
basePath
基本路径可以不配置
position
如果配置多个Api 想改变显示的顺序位置
produces
For example, “application/json, application/xml”
consumes
For example, “application/json, application/xml”
protocols
Possible values: http, https, ws, wss.
authorizations
高级特性认证时配置
hidden
配置为true 将在文档中隐藏
实例:
1 2 3 4 5 6 @Controller @RequestMapping(value = "/api/pet", produces = {APPLICATION_JSON_VALUE, APPLICATION_XML_VALUE}) @Api(value = "/pet", description = "Operations about pets") public class PetController {}
@ApiOperation
@ApiOperation 注解在用于对一个操作或HTTP方法进行描述。具有相同路径的不同操作会被归组为同一个操作对象。不同的HTTP请求方法及路径组合构成一个唯一操作。
主要属性:
属性
描述
value
url的路径值
tags
如果设置这个值、value的值会被覆盖
description
对api资源的描述
basePath
基本路径可以不配置
position
如果配置多个Api 想改变显示的顺序位置
produces
For example, “application/json, application/xml”
consumes
For example, “application/json, application/xml”
protocols
Possible values: http, https, ws, wss.
authorizations
高级特性认证时配置
hidden
配置为true 将在文档中隐藏
response
返回的对象
responseContainer
这些对象是有效的 “List”, “Set” or “Map”.,其他无效
httpMethod
“GET”, “HEAD”, “POST”, “PUT”, “DELETE”, “OPTIONS” and “PATCH”
code
http的状态码 默认 200
extensions
扩展属性
实例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 @RequestMapping(value = "/order/{orderId}", method = GET) @ApiOperation( value = "Find purchase order by ID", notes = "For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions", response = Order.class, tags = { "Pet Store" }) public ResponseEntity<Order> getOrderById (@PathVariable("orderId") String orderId) throws NotFoundException { Order order = storeData.get(Long.valueOf(orderId)); if (null != order) { return ok(order); } else { throw new NotFoundException (404 , "Order not found" ); } }
@ApiOperation
@ApiParam作用于请求方法上,定义api参数的注解。
主要属性:
属性
描述
name
属性名称
value
属性值
defaultValue
默认属性值
allowableValues
可以不配置
required
是否属性必填
access
不过多描述
allowMultiple
默认为false
hidden
隐藏该属性
example
举例子
实例:
1 2 3 public ResponseEntity<Order> getOrderById ( @ApiParam(value = "ID of pet that needs to be fetched", allowableValues = "range[1,5]", required = true) @PathVariable("orderId") String orderId)
@ApiImplicitParams、@ApiImplicitParam
@ApiImplicitParams、@ApiImplicitParam也可以定义参数.
@ApiImplicitParams:用在请求的方法上,包含一组参数说明
@ApiImplicitParam:对单个参数的说明
主要属性:
属性
描述
name
参数名
value
参数的说明、描述
required
参数是否必须必填
paramType
参数放在哪个地方 query --> 请求参数的获取:@RequestParam header --> 请求参数的获取:@RequestHeader path(用于restful接口)–> 请求参数的获取:@PathVariable body(请求体)–> @RequestBody User user form(普通表单提交)
dataType
参数类型,默认String,其它值dataType=“Integer”
defaultValue
参数的默认值
实例:
1 2 3 4 5 6 7 8 9 10 11 @ApiImplicitParams({ @ApiImplicitParam(name="mobile",value="手机号",required=true,paramType="form"), @ApiImplicitParam(name="password",value="密码",required=true,paramType="form"), @ApiImplicitParam(name="age",value="年龄",required=true,paramType="form",dataType="Integer") }) @PostMapping("/login") public JsonResult login (@RequestParam String mobile, @RequestParam String password, @RequestParam Integer age) { return JsonResult.ok(map); }
@ApiResponses、@ApiResponse
@ApiResponses、@ApiResponse进行方法返回对象的说明。
主要属性:
属性
描述
code
数字,例如400
message
信息,例如"请求参数没填好"
response
抛出异常的类
实例:
1 2 3 4 5 6 7 8 9 10 11 @ApiResponses({ @ApiResponse(code = 200, message = "请求成功"), @ApiResponse(code = 400, message = "请求参数没填好"), @ApiResponse(code = 404, message = "请求路径没有或页面跳转路径不对") }) @ResponseBody @RequestMapping("/list") public JsonResult list (@RequestParam String userId) { ... return JsonResult.ok().put("page" , pageUtil); }
@ApiModel、@ApiModelProperty
@ApiModel用于描述一个Model的信息(这种一般用在post创建的时候,使用@RequestBody这样的场景,请求参数无法使用@ApiImplicitParam注解进行描述的时候)。
@ApiModelProperty用来描述一个Model的属性。
实例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 @ApiModel(description= "返回响应数据") public class RestMessage implements Serializable { @ApiModelProperty(value = "是否成功",required=true) private boolean success=true ; @ApiModelProperty(value = "错误码") private Integer errCode; @ApiModelProperty(value = "提示信息") private String message; @ApiModelProperty(value = "数据") private Object data; }
@PathVariable
@PathVariable用于获取get请求url路径上的参数,即参数绑定的作用,通俗的说是url中"?"前面绑定的参数。
实例:
1 2 3 4 5 @GetMapping("/query/{id}") private List<Student> queryById ( @ApiParam(name = "id", value = "学生id", required = true) @PathVariable("id") Long id) { List<Student> studentList = studentService.queryById(id); return studentList; }
@RequestParam
@RequestParam用于获取前端传过来的参数,可以是get、post请求,通俗的说是url中"?"后面拼接的每个参数。
实例:
1 2 3 4 5 @GetMapping("/query/student") private List<Student> queryByIdStu(@ApiParam(name = "byId", value = "学生id", required = false) @RequestParam("id") Long id) { List<Student> studentList = studentService.queryById(id); return studentList; }
@ApiIgnore
用于隐藏某个Controller类或接口方法
隐藏整个Controller
1 2 3 4 5 6 7 @ApiIgnore @Api(description = "User控制层") @RestController @RequestMapping public class UserController { }
隐藏某个接口
有时候我们有些接口没开发完或者是不想发布出去,我们可以来隐藏这些接口。
方法一
使用@ApiIgnore
注解隐藏该接口方法
1 2 3 4 5 6 @ApiIgnore @ApiOperation("根据ID查询用户") @GetMapping("/user{id}") public String getUser (@ApiParam("用户ID") Integer id) { return "get userid = " + id; }
方法二
使用@ApiOperation
注解的hidden
属性来隐藏接口方法。
1 2 3 4 5 @ApiOperation(value = "根据ID查询用户",hidden = true) @GetMapping("/user{id}") public String getUser (@ApiParam("用户ID") Integer id) { return "get userid = " + id; }
本文章来源于我的博客:https://blog.hikki.site