swagger2和knife4j的詳細使用教程(入門級)
入門級swagger2和knife4j的詳細使用
重要的使事情說三遍
重要的使事情說三遍
重要的使事情說三遍
使用swagge或knife4j都有與springboot的版本兼容問題,該文章使用的springboot版本是2.2.2.RELEASE版本,如果高版本可能會出現(xiàn)啟動報錯
1、swagger介紹
相信無論是前端還是后端開發(fā),都或多或少地被接口文檔折磨過。前端經(jīng)常抱怨后端給的接口文檔與實際情況不一致。后端又覺得編寫及維護接口文檔會耗費不少精力,經(jīng)常來不及更新。其實無論是前端調(diào)用后端,還是后端調(diào)用后端,都期望有一個好的接口文檔。但是這個接口文檔對于程序員來說,就跟注釋一樣,經(jīng)常會抱怨別人寫的代碼沒有寫注釋,然而自己寫起代碼起來,最討厭的,也是寫注釋。所以僅僅只通過強制來規(guī)范大家是不夠的,隨著時間推移,版本迭代,接口文檔往往很容易就跟不上代碼了。
使用Swagger你只需要按照它的規(guī)范去定義接口及接口相關的信息。再通過Swagger衍生出來的一系列項目和工具,就可以做到生成各種格式的接口文檔,生成多種語言的客戶端和服務端的代碼,以及在線接口調(diào)試頁面等等。這樣,如果按照新的開發(fā)模式,在開發(fā)新版本或者迭代版本的時候,只需要更新Swagger描述文件,就可以自動生成接口文檔和客戶端服務端代碼,做到調(diào)用端代碼、服務端代碼以及接口文檔的一致性。
為了簡化swagger的使用,Spring框架對swagger進行了整合,建立了Spring-swagger項目,后面改成了現(xiàn)在的Springfox。通過在項目中引入Springfox,可以掃描相關的代碼,生成描述文件,進而生成與代碼一致的接口文檔和客戶端代碼。
Springfox對應的maven坐標如下:
注意:swagger與springBoot的版本是有兼用性的,需要對應的版本號
<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>
2、swagger常用注解
注解 | 說明 |
---|---|
@Api | 用在請求的類上,例如Controller,表示對類的說明 |
@ApiModel | 用在類上,通常是實體類,表示一個返回響應數(shù)據(jù)的信息 |
@ApiModelProperty | 用在屬性上,描述響應類的屬性 |
@ApiOperation | 用在請求的方法上,說明方法的用途、作用 |
@ApiImplicitParams | 用在請求的方法上,表示一組參數(shù)說明 |
@ApiImplicitParam | 用在@ApiImplicitParams注解中,指定一個請求參數(shù)的各個方面 |
3、 swagger入門案例
3.1、第一步:創(chuàng)建maven工程swagger_demo并配置pom.xml文件
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.2.2.RELEASE</version> <relativePath/> </parent> <groupId>org.example</groupId> <artifactId>swagger_demo</artifactId> <version>1.0-SNAPSHOT</version> <properties> <maven.compiler.source>8</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <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> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> </dependencies> </project>
3.2、創(chuàng)建application.yml文件
server: port: 9000
3.3、第三步: 創(chuàng)建實體類User和Menu
package com.zcl.entity; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; /** * 項目名稱:swagger_demo * 描述:用戶實體類 * * @author zhong * @date 2022-08-29 6:50 */ @Data @ApiModel(value = "用戶實體",description = "用戶響應實體") public class User { @ApiModelProperty(value = "主鍵") private int id; @ApiModelProperty(value = "姓名") private String name; @ApiModelProperty(value = "年齡") private int age; @ApiModelProperty(value = "地址") private String address; }
package com.zcl.entity; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; /** * 項目名稱:swagger_demo * 描述:菜單實體類 * * @author zhong * @date 2022-08-29 6:49 */ @Data @ApiModel(value = "菜單實體",discriminator = "菜單實體描述") public class Menu { @ApiModelProperty(value = "主鍵") private int id; @ApiModelProperty(value = "菜單名稱") private String name; }
3.4、第四步:創(chuàng)建UserController和MenuController
package com.zcl.controller.user; import com.zcl.entity.User; 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.*; import java.util.ArrayList; import java.util.List; /** * 項目名稱:swagger_demo * 描述:用戶控制器 * * @author zhong * @date 2022-08-29 6:55 */ @Api(value = "用戶控制器") @RestController @RequestMapping("/user") public class UserController { @GetMapping("/getUsers") @ApiOperation(value = "查詢所有用戶", notes = "查詢所有用戶信息") public List<User> getAllUsers(){ User user = new User(); user.setId(100); user.setName("itcast"); user.setAge(20); user.setAddress("bj"); List<User> list = new ArrayList<>(); list.add(user); return list; } @PostMapping("/save") @ApiOperation(value = "新增用戶", notes = "新增用戶信息") public String save(@RequestBody User user){ return "OK"; } @PutMapping("/update") @ApiOperation(value = "修改用戶", notes = "修改用戶信息") public String update(@RequestBody User user){ return "OK"; } @DeleteMapping("/delete") @ApiOperation(value = "刪除用戶", notes = "刪除用戶信息") public String delete(int id){ return "OK"; } @ApiImplicitParams({ @ApiImplicitParam(name = "pageNum", value = "頁碼", required = true, type = "Integer"), @ApiImplicitParam(name = "pageSize", value = "每頁條數(shù)", required = true, type = "Integer"), }) @ApiOperation(value = "分頁查詢用戶信息") @GetMapping(value = "page/{pageNum}/{pageSize}") public String findByPage(@PathVariable Integer pageNum, @PathVariable Integer pageSize) { return "OK"; } }
package com.zcl.controller.menu; import com.zcl.entity.Menu; 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.*; import java.util.ArrayList; import java.util.List; /** * 項目名稱:swagger_demo * 描述:菜單控制器 * * @author zhong * @date 2022-08-29 7:00 */ @Api(tags = "菜單控制器") @RestController @RequestMapping("/menu") public class MenuController { @GetMapping("/getMenus") @ApiOperation(value = "查詢所有菜單", notes = "查詢所有菜單信息") public List<Menu> getMenus(){ Menu menu = new Menu(); menu.setId(100); menu.setName("itcast"); List<Menu> list = new ArrayList<>(); list.add(menu); return list; } @PostMapping("/save") @ApiOperation(value = "新增菜單", notes = "新增菜單信息") public String save(@RequestBody Menu menu){ return "OK"; } @PutMapping("/update") @ApiOperation(value = "修改菜單", notes = "修改菜單信息") public String update(@RequestBody Menu menu){ return "OK"; } @DeleteMapping("/delete") @ApiOperation(value = "刪除菜單", notes = "刪除菜單信息") public String delete(int id){ return "OK"; } @ApiImplicitParams({ @ApiImplicitParam(name = "pageNum", value = "頁碼", required = true, type = "Integer"), @ApiImplicitParam(name = "pageSize", value = "每頁條數(shù)", required = true, type = "Integer"), }) @ApiOperation(value = "分頁查詢菜單信息") @GetMapping(value = "page/{pageNum}/{pageSize}") public String findByPage(@PathVariable Integer pageNum, @PathVariable Integer pageSize) { return "OK"; } }
3.5、第五步:創(chuàng)建配置類SwaggerAutoConfiguration
package com.zcl.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import springfox.documentation.builders.ApiInfoBuilder; 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; /** * 項目名稱:swagger_demo * 描述:swagger自動配置類 * * @author zhong * @date 2022-08-29 7:04 */ @Configuration @EnableSwagger2 public class SwaggerAutoConfiguration { @Bean public Docket createRestApi1() { Docket docket = new Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo()).groupName("用戶接口組") .select() //為當前包路徑 .apis(RequestHandlerSelectors.basePackage("com.zcl.controller.user")) .build(); return docket; } @Bean public Docket createRestApi2() { Docket docket = new Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo()).groupName("菜單接口組") .select() //為當前包路徑 .apis(RequestHandlerSelectors.basePackage("com.zcl.controller.menu")) .build(); return docket; } //構建 api文檔的詳細信息 private ApiInfo apiInfo() { return new ApiInfoBuilder() //頁面標題 .title("API接口文檔") //創(chuàng)建人 .contact(new Contact("雕刻筆記", "http://xiaozhong01.top", "")) //版本號 .version("1.0") //描述 .description("API 描述") .build(); } }
注意:如果不需要進行分組,可以將后面的createRestApi2()
進行刪除就剩余一個組了,并將.groupName("用戶接口組")
分組描述去掉以及將掃描控制器包修改即可
3.6、第六步:創(chuàng)建啟動類SwaggerApplication
package com.zcl; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * 項目名稱:swagger_demo * 描述:swagger項目啟動類 * * @author zhong * @date 2022-08-29 7:13 */ @SpringBootApplication public class SwaggerApplication { public static void main(String[] args) { SpringApplication.run(SwaggerApplication.class,args); } }
3.7、項目啟動
執(zhí)行啟動類main方法啟動項目,訪問地址:http://localhost:9000/swagger-ui.html
4、knife4j介紹
knife4j是為Java MVC框架集成Swagger生成Api文檔的增強解決方案,前身是swagger-bootstrap-ui,取名knife4j是希望它能像一把匕首一樣小巧,輕量,并且功能強悍!其底層是對Springfox的封裝,使用方式也和Springfox一致,只是對接口文檔UI進行了優(yōu)化。
核心功能:
- 文檔說明:根據(jù)Swagger的規(guī)范說明,詳細列出接口文檔的說明,包括接口地址、類型、請求示例、請求參數(shù)、響應示例、響應參數(shù)、響應碼等信息,對該接口的使用情況一目了然。
- 在線調(diào)試:提供在線接口聯(lián)調(diào)的強大功能,自動解析當前接口參數(shù),同時包含表單驗證,調(diào)用參數(shù)可返回接口響應內(nèi)容、headers、響應時間、響應狀態(tài)碼等信息,幫助開發(fā)者在線調(diào)試。
5、knife4j入門案例
第一步:創(chuàng)建maven工程knife4j_demo并配置pom.xml文件
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.2.2.RELEASE</version> <relativePath/> </parent> <groupId>org.example</groupId> <artifactId>knife4j</artifactId> <version>1.0-SNAPSHOT</version> <properties> <maven.compiler.source>8</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>com.github.xiaoymin</groupId> <artifactId>knife4j-spring-boot-starter</artifactId> <version>2.0.1</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> </dependencies> </project>
第二步: 創(chuàng)建實體類User和Menu
package com.zcl.entity; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; /** * 項目名稱:swagger_demo * 描述:菜單實體類 * * @author zhong * @date 2022-08-29 6:49 */ @Data @ApiModel(value = "菜單實體",discriminator = "菜單實體描述") public class Menu { @ApiModelProperty(value = "主鍵") private int id; @ApiModelProperty(value = "菜單名稱") private String name; }
package com.zcl.entity; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; /** * 項目名稱:swagger_demo * 描述:用戶實體類 * * @author zhong * @date 2022-08-29 6:50 */ @Data @ApiModel(value = "用戶實體",description = "用戶響應實體") public class User { @ApiModelProperty(value = "主鍵") private int id; @ApiModelProperty(value = "姓名") private String name; @ApiModelProperty(value = "年齡") private int age; @ApiModelProperty(value = "地址") private String address; }
第三步:創(chuàng)建UserController和MenuController
控制器與入門的swagger2是一樣的,直接復制下來
第四步:創(chuàng)建接口文檔配置屬性類SwaggerProperties
由于上一個
swagger_demo
的接口文檔配置文件是寫死在項目代碼中的,不利于后面的開發(fā)與維護,使用knife4j時并將相關的屬性配置以yml
全局的方式靈活的進行配置,方便進行修改
package com.zcl.config; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; /** * 項目名稱:knife4j * 描述:配置屬性類,用于封裝yml配置文件中關于接口相關的配置文件 * * @author zhong * @date 2022-08-29 7:58 */ @Data @ConfigurationProperties(prefix = "knife.swagger") public class SwaggerProperties { /**標題*/ private String title = "在線文檔"; /**自定義組名*/ private String group = ""; /**描述*/ private String description = "在線文檔"; /**版本*/ private String version = "1.0"; /**聯(lián)系人*/ private Contact contact = new Contact(); /**swagger會解析的包路徑*/ private String basePackage = "com.zcl"; /**swagger會解析的url規(guī)則*/ private List<String> basePath = new ArrayList<>(); /**在basePath基礎上需要排除的url規(guī)則*/ private List<String> excludePath = new ArrayList<>(); /**分組文檔*/ private Map<String, DocketInfo> docket = new LinkedHashMap<>(); public String getGroup() { if (group == null || "".equals(group)) { return title; } return group; } @Data public static class DocketInfo { /**標題*/ private String title = "在線文檔"; /**自定義組名*/ private String group = ""; /**描述*/ private String description = "在線文檔"; /**版本*/ private String version = "1.0"; /**聯(lián)系人*/ private Contact contact = new Contact(); /**swagger會解析的包路徑*/ private String basePackage = "com.zcl"; /**swagger會解析的url規(guī)則*/ private List<String> basePath = new ArrayList<>(); /**在basePath基礎上需要排除的url規(guī)則*/ private List<String> excludePath = new ArrayList<>(); /**分組文檔*/ private Map<String, DocketInfo> docket = new LinkedHashMap<>(); public String getGroup() { if (group == null || "".equals(group)) { return title; } return group; } } @Data public static class Contact { /**聯(lián)系人*/ private String name = "pinda"; /**聯(lián)系人url*/ private String url = ""; /**聯(lián)系人email*/ private String email = ""; } }
第五步:創(chuàng)建application.yml文件
該配置文件的屬性是對應上面的配置文件屬性的如果不對上就不會被讀取到
下面重點的是對【docket】進行map分組的屬性配置
private Map<String, DocketInfo> docket = new LinkedHashMap<>();
不進行分組的配置
server: port: 7788 knife: swagger: enabled: true #是否啟用swagger的開關 title: knife4j測試文檔 description: knife4j測試文檔描述 version: v1.0.0 basePackage: com.zcl.controller
進行分組的配置
server: port: 7788 knife: swagger: enabled: true #是否啟用swagger的開關 title: knife4j測試文檔 description: knife4j測試文檔描述 version: v1.0.0 docket: # 進行分組 user: # key # value title: 用戶模塊 base-package: com.zcl.controller.user menu: title: 菜單模塊 base-package: com.zcl.controller.menu
注意:上面配置文件中的enabled
屬性是對應著下面配置類中【@ConditionalOnProperty】通過注解判斷是否符合條件才讓配置類生效
第六步:創(chuàng)建配置類SwaggerAutoConfiguration
該配置類需要使到上面創(chuàng)建的
SwaggerProperties
生效以及需要啟用swagger注解
package com.zcl.config; import com.google.common.base.Predicate; import com.google.common.base.Predicates; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryAware; import org.springframework.beans.factory.config.ConfigurableBeanFactory; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; 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.annotation.Resource; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Set; /** * 項目名稱:knife4j * 描述:配置類 * * @author zhong * @date 2022-08-29 8:22 */ @Configuration @EnableConfigurationProperties(SwaggerProperties.class) @EnableSwagger2 @ConditionalOnProperty(name = "knife.swagger.enabled", havingValue = "true", matchIfMissing = true) public class SwaggerAutoConfiguration implements BeanFactoryAware { private BeanFactory beanFactory; /** * 通過類型注入去查找beanFactory * @param beanFactory * @throws BeansException */ @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { this.beanFactory = beanFactory; } /** * 注入自動配置屬性類 */ @Resource private SwaggerProperties swaggerProperties; /** * 遍歷swaggerProperties屬性配置的內(nèi)容,轉換成List集合【方便判斷有沒有進行分組,沒有分組就一個list,分組就有多個】 * 使用@ConditionalOnProperty條件注入,bean工程有就不創(chuàng)建 * @return */ @Bean @ConditionalOnMissingBean public List<Docket> createRestApi() { // 強轉beanFactory為可配置的bean工廠 ConfigurableBeanFactory configurableBeanFactory = (ConfigurableBeanFactory) beanFactory; // 創(chuàng)建返回的list集合 List<Docket> docketList = new ArrayList<>(); // 獲取到分組的對象如果為空就是不分組 if(swaggerProperties.getDocket().isEmpty()){ Docket docket = createDocket(swaggerProperties); docketList.add(docket); }else{ // 存在分組對象 // 獲取到key【user\menu】 Set<String> keySet = swaggerProperties.getDocket().keySet(); // 遍歷key獲取到對應的value for (String key : keySet) { // 獲取到info SwaggerProperties.DocketInfo docketInfo = swaggerProperties.getDocket().get(key); ApiInfo apiInfo = new ApiInfoBuilder() //頁面標題 .title(docketInfo.getTitle()) //創(chuàng)建人 .contact(new Contact(docketInfo.getContact().getName(), docketInfo.getContact().getUrl(), docketInfo.getContact().getEmail())) //版本號 .version(docketInfo.getVersion()) //描述 .description(docketInfo.getDescription()) .build(); // base-path處理 // 當沒有配置任何path的時候,解析/** if (docketInfo.getBasePath().isEmpty()) { docketInfo.getBasePath().add("/**"); } List<Predicate<String>> basePath = new ArrayList<>(); for (String path : docketInfo.getBasePath()) { basePath.add(PathSelectors.ant(path)); } // exclude-path處理 List<Predicate<String>> excludePath = new ArrayList<>(); for (String path : docketInfo.getExcludePath()) { excludePath.add(PathSelectors.ant(path)); } Docket docket = new Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo) .groupName(docketInfo.getGroup()) .select() //為當前包路徑 .apis(RequestHandlerSelectors.basePackage(docketInfo.getBasePackage())) .paths(Predicates.and(Predicates.not(Predicates.or(excludePath)),Predicates.or(basePath))) .build(); configurableBeanFactory.registerSingleton(key, docket); docketList.add(docket); } } return docketList; } /** * 構建 api文檔的詳細信息 * @param swaggerProperties * @return */ private ApiInfo apiInfo(SwaggerProperties swaggerProperties) { return new ApiInfoBuilder() //頁面標題 .title(swaggerProperties.getTitle()) //創(chuàng)建人 .contact(new Contact(swaggerProperties.getContact().getName(), swaggerProperties.getContact().getUrl(), swaggerProperties.getContact().getEmail())) //版本號 .version(swaggerProperties.getVersion()) //描述 .description(swaggerProperties.getDescription()) .build(); } /** * 創(chuàng)建接口文檔對象 * @param swaggerProperties 屬性配置 * @return */ private Docket createDocket(SwaggerProperties swaggerProperties) { //API 基礎信息 ApiInfo apiInfo = apiInfo(swaggerProperties); // base-path處理 // 當沒有配置任何path的時候,解析/** if (swaggerProperties.getBasePath().isEmpty()) { swaggerProperties.getBasePath().add("/**"); } List<Predicate<String>> basePath = new ArrayList<>(); for (String path : swaggerProperties.getBasePath()) { basePath.add(PathSelectors.ant(path)); } // exclude-path排除處理 List<Predicate<String>> excludePath = new ArrayList<>(); for (String path : swaggerProperties.getExcludePath()) { excludePath.add(PathSelectors.ant(path)); } return new Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo) .groupName(swaggerProperties.getGroup()) .select() .apis(RequestHandlerSelectors.basePackage(swaggerProperties.getBasePackage())) .paths(Predicates.and(Predicates.not(Predicates.or(excludePath)),Predicates.or(basePath))) .build(); } }
第七步:創(chuàng)建啟動類knife4jApplication
package com.zcl; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * 項目名稱:knife4j * 描述:knife4j項目啟動類 * * @author zhong * @date 2022-08-29 8:09 */ @SpringBootApplication public class knife4jApplication { public static void main(String[] args) { SpringApplication.run(knife4jApplication.class, args); } }
執(zhí)行啟動類main方法啟動項目,訪問地址:http://localhost:7788/doc.html
總結
到此這篇關于swagger2和knife4j的詳細使用教程的文章就介紹到這了,更多相關swagger2和knife4j使用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
啟用Spring事務管理@EnableTransactionManagement示例解析
這篇文章主要為大家介紹了啟用Spring事務管理@EnableTransactionManagement示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-09-09SpringMVC HttpMessageConverter報文信息轉換器
??HttpMessageConverter???,報文信息轉換器,將請求報文轉換為Java對象,或將Java對象轉換為響應報文。???HttpMessageConverter???提供了兩個注解和兩個類型:??@RequestBody,@ResponseBody???,??RequestEntity,ResponseEntity??2023-01-01解決springboot集成swagger碰到的坑(報404)
這篇文章主要介紹了解決springboot集成swagger碰到的坑(報404),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-06-06