Spring|Spring Boot 2.X(十五)(集成 Swagger2 开发 API 文档(在线+离线))

前言 相信很多后端开发在项目中都会碰到要写 api 文档,不管是给前端、移动端等提供更好的对接,还是以后为了以后交接方便,都会要求写 api 文档。
而手写 api 文档的话有诸多痛点:

  • 文档更新的时候,需要再次发送给对接人
  • 接口太对,手写文档很难管理
  • 接口返回的结果不明确
  • 不能直接在线测试接口,通常需要使用工具,如 postman 等
Swagger 就很好的解决了这个问题。
Swagger 简介 Swagger 是一个规范和完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务。总体目标是使客户端和文件系统作为服务器以同样的速度来更新。文件的方法,参数和模型紧密集成到服务器端的代码,允许API来始终保持同步。
官网:https://swagger.io
Swagger 使用 1.相关依赖
io.springfox springfox-swagger2 2.9.2 io.springfox springfox-swagger-ui 2.9.2

2.Swagger 配置类
@Configuration @EnableSwagger2 public class SwaggerConfig { @Bean public Docket buildDocket() { return new Docket(DocumentationType.SWAGGER_2) .apiInfo(buildApiInf()) //将api的元信息设置为包含在json resourcelisting响应中 //.host("127.0.0.1:8080") //设置ip和端口,或者域名 .select()//启动用于api选择的生成器 //.apis(RequestHandlerSelectors.any()) .apis(RequestHandlerSelectors.basePackage("cn.zwqh.springboot.controller"))//指定controller路径 .paths(PathSelectors.any()).build(); }private ApiInfo buildApiInf() {Contact contact=new Contact("朝雾轻寒","https://www.zwqh.top/","zwqh@clover1314.com"); return new ApiInfoBuilder() .title("Swagger Demo Restful API Docs")//文档标题 .description("Swagger 示例 Restful Api 文档")//文档描述 .contact(contact)//联系人 .version("1.0")//版本号 //.license("")//更新此API的许可证信息 //.licenseUrl("")//更新此API的许可证Url //.termsOfServiceUrl("")//更新服务条款URL .build(); } }

3.Spring MVC 相关配置
@Configuration public class WebMvcConfig extends WebMvcConfigurationSupport { /** * 静态资源配置(默认) */ @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/**").addResourceLocations("classpath:/static/"); // 静态资源路径 registry.addResourceHandler("swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/"); registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/"); super.addResourceHandlers(registry); }}

如果不添加此静态资源配置会报错,找不到相关路径
4.Model 中使用 Swagger 注解
@ApiModel(value = "https://www.it610.com/article/UserEntity", description = "用户对象") public class UserEntity implements Serializable{/** * */ private static final long serialVersionUID = 5237730257103305078L; @ApiModelProperty(value ="https://www.it610.com/article/用户id",name="id",dataType="Long",required = false,example = "1",hidden = false ) private Long id; @ApiModelProperty(value ="https://www.it610.com/article/用户名",name="userName",dataType="String",required = false,example = "关羽" ) private String userName; @ApiModelProperty(value ="https://www.it610.com/article/用户性别",name="userSex",dataType="String",required = false,example = "男" ) private String userSex; public Long getId() { return id; }public void setId(Long id) { this.id = id; }public String getUserName() { return userName; }public void setUserName(String userName) { this.userName = userName; }public String getUserSex() { return userSex; }public void setUserSex(String userSex) { this.userSex = userSex; }}

5. Controller 中使用 Swagger 注解
@RestController @RequestMapping("/api") @Api(tags = { "接口分组1", "接口分组2" }) public class ApiController {@Autowired private UserDao userDao; @GetMapping("/getAllUser") @ApiOperation(value = "https://www.it610.com/article/获取所有用户", notes = "", httpMethod = "GET", tags = "接口分组3") public List getAll() { return userDao.getAll(); }@GetMapping("/getUserById") @ApiOperation(value = "https://www.it610.com/article/根据id获取用户", notes = "id必传", httpMethod = "GET") @ApiImplicitParam(name = "id", value = "https://www.it610.com/article/用户id",example = "1", required = true, dataType = "long", paramType = "query") public UserEntity getOne(Long id) { return userDao.getOne(id); }@PostMapping("/getUserByNameAndSex") @ApiOperation(value = "https://www.it610.com/article/根据name和sex获取用户", notes = "", httpMethod = "POST") @ApiImplicitParams({ @ApiImplicitParam(name = "userName", value = "https://www.it610.com/article/用户名", example = "关羽", required = true, dataType = "string", paramType = "query"), @ApiImplicitParam(name = "userSex", value = "https://www.it610.com/article/用户性别", example = "男", required = true, dataType = "string", paramType = "query") }) public UserEntity getUserByNameAndSex(String userName, String userSex) { return userDao.getUserByNameAndSex(userName, userSex); }@PostMapping("/insertUser") @ApiOperation(value = "https://www.it610.com/article/新增用户", notes = "传json,数据放body", httpMethod = "POST") @ApiImplicitParams({ @ApiImplicitParam(name = "body", value = "https://www.it610.com/article/用户对象json", example = "{userName:'朝雾轻寒',userSex:'男'}", required = true) }) public String insertUser(@RequestBody String body) { System.out.println(body); UserEntity user = JSON.parseObject(body, UserEntity.class); userDao.insertUser(user); return "{code:0,msg:'success'}"; }@PostMapping("/updateUser") @ApiOperation(value = "https://www.it610.com/article/修改用户", notes = "传json,数据放body", httpMethod = "POST") @ApiImplicitParams({ @ApiImplicitParam(name = "body", value = "https://www.it610.com/article/用户对象json", example = "{id:23,userName:'朝雾轻寒',userSex:'女'}", required = true) }) public String updateUser(@RequestBody String body) { System.out.println(body); UserEntity user = JSON.parseObject(body, UserEntity.class); userDao.updateUser(user); return "{code:0,msg:'success'}"; }@PostMapping("/deleteUser") @ApiOperation(value = "https://www.it610.com/article/删除用户", notes = "id必传", httpMethod = "POST") public String deleteUser(@ApiParam(name = "id", value = "https://www.it610.com/article/用户id", required = true) Long id) { userDao.deleteUser(id); return "{code:0,msg:'success'}"; } }

5.测试
访问 http://127.0.0.1:8080/swagger-ui.html 进行接口在线测试
Swagger 常用注解 1.@Api
用于类,表示标识这个类是swagger的资源。属性如下:
  • tags 表示说明,tags如果有多个值,会生成多个列表
  • value 表示说明,可以使用tags替代
2.@ApiOperation
用于方法,表示一个http请求的操作。属性如下:
  • value 用于方法描述
  • notes 用于提示内容
  • tags 用于API文档控制的标记列表,视情况而用,可以进行独立分组
3.@ApiParam
用于方法、参数、字段说明;表示对参数的添加元数据。
  • name 参数名
  • value 参数说明
  • required 是否必填
4.@ApiModel
【Spring|Spring Boot 2.X(十五)(集成 Swagger2 开发 API 文档(在线+离线))】用于类,表示对类进行说明,用于参数用实体类接受。
  • value 对象名
  • description 描述
5.@ApiModelProperty
用于方法、字段,表示对model属性的说明或者数据操作更改。
  • value 字段说明
  • name 重写属性名
  • dataType 重写属性数据类型
  • required 是否必填
  • example 举例说明
  • hidden 隐藏
6.@ApiIgnore
用于类、方法、方法参数,表示这个方法或者类被忽略,不在swagger-ui.html上显示。
7.@ApiImplicitParam
用于方法,表示单独的请求参数。
  • name 参数名
  • value 参数说明
  • dataType 数据类型
  • paramType 参数类型
  • example 举例说明
8.@ApiImplicitParams
用于方法,包含多个 @ApiImplicitParam。
9.@ApiResponses @ApiResponse
用于类或者方法,描述操作的可能响应。
  • code 响应的HTTP状态代码
  • message 响应附带的可读消息
10.@ResponseHeader
用于方法,响应头设置。
  • name 响应头名称
  • description 头描述
  • response 默认响应类 void
  • responseContainer 参考ApiOperation中配置
Swagger 导出离线 api 文档 1.导出 AsciiDocs、Markdown、Confluence 格式文档
添加依赖
io.github.swagger2markup swagger2markup 1.3.3

转换工具类
public class SwaggerUtils {private static final String url = "http://127.0.0.1:8080/v2/api-docs"; /** * 生成AsciiDocs格式文档 * @throws MalformedURLException */ public static void generateAsciiDocs() throws MalformedURLException { Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder() .withMarkupLanguage(MarkupLanguage.ASCIIDOC) .withOutputLanguage(Language.ZH) .withPathsGroupedBy(GroupBy.TAGS) .withGeneratedExamples() .withoutInlineSchema().build(); Swagger2MarkupConverter.from(new URL(url)) .withConfig(config) .build() .toFolder(Paths.get("./docs/asciidoc/generated")); } /** * 生成AsciiDocs格式文档,并汇总成一个文件 * @throws MalformedURLException */ public static void generateAsciiDocsToFile() throws MalformedURLException { Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder() .withMarkupLanguage(MarkupLanguage.ASCIIDOC) .withOutputLanguage(Language.ZH) .withPathsGroupedBy(GroupBy.TAGS) .withGeneratedExamples() .withoutInlineSchema() .build(); Swagger2MarkupConverter.from(new URL(url)) .withConfig(config) .build() .toFile(Paths.get("./docs/asciidoc/generated/all")); }/** * 生成Markdown格式文档 * @throws MalformedURLException */ public static void generateMarkdownDocs() throws MalformedURLException { Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder() .withMarkupLanguage(MarkupLanguage.MARKDOWN) .withOutputLanguage(Language.ZH) .withPathsGroupedBy(GroupBy.TAGS) .withGeneratedExamples() .withoutInlineSchema() .build(); Swagger2MarkupConverter.from(new URL(url)) .withConfig(config) .build() .toFolder(Paths.get("./docs/markdown/generated")); } /** * 生成Markdown格式文档,并汇总成一个文件 * @throws MalformedURLException */ public static void generateMarkdownDocsToFile() throws MalformedURLException { Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder() .withMarkupLanguage(MarkupLanguage.MARKDOWN) .withOutputLanguage(Language.ZH) .withPathsGroupedBy(GroupBy.TAGS) .withGeneratedExamples() .withoutInlineSchema() .build(); Swagger2MarkupConverter.from(new URL(url)) .withConfig(config) .build() .toFile(Paths.get("./docs/markdown/generated/all")); }/** * 生成Confluence格式文档 * @throws MalformedURLException */ public static void generateConfluenceDocs() throws MalformedURLException { Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder() .withMarkupLanguage(MarkupLanguage.CONFLUENCE_MARKUP) .withOutputLanguage(Language.ZH) .withPathsGroupedBy(GroupBy.TAGS) .withGeneratedExamples() .withoutInlineSchema() .build(); Swagger2MarkupConverter.from(new URL(url)) .withConfig(config) .build() .toFolder(Paths.get("./docs/confluence/generated")); }/** * 生成Confluence格式文档,并汇总成一个文件 * @throws MalformedURLException */ public static void generateConfluenceDocsToFile() throws MalformedURLException { Swagger2MarkupConfig config = new Swagger2MarkupConfigBuilder() .withMarkupLanguage(MarkupLanguage.CONFLUENCE_MARKUP) .withOutputLanguage(Language.ZH) .withPathsGroupedBy(GroupBy.TAGS) .withGeneratedExamples() .withoutInlineSchema() .build(); Swagger2MarkupConverter.from(new URL(url)) .withConfig(config) .build() .toFile(Paths.get("./docs/confluence/generated/all")); }}

使用测试 Controller
@RestController @RequestMapping("/export") @ApiIgnore public class ExportController {@RequestMapping("/ascii") public String exportAscii() throws MalformedURLException{ SwaggerUtils.generateAsciiDocs(); return "success"; }@RequestMapping("/asciiToFile") public String asciiToFile() throws MalformedURLException{ SwaggerUtils.generateAsciiDocsToFile(); return "success"; }@RequestMapping("/markdown") public String exportMarkdown() throws MalformedURLException{ SwaggerUtils.generateMarkdownDocs(); return "success"; }@RequestMapping("/markdownToFile") public String exportMarkdownToFile() throws MalformedURLException{ SwaggerUtils.generateMarkdownDocsToFile(); return "success"; }@RequestMapping("/confluence") public String confluence() throws MalformedURLException{ SwaggerUtils.generateConfluenceDocs(); return "success"; }@RequestMapping("/confluenceToFile") public String confluenceToFile() throws MalformedURLException{ SwaggerUtils.generateConfluenceDocsToFile(); return "success"; } }

2.导出 html、pdf、xml 格式
添加依赖
org.springframework.restdocs spring-restdocs-mockmvc test io.springfox springfox-staticdocs 2.6.1

org.springframework.boot spring-boot-maven-plugin io.github.swagger2markup swagger2markup-maven-plugin 1.3.1 http://127.0.0.1:8080/v2/api-docs ./docs/asciidoc/generated ASCIIDOC org.asciidoctor asciidoctor-maven-plugin 1.5.3 org.asciidoctor asciidoctorj-pdf 1.5.0-alpha.10.1 org.jruby jruby-complete 1.7.21 ./docs/asciidoc/generated ./docs/asciidoc/html htmltrue book coderayleft3true

可以修改此处 html 和 pdf,通过 mvn asciidoctor:process-asciidoc 可以导出相应格式文件
./docs/asciidoc/html html

执行 mvn asciidoctor:process-asciidoc 后再执行 mvn generate-resources,可在 targt/generated-docs 目录下生成 xml 格式文件。
完整代码 github
码云
非特殊说明,本文版权归 朝雾轻寒 所有,转载请注明出处.
原文标题:Spring Boot 2.X(十五):集成 Swagger2 开发 API 文档(在线+离线)
原文地址: https://www.zwqh.top/article/info/24

    推荐阅读