Springboot2整合knife4j过程解析
knife4j官网:https://doc.xiaominfo.com/guide/useful.html
这玩艺就swagger的升级版,但是用起来比swagger方便多了,至少不会出现莫名的版本兼容问题
下面记录一个配置示例
1.代码结构
2.pom.xml
4.0.0 org.springframework.boot spring-boot-starter-parent 2.2.5.RELEASE com.example knife4j-demo 0.0.1-SNAPSHOT knife4j-demo DemoprojectforSpringBoot 1.8 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-test test org.junit.vintage junit-vintage-engine com.github.xiaoymin knife4j-spring-boot-starter 2.0.2 com.alibaba fastjson 1.2.58 org.projectlombok lombok 1.18.10 org.springframework.boot spring-boot-maven-plugin
3.配置类
packagecom.example.knife4j.demo.config;
importcom.github.xiaoymin.knife4j.spring.annotations.EnableKnife4j;
importorg.springframework.context.annotation.Bean;
importorg.springframework.context.annotation.Configuration;
importorg.springframework.context.annotation.Import;
importspringfox.bean.validators.configuration.BeanValidatorPluginsConfiguration;
importspringfox.documentation.builders.ApiInfoBuilder;
importspringfox.documentation.builders.PathSelectors;
importspringfox.documentation.builders.RequestHandlerSelectors;
importspringfox.documentation.service.ApiInfo;
importspringfox.documentation.spi.DocumentationType;
importspringfox.documentation.spring.web.plugins.Docket;
importspringfox.documentation.swagger2.annotations.EnableSwagger2;
@Configuration
@EnableSwagger2
@EnableKnife4j
@Import(BeanValidatorPluginsConfiguration.class)
publicclassSwaggerConfiguration{
@Bean(value="defaultApi2")
publicDocketdefaultApi2(){
Docketdocket=newDocket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
//分组名称
.groupName("2.X版本")
.select()
//这里指定Controller扫描包路径(项目路径也行)
.apis(RequestHandlerSelectors.basePackage("com.example.knife4j.demo"))
.paths(PathSelectors.any())
.build();
returndocket;
}
privateApiInfoapiInfo(){
returnnewApiInfoBuilder()
.title("不重要")
.description("测试名称不重要")
.termsOfServiceUrl("http://localhost:88888/")
.contact("10086@mail.com")
.version("1.0")
.build();
}
}
4.模型bean
packagecom.example.knife4j.demo.beans;
importio.swagger.annotations.ApiModel;
importio.swagger.annotations.ApiModelProperty;
/**
*创建时间:23:092018/9/19
*修改时间:
*编码人员:ZhengQf
*版本:0.0.1
*功能描述:
*/
@ApiModel(value="用户模型")
publicclassUserEntity{
@ApiModelProperty(value="id",required=true,example="123")
privateIntegerid;
@ApiModelProperty(value="用户姓名",required=true,example="郑钦锋")
privateStringname;
publicIntegergetId(){
returnid;
}
publicvoidsetId(Integerid){
this.id=id;
}
publicStringgetName(){
returnname;
}
publicvoidsetName(Stringname){
this.name=name;
}
@Override
publicStringtoString(){
return"DemoDoctor[id="+id+",name="+name+"]";
}
}
5.两个接口controller
packagecom.example.knife4j.demo.controller;
importio.swagger.annotations.Api;
importio.swagger.annotations.ApiOperation;
importorg.springframework.web.bind.annotation.GetMapping;
importorg.springframework.web.bind.annotation.RestController;
@Api(value="IndexController测试接口")
@RestController
publicclassIndexController{
@ApiOperation(value="测试index接口",nickname="测试IndexController的index接口")
@GetMapping("/index")
publicStringindex(){
return"测试IndexController的index接口...";
}
}
packagecom.example.knife4j.demo.controller;
importcom.example.knife4j.demo.beans.UserEntity;
importio.swagger.annotations.Api;
importio.swagger.annotations.ApiImplicitParam;
importio.swagger.annotations.ApiImplicitParams;
importio.swagger.annotations.ApiOperation;
importorg.springframework.web.bind.annotation.*;
@Api(value="用户接口")
@RestController
publicclassUserController{
@ApiOperation(value="获取用户信息接口",nickname="根据用户ID获取用户相关信息")
@ApiImplicitParam(name="id",value="用户ID",required=true,dataType="int")
@PostMapping("/postMember")
publicUserEntitypostMember(@RequestParamIntegerid){
UserEntityuserEntity=newUserEntity();
userEntity.setId(id);
userEntity.setName("admin");
returnuserEntity;
}
@ApiOperation(value="添加用户",nickname="添加用户接口1",notes="入参是复杂对象",produces="application/json")
@PostMapping("/postUser")
@ResponseBody
@ApiImplicitParam(paramType="query",name="userId",value="用户id",required=true,dataType="int")
publicUserEntitypostUser(@RequestBodyUserEntityuser,@RequestParam("userId")intuserId){//这里用包装类竟然报错
if(user.getId()==userId){
returnuser;
}
returnnewUserEntity();
}
@ApiOperation(value="添加用户",nickname="添加用户接口2",notes="入参是简单对象",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")})
publicUserEntityaddUser(StringuserName,intid){
UserEntityuserEntity=newUserEntity();
userEntity.setName(userName);
userEntity.setId(id);
returnuserEntity;
}
}
6.srpingboot项目启动类
packagecom.example.knife4j.demo;
importorg.springframework.boot.SpringApplication;
importorg.springframework.boot.autoconfigure.SpringBootApplication;
importorg.springframework.boot.autoconfigure.condition.ConditionalOnClass;
importorg.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
importorg.springframework.web.servlet.config.annotation.WebMvcConfigurer;
importspringfox.documentation.spring.web.SpringfoxWebMvcConfiguration;
@ConditionalOnClass(SpringfoxWebMvcConfiguration.class)
@SpringBootApplication
publicclassKnife4jDemoApplicationimplementsWebMvcConfigurer{
publicstaticvoidmain(String[]args){
SpringApplication.run(Knife4jDemoApplication.class,args);
}
@Override
publicvoidaddResourceHandlers(ResourceHandlerRegistryregistry){
registry.addResourceHandler("doc.html").addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
}
}
这样简单一配置,就ok了,浏览器访问:http://127.0.0.1:8080/doc.html
不过,在项目中我使用了ResponseBodyAdvice接口对项目接口响应内容做统一处理,然后使用knife4j就出问题了。
ResponseBodyAdvice接口实现如下:
importorg.springframework.context.annotation.Configuration; importorg.springframework.core.MethodParameter; importorg.springframework.http.MediaType; importorg.springframework.http.converter.HttpMessageConverter; importorg.springframework.http.server.ServerHttpRequest; importorg.springframework.http.server.ServerHttpResponse; importorg.springframework.web.bind.annotation.RestControllerAdvice; importorg.springframework.web.servlet.config.annotation.EnableWebMvc; importorg.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice; /** *自定义advise,对restful请求响应体进行统一规范 */ @EnableWebMvc @Configuration @RestControllerAdvice publicclassResponseAdviseimplementsResponseBodyAdvice
请求报错
而且后台还说找不到映射路径
2020-03-1023:31:01.533WARN7940---[nio-8080-exec-1]o.s.web.servlet.PageNotFound:NomappingforGET/service-worker.js
2020-03-1023:31:01.560WARN7940---[nio-8080-exec-4]o.s.web.servlet.PageNotFound:NomappingforGET/favicon.ico
2020-03-1023:31:14.468WARN7940---[nio-8080-exec-8]o.s.web.servlet.PageNotFound:NomappingforGET/service-worker.js
然后,我在ResponseAdvise#beforeBodyWrite方法中打上断点,发现我将swagger的请求内容进行了修改,以至于报了404。
最后在ResponseAdvise类上声明只对本项目的响应体内容进行统一处理
@RestControllerAdvice(basePackages="com.example.knife4j.demo")
这样,就完全ok!
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。