作为一名程序员,我们最讨厌两件事:1. 别人不写注释。2. 自己写注释。
而作为一名接口开发者,我们同样讨厌两件事:1. 别人不写接口文档,文档不及时更新。2. 需要自己写接口文档,还需要及时更新。
相信无论是前端还是后端开发,都或多或少地被接口文档折磨过。前端经常抱怨后端给的接口文档与实际情况不一致。后端又觉得编写及维护接口文档会耗费不少精力,经常来不及更新。
而随着Springboot、Springcloud等微服务的流行,每个项目都有成百上千个接口调用,这时候再要求人工编写接口文档并且保证文档的实时更新几乎是一件不可能完成的事,所以这时候我们迫切需要一个工具,一个能帮我们自动化生成接口文档以及自动更新文档的工具。它就是Swagger。
Swagger 提供了一个全新的维护 API 文档的方式,有4大优点:
现在我们知道了Swagger的作用,接下来将其集成到我们项目中。
集成Swagger很简单,只需要简单三步。
<dependency>
<groupId>io.springfoxgroupId>
<artifactId>springfox-swagger2artifactId>
<version>2.9.2version>
dependency>
<dependency>
<groupId>io.springfoxgroupId>
<artifactId>springfox-swagger-uiartifactId>
<version>2.9.2version>
dependency>
package com.king.other.short_link.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
/**
* @program: springboot
* @description:
* @author: King
* @create: 2021-10-10 22:33
*/
@Configuration
@EnableSwagger2 //启用swaggerr 注解解析器
public class Swagger2Config {
// 是否开启swagger,正式环境一般是需要关闭的,可根据springboot的多环境配置进行设置
@Value(value = "${swagger.enable}") //通过 @Value 获取配置信息
// 复习@Environement @Value @ConfigurationProperties
private Boolean swaggerEnable;
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.ignoredParameterTypes(HttpSession.class, HttpServletRequest.class) //在生成的文档将哪些类对象的属性排除
// 是否开启
.enable(swaggerEnable)
.select()
// 扫描的路径包,只要这些包中的类配有swagger注解,则启用这些注解
.apis(RequestHandlerSelectors.basePackage("com.king"))
// 指定路径处理PathSelectors.any()代表所有的路径
.paths(PathSelectors.any())
.build();
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("测试平台-平台管理API文档")
.description("平台管理服务api")
// 作者信息
.contact(new Contact("king", "http://www.huahuazhw.xyz", "[email protected]"))
.version("1.0.0")
.build();
}
}
注:这里的swaggerEnable 用于控制是否开启Swagger,生产环境记得关闭Swagger,将值设置为 false 在application文件里面配置即可
package com.king.other.short_link.controller;
import com.king.other.short_link.bean.ShortLink;
import com.king.other.short_link.service.ShortLinkServiceImpl;
import com.king.other.short_link.vo.Result;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @program: springboot
* @description:
* @author: King
* @create: 2021-09-18 14:20
*/
@RestController
@Api(value = "链接转换接口", tags = "测试接口1")
public class ShortLinkController {
@Autowired
ShortLinkServiceImpl shortLinkService;
//生成分享链接
@RequestMapping(value = "/share.do")
@ApiOperation(value = "长链转短链", tags ="测试接口1")
@ApiImplicitParam(name = "longLink", value = "长链", dataType = "string", paramType = "query", example = "www.baidu.com", required = true)
public Result shareLink(HttpServletRequest request, String longLink) {
Result result = new Result();
if (longLink != null) {
result.setData(shortLinkService.addShortLink(longLink, getUrlStart(request)));
result.setStatus(true);
}
return result;
}
//实现短链跳转
@RequestMapping(value = "/short/{shortLink}")
@ApiOperation(value = "实现短链跳转", tags ="测试接口1")
@ApiImplicitParam(name = "shortLink", value = "短链", dataType = "string", paramType = "query", example = "NbI6qbyb", required = true)
public void sendRedirect(HttpServletResponse response, @PathVariable String shortLink) {
ShortLink shorts = shortLinkService.getLongLink(shortLink);
if (shorts != null) {
try {
response.sendRedirect(shorts.getLongLink());
} catch (IOException e) {
e.printStackTrace();
}
}
}
//获取请求的协议域名,端口号生成连接的前半部分
public String getUrlStart(HttpServletRequest request) {
StringBuilder url = new StringBuilder();
url.append(request.getScheme());
System.out.println(url);
url.append("://").append(request.getServerName());
System.out.println(url);
url.append(":").append(request.getServerPort());
System.out.println(url);
return url.toString();
}
}
package com.king.other.short_link.controller;
import com.king.other.short_link.vo.Result;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @program: springboot
* @description:
* @author: King
* @create: 2021-10-10 23:14
*/
@RestController
@Api(value = "操作接口", tags = "测试接口2")
public class TestController {
@PostMapping(value = "/test.do")
@ApiOperation(value = "测试接口多个参数", tags = "测试接口2")
@ApiImplicitParams({
@ApiImplicitParam(name = "name", value = "用户名", dataType = "string", paramType = "query", example = "lihailin9073", required = true),
@ApiImplicitParam(name = "email", value = "邮箱", dataType = "string", paramType = "query", example = "[email protected]", required = true),
})
public Result test(String name, String email) {
Result result = new Result();
Map<String, String> map = new HashMap<>();
map.put("用户名", name);
map.put("邮箱", email);
result.setData(map);
result.setMessage("这是一个测试接口");
result.setStatus(true);
return result;
}
}
通过@Api注解标注需要生成接口文档,通过@ApiOperation注解标注接口名。通过@ApiImplicitParam或者@ApiImplicitParams 用在请求的方法上,表示一组参数说明
同时我们给响应类也加上对应的注解
package com.king.other.short_link.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* @program: springboot
* @description:
* @author: King
* @create: 2021-09-18 14:26
*/
@Data
@ApiModel(value = "返回响应类")
public class Result {
@ApiModelProperty(value = "状态")
protected boolean status;
@ApiModelProperty(value = "返回信息")
protected String message;
@ApiModelProperty(value = "数据")
protected Object data;
}
@Api:用在请求的类上,表示对类的说明
tags="说明该类的作用,可以在UI界面上看到的注解"
value="该参数没什么意义,在UI界面上也看到,所以不需要配置"
@ApiOperation:用在请求的方法上,说明方法的用途、作用
value="说明方法的用途、作用"
notes="方法的备注说明"
@ApiImplicitParams:用在请求的方法上,表示一组参数说明
@ApiImplicitParam:用在@ApiImplicitParams注解中,指定一个请求参数的各个方面
name:参数名
value:参数的汉字说明、解释
required:参数是否必须传
paramType:参数放在哪个地方
· header --> 请求参数的获取:@RequestHeader
· query --> 请求参数的获取:@RequestParam
· path(用于restful接口)--> 请求参数的获取:@PathVariable
· body(不常用)
· form(不常用)
dataType:参数类型,默认String,其它值dataType="Integer"
defaultValue:参数的默认值
@ApiResponses:用在请求的方法上,表示一组响应
@ApiResponse:用在@ApiResponses中,一般用于表达一个错误的响应信息
code:数字,例如400
message:信息,例如"请求参数没填好"
response:抛出异常的类
@ApiModel:用于响应类上,表示一个返回响应数据的信息
(这种一般用在post创建的时候,使用@RequestBody这样的场景,
请求参数无法使用@ApiImplicitParam注解进行描述的时候)
@ApiModelProperty:用在属性上,描述响应类的属性
简单三步,我们项目就集成了Swagger接口文档,赶紧启动服务,访问http://localhost:9090/swagger-ui.html
体验一下。
Swagger2原生UI有点丑,我们可以借助Swagger的增强工具knife4j优化一下。
<dependency>
<groupId>com.github.xiaoymingroupId>
<artifactId>knife4j-spring-boot-starterartifactId>
<version>2.0.2version>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-validationartifactId>
dependency>
@Configuration
@EnableSwagger2 //启用swaggerr 注解解析器
@EnableKnife4j //启用knife4j增强
@Import(BeanValidatorPluginsConfiguration.class)
public class Swagger2Config {
...
}
通过上面两步我们就完成了Swagger的美化,通过浏览器访问http://localhost:9090/doc.html
即可看到效果。
最后附上源代码
Github https://github.com/KingJin-web/springboot/tree/master/other
Gitee https://gitee.com/KingJin-web/springboot/tree/master/other
以上内容属于个人笔记整理,如有错误,欢迎批评指正!