相信不少後端開發在項目中都會碰到要寫 api 文檔,無論是給前端、移動端等提供更好的對接,仍是之後爲了之後交接方便,都會要求寫 api 文檔。html
而手寫 api 文檔的話有諸多痛點:前端
Swagger 就很好的解決了這個問題。git
Swagger 是一個規範和完整的框架,用於生成、描述、調用和可視化 RESTful 風格的 Web 服務。整體目標是使客戶端和文件系統做爲服務器以一樣的速度來更新。文件的方法,參數和模型緊密集成到服務器端的代碼,容許API來始終保持同步。github
官網:https://swagger.ioweb
<!--swagger2 --> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>2.9.2</version> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>2.9.2</version> </dependency>
@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(); } }
@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); } }
若是不添加此靜態資源配置會報錯,找不到相關路徑
@ApiModel(value = "UserEntity", description = "用戶對象") public class UserEntity implements Serializable{ /** * */ private static final long serialVersionUID = 5237730257103305078L; @ApiModelProperty(value ="用戶id",name="id",dataType="Long",required = false,example = "1",hidden = false ) private Long id; @ApiModelProperty(value ="用戶名",name="userName",dataType="String",required = false,example = "關羽" ) private String userName; @ApiModelProperty(value ="用戶性別",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; } }
@RestController @RequestMapping("/api") @Api(tags = { "接口分組1", "接口分組2" }) public class ApiController { @Autowired private UserDao userDao; @GetMapping("/getAllUser") @ApiOperation(value = "獲取全部用戶", notes = "", httpMethod = "GET", tags = "接口分組3") public List<UserEntity> getAll() { return userDao.getAll(); } @GetMapping("/getUserById") @ApiOperation(value = "根據id獲取用戶", notes = "id必傳", httpMethod = "GET") @ApiImplicitParam(name = "id", value = "用戶id",example = "1", required = true, dataType = "long", paramType = "query") public UserEntity getOne(Long id) { return userDao.getOne(id); } @PostMapping("/getUserByNameAndSex") @ApiOperation(value = "根據name和sex獲取用戶", notes = "", httpMethod = "POST") @ApiImplicitParams({ @ApiImplicitParam(name = "userName", value = "用戶名", example = "關羽", required = true, dataType = "string", paramType = "query"), @ApiImplicitParam(name = "userSex", value = "用戶性別", example = "男", required = true, dataType = "string", paramType = "query") }) public UserEntity getUserByNameAndSex(String userName, String userSex) { return userDao.getUserByNameAndSex(userName, userSex); } @PostMapping("/insertUser") @ApiOperation(value = "新增用戶", notes = "傳json,數據放body", httpMethod = "POST") @ApiImplicitParams({ @ApiImplicitParam(name = "body", value = "用戶對象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 = "修改用戶", notes = "傳json,數據放body", httpMethod = "POST") @ApiImplicitParams({ @ApiImplicitParam(name = "body", value = "用戶對象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 = "刪除用戶", notes = "id必傳", httpMethod = "POST") public String deleteUser(@ApiParam(name = "id", value = "用戶id", required = true) Long id) { userDao.deleteUser(id); return "{code:0,msg:'success'}"; } }
訪問 http://127.0.0.1:8080/swagger-ui.html 進行接口在線測試spring
用於類,表示標識這個類是swagger的資源。屬性以下:json
用於方法,表示一個http請求的操做。屬性以下:後端
用於方法、參數、字段說明;表示對參數的添加元數據。api
用於類,表示對類進行說明,用於參數用實體類接受。springboot
用於方法、字段,表示對model屬性的說明或者數據操做更改。
用於類、方法、方法參數,表示這個方法或者類被忽略,不在swagger-ui.html上顯示。
用於方法,表示單獨的請求參數。
用於方法,包含多個 @ApiImplicitParam。
用於類或者方法,描述操做的可能響應。
用於方法,響應頭設置。
添加依賴
<!-- swagger2markup 相關依賴 --> <dependency> <groupId>io.github.swagger2markup</groupId> <artifactId>swagger2markup</artifactId> <version>1.3.3</version> </dependency>
轉換工具類
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"; } }
添加依賴
<!--離線文檔 --> <dependency> <groupId>org.springframework.restdocs</groupId> <artifactId>spring-restdocs-mockmvc</artifactId> <scope>test</scope> </dependency> <!--springfox-staticdocs 生成靜態文檔 --> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-staticdocs</artifactId> <version>2.6.1</version> </dependency>
<build> <pluginManagement> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> <plugin> <groupId>io.github.swagger2markup</groupId> <artifactId>swagger2markup-maven-plugin</artifactId> <version>1.3.1</version> <configuration> <swaggerInput>http://127.0.0.1:8080/v2/api-docs</swaggerInput> <outputDir>./docs/asciidoc/generated</outputDir> <config> <swagger2markup.markupLanguage>ASCIIDOC</swagger2markup.markupLanguage> </config> </configuration> </plugin> <plugin> <groupId>org.asciidoctor</groupId> <artifactId>asciidoctor-maven-plugin</artifactId> <version>1.5.3</version> <!-- <version>2.0.0-RC.1</version> --> <!-- Include Asciidoctor PDF for pdf generation --> <dependencies> <dependency> <groupId>org.asciidoctor</groupId> <artifactId>asciidoctorj-pdf</artifactId> <version>1.5.0-alpha.10.1</version> </dependency> <dependency> <groupId>org.jruby</groupId> <artifactId>jruby-complete</artifactId> <version>1.7.21</version> </dependency> </dependencies> <configuration> <sourceDirectory>./docs/asciidoc/generated</sourceDirectory> <outputDirectory>./docs/asciidoc/html</outputDirectory> <backend>html</backend> <!-- <outputDirectory>./docs/asciidoc/pdf</outputDirectory> <backend>pdf</backend> --> <headerFooter>true</headerFooter> <doctype>book</doctype> <sourceHighlighter>coderay</sourceHighlighter> <attributes> <!-- 菜單欄在左邊 --> <toc>left</toc> <!-- 多標題排列 --> <toclevels>3</toclevels> <!-- 自動打數字序號 --> <sectnums>true</sectnums> </attributes> </configuration> </plugin> </plugins> </pluginManagement> </build>
能夠修改此處 html 和 pdf,經過 mvn asciidoctor:process-asciidoc 能夠導出相應格式文件
<outputDirectory>./docs/asciidoc/html</outputDirectory> <backend>html</backend>
執行 mvn asciidoctor:process-asciidoc 後再執行 mvn generate-resources,可在 targt/generated-docs 目錄下生成 xml 格式文件。
非特殊說明,本文版權歸 朝霧輕寒 全部,轉載請註明出處.
原文標題:Spring Boot 2.X(十五):集成 Swagger2 開發 API 文檔(在線+離線)
原文地址: https://www.zwqh.top/article/info/24
若是文章對您有幫助,請掃碼關注下個人公衆號,文章持續更新中...