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(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。