Springboot2整合knife4j過(guò)程解析
knife4j官網(wǎng):https://doc.xiaominfo.com/guide/useful.html
這玩藝就swagger的升級(jí)版,但是用起來(lái)比swagger方便多了,至少不會(huì)出現(xiàn)莫名的版本兼容問(wèn)題
下面記錄一個(gè)配置示例
1.代碼結(jié)構(gòu)
2.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 https://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.5.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.example</groupId> <artifactId>knife4j-demo</artifactId> <version>0.0.1-SNAPSHOT</version> <name>knife4j-demo</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>com.github.xiaoymin</groupId> <artifactId>knife4j-spring-boot-starter</artifactId> <!--在引用時(shí)請(qǐng)?jiān)趍aven中央倉(cāng)庫(kù)搜索最新版本號(hào)--> <version>2.0.2</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.58</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.10</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
3.配置類
package com.example.knife4j.demo.config; import com.github.xiaoymin.knife4j.spring.annotations.EnableKnife4j; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import springfox.bean.validators.configuration.BeanValidatorPluginsConfiguration; import springfox.documentation.builders.ApiInfoBuilder; import springfox.documentation.builders.PathSelectors; import springfox.documentation.builders.RequestHandlerSelectors; import springfox.documentation.service.ApiInfo; import springfox.documentation.spi.DocumentationType; import springfox.documentation.spring.web.plugins.Docket; import springfox.documentation.swagger2.annotations.EnableSwagger2; @Configuration @EnableSwagger2 @EnableKnife4j @Import(BeanValidatorPluginsConfiguration.class) public class SwaggerConfiguration { @Bean(value = "defaultApi2") public Docket defaultApi2() { Docket docket=new Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo()) //分組名稱 .groupName("2.X版本") .select() //這里指定Controller掃描包路徑(項(xiàng)目路徑也行) .apis(RequestHandlerSelectors.basePackage("com.example.knife4j.demo")) .paths(PathSelectors.any()) .build(); return docket; } private ApiInfo apiInfo() { return new ApiInfoBuilder() .title("不重要") .description("測(cè)試名稱不重要") .termsOfServiceUrl("http://localhost:88888/") .contact("10086@mail.com") .version("1.0") .build(); } }
4.模型bean
package com.example.knife4j.demo.beans; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; /** * 創(chuàng)建時(shí)間: 23:09 2018/9/19 * 修改時(shí)間: * 編碼人員: ZhengQf * 版 本: 0.0.1 * 功能描述: */ @ApiModel(value = "用戶模型") public class UserEntity { @ApiModelProperty(value="id" ,required= true,example = "123") private Integer id; @ApiModelProperty(value="用戶姓名" ,required=true,example = "鄭欽鋒") private String name; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "DemoDoctor [id=" + id + ", name=" + name + "]"; } }
5.兩個(gè)接口controller
package com.example.knife4j.demo.controller; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @Api(value = "IndexController測(cè)試接口") @RestController public class IndexController { @ApiOperation(value = "測(cè)試index接口", nickname = "測(cè)試IndexController的index接口") @GetMapping("/index") public String index() { return "測(cè)試IndexController的index接口..."; } }
package com.example.knife4j.demo.controller; import com.example.knife4j.demo.beans.UserEntity; 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.*; @Api(value = "用戶接口") @RestController public class UserController { @ApiOperation(value = "獲取用戶信息接口", nickname = "根據(jù)用戶ID獲取用戶相關(guān)信息") @ApiImplicitParam(name = "id", value = "用戶ID", required = true, dataType = "int") @PostMapping("/postMember") public UserEntity postMember(@RequestParam Integer id) { UserEntity userEntity = new UserEntity(); userEntity.setId(id); userEntity.setName("admin"); return userEntity; } @ApiOperation(value = "添加用戶", nickname = "添加用戶接口1", notes = "入?yún)⑹菑?fù)雜對(duì)象", produces = "application/json") @PostMapping("/postUser") @ResponseBody @ApiImplicitParam(paramType = "query", name = "userId", value = "用戶id", required = true, dataType = "int") public UserEntity postUser(@RequestBody UserEntity user, @RequestParam("userId") int userId) { // 這里用包裝類竟然報(bào)錯(cuò) if (user.getId() == userId) { return user; } return new UserEntity(); } @ApiOperation(value = "添加用戶", nickname = "添加用戶接口2", notes = "入?yún)⑹呛?jiǎn)單對(duì)象", produces = "application/json") @PostMapping("/addUser") @ResponseBody @ApiImplicitParams({ @ApiImplicitParam(paramType = "query", name = "userName", value = "用戶姓名", required = true, dataType = "String"), @ApiImplicitParam(paramType = "query", name = "id", value = "用戶id", required = true, dataType = "int")}) public UserEntity addUser(String userName, int id) { UserEntity userEntity = new UserEntity(); userEntity.setName(userName); userEntity.setId(id); return userEntity; } }
6.srpingboot項(xiàng)目啟動(dòng)類
package com.example.knife4j.demo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import springfox.documentation.spring.web.SpringfoxWebMvcConfiguration; @ConditionalOnClass(SpringfoxWebMvcConfiguration.class) @SpringBootApplication public class Knife4jDemoApplication implements WebMvcConfigurer { public static void main(String[] args) { SpringApplication.run(Knife4jDemoApplication.class, args); } @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("doc.html").addResourceLocations("classpath:/META-INF/resources/"); registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/"); } }
這樣簡(jiǎn)單一配置,就ok了,瀏覽器訪問(wèn):http://127.0.0.1:8080/doc.html
不過(guò),在項(xiàng)目中我使用了ResponseBodyAdvice接口對(duì)項(xiàng)目接口響應(yīng)內(nèi)容做統(tǒng)一處理,然后使用knife4j就出問(wèn)題了。
ResponseBodyAdvice接口實(shí)現(xiàn)如下:
import org.springframework.context.annotation.Configuration; import org.springframework.core.MethodParameter; import org.springframework.http.MediaType; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.server.ServerHttpRequest; import org.springframework.http.server.ServerHttpResponse; import org.springframework.web.bind.annotation.RestControllerAdvice; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice; /** * 自定義advise ,對(duì)restful請(qǐng)求響應(yīng)體進(jìn)行統(tǒng)一規(guī)范 */ @EnableWebMvc @Configuration @RestControllerAdvice public class ResponseAdvise implements ResponseBodyAdvice<Object> { @Override public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) { return true; } @Override public Object beforeBodyWrite(Object object, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) { if (object instanceof ResponseData) { return object; } return ResponseData.of().setData(object); } }
請(qǐng)求報(bào)錯(cuò)
而且后臺(tái)還說(shuō)找不到映射路徑
2020-03-10 23:31:01.533 WARN 7940 --- [nio-8080-exec-1] o.s.web.servlet.PageNotFound : No mapping for GET /service-worker.js
2020-03-10 23:31:01.560 WARN 7940 --- [nio-8080-exec-4] o.s.web.servlet.PageNotFound : No mapping for GET /favicon.ico
2020-03-10 23:31:14.468 WARN 7940 --- [nio-8080-exec-8] o.s.web.servlet.PageNotFound : No mapping for GET /service-worker.js
然后,我在ResponseAdvise#beforeBodyWrite方法中打上斷點(diǎn),發(fā)現(xiàn)我將swagger的請(qǐng)求內(nèi)容進(jìn)行了修改,以至于報(bào)了404。
最后在ResponseAdvise類上聲明只對(duì)本項(xiàng)目的響應(yīng)體內(nèi)容進(jìn)行統(tǒng)一處理
@RestControllerAdvice(basePackages = "com.example.knife4j.demo")
這樣,就完全ok!
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Java使用Condition控制線程通信的方法實(shí)例詳解
這篇文章主要介紹了Java使用Condition控制線程通信的方法,結(jié)合實(shí)例形式分析了使用Condition類同步檢測(cè)控制線程通信的相關(guān)操作技巧,需要的朋友可以參考下2019-09-09SpringCloud整合Nacos實(shí)現(xiàn)流程詳解
這篇文章主要介紹了SpringCloud整合Nacos實(shí)現(xiàn)流程詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-09-09解決SpringBoot項(xiàng)目中l(wèi)og4j與logback的Jar包沖突問(wèn)題
這篇文章主要給大家介紹了解決SpringBoot項(xiàng)目中l(wèi)og4j與logback的Jar包沖突問(wèn)題,文中有詳細(xì)的解決方法和沖突的原因,有遇到相同問(wèn)題的朋友可以參考閱讀本文2023-10-10只用400行Java代碼就能實(shí)現(xiàn)的飛翔的小鳥(niǎo)游戲
今天給大家?guī)?lái)的是關(guān)于Java實(shí)戰(zhàn)的相關(guān)知識(shí),文章圍繞著只用400行Java代碼就能實(shí)現(xiàn)的飛翔的小鳥(niǎo)游戲展開(kāi),文中有非常詳細(xì)的介紹及代碼示例,需要的朋友可以參考下2021-06-06基于redis setIfAbsent的使用說(shuō)明
這篇文章主要介紹了基于redis setIfAbsent的使用說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-01-01

Spring WebFlux使用函數(shù)式編程模型構(gòu)建異步非阻塞服務(wù)