knife4j official website: https://doc.xiaominfo.com/guide/useful.html#java%E5%BC%80%E5%8F%91
This stuff used to swagger upgraded version, but easy to use them more than swagger, at least not appear inexplicable version compatibility issues
The following configuration example of a recording
1. Structure Code
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> <!--在引用时请在maven中央仓库搜索最新版本号--> <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. Configure class
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 version" ) .Select () // This specifies Controller scan package path (path project is also OK) .apis (RequestHandlerSelectors.basePackage ( "com.example.knife4j.demo" )) .paths (PathSelectors .ANY ()) .build (); return Docket; } Private apiInfo apiInfo () { return new new ApiInfoBuilder () .title ( "important" ) .description ( "test name unimportant" ) .termsOfServiceUrl ( "HTTP: / / localhost: 88888 / " ) .contact ("[email protected]") .version("1.0") .build(); } }
4. Models bean
Package Penalty for com.example.knife4j.demo.beans; Import io.swagger.annotations.ApiModel; Import io.swagger.annotations.ApiModelProperty; / ** * Create a Time: 23:09 2018/9/19 * Modified: * coding art: ZhengQf * version: 0.0.1 * function: * / @ApiModel (value = "user model" ) public class userEntity { @ApiModelProperty (value = "ID", required = to true , Example = "123" ) Private Integer the above mentioned id; @ApiModelProperty (value = "user name", required = to true , Example = "Zheng Qinfeng" ) 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 + "]"; } }
The two controller interfaces
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 test interface" ) @RestController public class IndexController { @ApiOperation (value = "index test Interface", nickname = "Interface test IndexController the index" ) @GetMapping ( "/ index" ) public String index () { return "test IndexController the index interfaces ..."; } }
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 = "user Interface" ) @RestController public class the UserController { @ApiOperation (value = "Get user Interface information" , nickname = "get user information about a user ID" ) @ApiImplicitParam (name= "Id", value = "User ID", required = to true , dataType = "int" ) @PostMapping ( "/ postMember" ) public userEntity postMember (@RequestParam ID Integer) { userEntity userEntity = new new userEntity (); userEntity. the setId (ID); userEntity.setName ( "ADMIN" ); return userEntity; } @ApiOperation (value = "Add user", nickname = "Add user Interface 1", notes = "parameters into a complex object", produces = " the Application / json " ) @PostMapping ( " / postUser ") @ResponseBody @ApiImplicitParam(paramType = "Query", name = " userId", value = " User ID", required = to true , dataType = "int" ) public userEntity postUser (User @RequestBody userEntity, @RequestParam ( "the userId") int the userId) { // even given herein with packaging IF (user.getId () == the userId) { return user; } return new new userEntity (); } @ApiOperation (value = "Add user", nickname = "Add user Interface 2", notes = "argument is the simple Object", Produces = "file application / JSON" ) @PostMapping ( "/ the 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 project startup class
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/"); } }
Such a simple configuration, ok, browser access: http://127.0.0.1:8080/doc.html#/home
However, in the project I used ResponseBodyAdvice interface program interfaces response content to do centrally, then use knife4j on the problem.
ResponseBodyAdvice interface as follows:
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 ,对restful请求响应体进行统一规范 */ @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); } }
Request error
And backstage and said I can not find the path mapping
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
Then I marked in ResponseAdvise # beforeBodyWrite method breakpoints, I found the contents of the request will swagger has been modified, so that the reported 404.
The final statement on ResponseAdvise class only response body content of this project a unified process
@RestControllerAdvice(basePackages = "com.example.knife4j.demo")
In this way, it is completely ok!