SpringbootV2.6整合Knife4j 3.0.3 问题记录

参考

https://juejin.cn/post/7249173717749940284

近期由于升级到springboot2.6X,所以服务端很多组件都需要重新导入以及解决依赖问题。
下面就是一个很经典的问题了,
springboot2.6与knife4j的整合。

版本对应

springboot2.6与knife4j 3.0.3

  • 两者路径匹配模式不同

由于Springfox使用的路径匹配是基于AntPathMatcher,而Spring Boot 2.6.X使用的是PathPatternMatcher,所以将MVC的路径匹配规则改成 AntPathMatcher。具体配置如下:

--- application.yml:
spring:mvc:pathmatch:#Springfox使用的路径匹配是基于AntPathMatcher的,而Spring Boot 2.6.X使用的是PathPatternMatcher 解决knife4j匹配boot2.6.7 boot版本过高的问题matching-strategy: ant_path_matcher-- 或者:application.properties:
spring.mvc.pathmatch.matching-strategy=ANT_PATH_MATCHER
  • springboot加载springfox过程中失败:
    第一个点很多文章都提到了,但是我主要遇到的是第二个点,表现在:
"org.springframework.web.servlet.mvc.condition.PatternsRequestCondition.getPatterns()" because "this.condition" is null

这时候你可以

新增一个配置类,注意配置类不能放到swagger的配置类下,测试无效。配置Bean可以放在启动类下或者重新新增一个配置Bean,代码如下:

package net.w2p.AppBase.fixBugs;import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.ReflectionUtils;
import org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping;
import springfox.documentation.spring.web.plugins.WebFluxRequestHandlerProvider;
import springfox.documentation.spring.web.plugins.WebMvcRequestHandlerProvider;import java.lang.reflect.Field;
import java.util.List;
import java.util.stream.Collectors;/*** Springboot整合Knife4j问题修正*/
@Configuration
public class BeanPostProcessorConfig {@Beanpublic BeanPostProcessor springfoxHandlerProviderBeanPostProcessor() {return new BeanPostProcessor() {@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {if (bean instanceof WebMvcRequestHandlerProvider || bean instanceof WebFluxRequestHandlerProvider) {customizeSpringfoxHandlerMappings(getHandlerMappings(bean));}return bean;}private <T extends RequestMappingInfoHandlerMapping> void customizeSpringfoxHandlerMappings(List<T> mappings) {List<T> copy = mappings.stream().filter(mapping -> mapping.getPatternParser() == null).collect(Collectors.toList());mappings.clear();mappings.addAll(copy);}@SuppressWarnings("unchecked")private List<RequestMappingInfoHandlerMapping> getHandlerMappings(Object bean) {try {Field field = ReflectionUtils.findField(bean.getClass(), "handlerMappings");field.setAccessible(true);return (List<RequestMappingInfoHandlerMapping>) field.get(bean);} catch (IllegalArgumentException | IllegalAccessException e) {throw new IllegalStateException(e);}}};}}
  • 配置demo
package net.w2p.AppBase;import com.github.xiaoymin.knife4j.spring.annotations.EnableKnife4j;
import com.google.common.base.Function;
import com.google.common.base.Optional;
import com.google.common.base.Predicate;
import io.swagger.annotations.ApiOperation;
import net.w2p.WebExt.config.AppENV;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import springfox.documentation.RequestHandler;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.*;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.contexts.SecurityContext;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;import javax.servlet.http.HttpSession;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;import static springfox.documentation.builders.PathSelectors.regex;/** @Api: 修饰整个类,描述Controller的作用* @ApiOperation: 描述一个类的一个方法,或者说一个接口* @ApiParam: 单个参数描述* @ApiModel: 用对象来接收参数* @ApiProperty: 用对象接收参数时,描述对象的一个字段* @ApiResponse: HTTP响应其中1个描述* @ApiResponses: HTTP响应整体描述* @ApiIgnore: 使用该注解忽略这个API* @ApiError :发生错误返回的信息* @ApiImplicitParam: 一个请求参数* @ApiImplicitParams: 多个请求参数*  doc.html*/@EnableSwagger2
@Configuration
@EnableKnife4jpublic class Swagger2Configuration implements WebMvcConfigurer {private String accessToken="token";private String title;private String description;private String version;private String termsOfServiceUrl;private String name;private String url;private String email;@Beanpublic Docket createRestApi() {boolean isEnableSwagger=true;if(!"test".equalsIgnoreCase(AppENV.getEnv())&&!"dev".equalsIgnoreCase(AppENV.getEnv())){isEnableSwagger=false;}if("dev".equalsIgnoreCase(AppENV.getEnv())){isEnableSwagger=true;}else{isEnableSwagger=false;}String scanPaths = "net.w2p.AppBase.controller.api;" +"net.w2p.AppBase.controller.common;" ;return new Docket(DocumentationType.SWAGGER_2).enable(isEnableSwagger).apiInfo(apiInfo())//                .enable(enableSwagger).directModelSubstitute(Timestamp.class, Long.class)//将Timestamp类型全部转为Long类型.directModelSubstitute(Date.class, Long.class)//将Date类型全部转为Long类型.forCodeGeneration(true).select().apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
//                .apis(RequestHandlerSelectors.any()).apis(basePackage(scanPaths))
//                .paths(PathSelectors.ant("/api/**"))
//                .paths(regex("^.*(?<!error)$")).paths(PathSelectors.any()).build()// 添加忽略类型.ignoredParameterTypes(HttpSession.class).securitySchemes(securitySchemes()).securityContexts(securityContexts());}private List<SecurityScheme> securitySchemes() {List<SecurityScheme> apiKeyList= new ArrayList();apiKeyList.add(new ApiKey("token", "token", "header"));return apiKeyList;}private List<SecurityContext> securityContexts() {List<SecurityContext> securityContexts=new ArrayList<>();securityContexts.add(SecurityContext.builder().securityReferences(defaultAuth()).forPaths(regex("^(?!auth).*$")).build());return securityContexts;}private List<SecurityReference> defaultAuth() {AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];authorizationScopes[0] = authorizationScope;List<SecurityReference> securityReferences = new ArrayList<>();securityReferences.add(new SecurityReference(accessToken, authorizationScopes));return securityReferences;}private ApiInfo apiInfo() {return new ApiInfoBuilder().title("api文档").description("综合前台网站").termsOfServiceUrl("http://www.baidu.com").contact(new Contact("freeLife","baidu.com","1000@qq.com")).version("2.9.2").build();}@Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry) {System.out.println("================> add doc.html -url");registry.addResourceHandler("doc.html").addResourceLocations("classpath:/META-INF/resources/");
//        registry.addResourceHandler("swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/");registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");}// 定义分隔符private static final String splitor = ";";/*** 声明基础包** @param basePackage 基础包路径* @return*/public static Predicate<RequestHandler> basePackage(final String basePackage) {return input -> declaringClass(input).transform(handlerPackage(basePackage)).or(true);}/*** 校验基础包** @param basePackage 基础包路径* @return*/private static Function<Class<?>, Boolean> handlerPackage(final String basePackage) {return input -> {for (String strPackage : basePackage.split(splitor)) {boolean isMatch = input.getPackage().getName().startsWith(strPackage);if (isMatch) {return true;}}return false;};}/*** 检验基础包实例** @param requestHandler 请求处理类* @return*/@SuppressWarnings("deprecation")private static Optional<? extends Class<?>> declaringClass(RequestHandler requestHandler) {return Optional.fromNullable(requestHandler.declaringClass());}
}

运行结果

在这里插入图片描述
正常运行。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/454248.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【UE 材质】扇形材质

目录 效果 步骤 &#xff08;1&#xff09;控制扇形的弧宽度 &#xff08;2&#xff09;控制扇形的角度 &#xff08;3&#xff09;完整节点 效果 步骤 &#xff08;1&#xff09;控制扇形的弧宽度 创建一个材质&#xff0c;混合模式设置为“Additive”&#xff0c;着色…

Python中的HTTP代理与网络安全

在当今数字化的世界里&#xff0c;网络安全已经成为我们无法忽视的重要议题。无数的信息在网络上传递&#xff0c;而我们的隐私和敏感数据也在这个过程中可能面临被窃取或滥用的风险。在Python编程中&#xff0c;HTTP代理作为一种工具&#xff0c;能够在网络安全方面发挥重要的…

JVM 性能调优 - Java 中的四种引用(4)

为什么会有四种引用 我们先回顾下在 Java 虚拟机内存体系(1) 中提到了的垃圾回收算法 1、引用计数法 原理:给对象添加一个引用计数器,每当有一个地方引用它,计数器的值就加一。每当有一个引用失效,计数器的值就减一。当计数器值为零时,这个对象被认为没有其他对象引用,…

瑞_数据结构与算法_B树

文章目录 1 什么是B树1.1 B树的背景1.2 B 的含义1.3 B-树的度和阶1.4 B-树的特性1.5 B-树演变过程示例 2 B-树的Java实现2.1 B树节点类Node &#x1f64a;前言&#xff1a;本文章为瑞_系列专栏之《数据结构与算法》的B树篇。由于博主是从B站黑马程序员的《数据结构与算法》学习…

【高质量精品】2024美赛A题22页word版成品论文+数据+多版本前三问代码及代码讲解+前四问思路模型等(后续会更新)

一定要点击文末的卡片&#xff0c;进入后&#xff0c;即可获取完整资料后续参考论文!! 整体分析:这个题目是一个典型的生态系统建模问题&#xff0c;涉及到动物种群的性比例变化、资源可用性、环境因素、生态系统相互作用等多个方面。这个题目的难点在于如何建立一个合理的数学…

ppt形状导入draw.io

draw.io里面的形状还是有点少&#xff0c;我有时想找一个形状&#xff0c;发现PPT里有&#xff0c;但draw.io里有&#xff0c;比如 也就是这个形状 最简单的想法就是我直接把这个形状在PPT里存成图片&#xff08;png)&#xff0c;然后再导入到draw.io里&#xff0c;但是结果是…

linux下 Make 和 Makefile构建你的项目

Make 和 Makefile构建你的项目 介绍 在软件开发中&#xff0c;构建项目是一个必不可少的步骤。make 是一个强大的自动化构建工具&#xff0c;而 Makefile 是 make 工具使用的配置文件&#xff0c;用于描述项目的构建规则和依赖关系。本篇博客将介绍 make 和 Makefile 的基本概…

VS Code+Live Server插件开发游戏并结合内网穿透分享好友异地访问

文章目录 前言1. 编写MENJA小游戏2. 安装cpolar内网穿透3. 配置MENJA小游戏公网访问地址4. 实现公网访问MENJA小游戏5. 固定MENJA小游戏公网地址 前言 本篇教程&#xff0c;我们将通过VS Code实现远程开发MENJA小游戏&#xff0c;并通过cpolar内网穿透发布到公网&#xff0c;分…

《MySQL》超详细笔记

目录 基本知识 主流数据库 数据库基本概念 MySQL启动 数据库基本命令 数据库 启动数据库 显示数据库 创建数据库 删除数据库 使用数据库 查询当前数据库信息 显示数据库中的表 导入数据库脚本 表 查看表的结构 查看创建某个表的SQL语句 数据库的查询命令 查询…

Linux截图快捷键以及修改快捷键方式

1. 截图快捷键 初始快捷键如下 全屏截图并保存&#xff1a;AltPrint 选区截图并保存&#xff1a;ShiftPrint 全屏截图并复制到剪贴板&#xff1a;AltCtrlPrint 选区截图并复制到剪贴板&#xff1a;ShiftCtrlPrint 会保存到Pictures文件夹下面 2. 修改快捷键 打开Settings界面…

k8s学习(RKE+k8s+rancher2.x)成长系列之简配版环境搭建(二)

三、简配版集群&#xff0c;适用于demo环境 1.集群架构设计 主机名角色配置(核数&#xff0c;内存&#xff0c;磁盘)MasterRKE,controlplane,etcd,worker,rancher-master2C 8G 40GSlaver1controlplane,worker,rancher-master2C 8G 40GSlaver2controlplane,worker,rancher-mas…

电机控制系列模块解析(第五篇)—— FOC需要调节哪些参数

最近有上传一些入门的免积分的资料&#xff0c;方便大家上手进行仿真分析。注意查收。 继续回到咱们的电机控制系列模块解析&#xff08;第五篇&#xff09;—— FOC需要调节哪些参数&#xff0c;这些参数都是可以理论计算的&#xff0c;后续章节将介绍其如何计算。 一、快速…