Springboot 升级带来的Swagger异常

news2025/1/4 19:20:48

当升级到Springboot 2.6.0 以上的版本后,Swagger 就不能正常工作了, 启动时报如下错误。当然如果你再使用sping boot ActuatorSpringfox, 也会引起相关的NPE error. (github issue: https://github.com/springfox/springfox/issues/3462)

NFO | jvm 1 | 2022/04/27 21:47:05 | WrapperJarApp: Caused by: org.springframework.context.ApplicationContextException: Failed to start bean 'documentationPluginsBootstrapper'; nested exception is java.lang.NullPointerException
INFO | jvm 1 | 2022/04/27 21:47:05 | WrapperJarApp: at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:181)
INFO | jvm 1 | 2022/04/27 21:47:05 | WrapperJarApp: at org.springframework.context.support.DefaultLifecycleProcessor.access$200(DefaultLifecycleProcessor.java:54)
INFO | jvm 1 | 2022/04/27 21:47:05 | WrapperJarApp: at org.springframework.context.support.DefaultLifecycleProcessor$LifecycleGroup.start(DefaultLifecycleProcessor.java:356)
INFO | jvm 1 | 2022/04/27 21:47:05 | WrapperJarApp: at java.lang.Iterable.forEach(Iterable.java:75)
INFO | jvm 1 | 2022/04/27 21:47:05 | WrapperJarApp: at org.springframework.context.support.DefaultLifecycleProcessor.startBeans(DefaultLifecycleProcessor.java:155)
INFO | jvm 1 | 2022/04/27 21:47:05 | WrapperJarApp: at org.springframework.context.support.DefaultLifecycleProcessor.onRefresh(DefaultLifecycleProcessor.java:123)
INFO | jvm 1 | 2022/04/27 21:47:05 | WrapperJarApp: at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:935)
INFO | jvm 1 | 2022/04/27 21:47:05 | WrapperJarApp: at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:586)
INFO | jvm 1 | 2022/04/27 21:47:05 | WrapperJarApp: at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:145)
INFO | jvm 1 | 2022/04/27 21:47:05 | WrapperJarApp: at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:740)
INFO | jvm 1 | 2022/04/27 21:47:05 | WrapperJarApp: at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:415)
INFO | jvm 1 | 2022/04/27 21:47:05 | WrapperJarApp: at org.springframework.boot.SpringApplication.run(SpringApplication.java:303)
INFO | jvm 1 | 2022/04/27 21:47:05 | WrapperJarApp: at org.springframework.boot.SpringApplication.run(SpringApplication.java:1312)
INFO | jvm 1 | 2022/04/27 21:47:05 | WrapperJarApp: at org.springframework.boot.SpringApplication.run(SpringApplication.java:1301)
INFO | jvm 1 | 2022/04/27 21:47:05 | WrapperJarApp: at com.ebay.adscollection.app.AdstrackingcollectionApplication.main(AdstrackingcollectionApplication.java:12)
INFO | jvm 1 | 2022/04/27 21:47:05 | WrapperJarApp: ... 14 more
INFO | jvm 1 | 2022/04/27 21:47:05 | WrapperJarApp: Caused by: java.lang.NullPointerException

下面就一一说明怎么解决

路径匹配策略

报错原因:
springboot2.6.0中将SpringMVC 默认路径匹配策略从AntPathMatcher 更改为PathPatternParser,导致出错

解决:
在 application.properties 文件中指定spring.mvc.pathmatch.matching-strategy=ant_path_matcher

Actuator

在Springboot 2.6 里Actuator 指定了ant_path_matcher, 并且没有办法通过配置的方式来切换。 我们可以通过定义bean 的方式来实现强制mapping。

@Bean
public WebMvcEndpointHandlerMapping webEndpointServletHandlerMapping(WebEndpointsSupplier webEndpointsSupplier, ServletEndpointsSupplier servletEndpointsSupplier, ControllerEndpointsSupplier controllerEndpointsSupplier, EndpointMediaTypes endpointMediaTypes, CorsEndpointProperties corsProperties, WebEndpointProperties webEndpointProperties, Environment environment) {
    List<ExposableEndpoint<?>> allEndpoints = new ArrayList();
    Collection<ExposableWebEndpoint> webEndpoints = webEndpointsSupplier.getEndpoints();
    allEndpoints.addAll(webEndpoints);
    allEndpoints.addAll(servletEndpointsSupplier.getEndpoints());
    allEndpoints.addAll(controllerEndpointsSupplier.getEndpoints());
    String basePath = webEndpointProperties.getBasePath();
    EndpointMapping endpointMapping = new EndpointMapping(basePath);
    boolean shouldRegisterLinksMapping = this.shouldRegisterLinksMapping(webEndpointProperties, environment, basePath);
    return new WebMvcEndpointHandlerMapping(endpointMapping, webEndpoints, endpointMediaTypes, corsProperties.toCorsConfiguration(), new EndpointLinksResolver(allEndpoints, basePath), shouldRegisterLinksMapping, null);
}


private boolean shouldRegisterLinksMapping(WebEndpointProperties webEndpointProperties, Environment environment, String basePath) {
    return webEndpointProperties.getDiscovery().isEnabled() && (StringUtils.hasText(basePath) || ManagementPortType.get(environment).equals(ManagementPortType.DIFFERENT));
}

springfox

Springfox-swagger2:jar:3.0.0 在 spring boot 2.6.x不在支持,而是转向springdoc
因此就在springboot 2.6.x , spring doc 应该去掉,而是用 springdoc-openapi-ui 替换。

   <dependency>
      <groupId>org.springdoc</groupId>
      <artifactId>springdoc-openapi-ui</artifactId>
      <version>1.6.8</version>
   </dependency>

替换掉 swagger 2 annotations ,选用wagger 3 annotations wagger 3 annotations 报名是 io.swagger.v3.oas.annotations.

@Api → @Tag

@ApiIgnore → @Parameter(hidden = true) or @Operation(hidden = true) or @Hidden

@ApiImplicitParam → @Parameter

@ApiImplicitParams → @Parameters

@ApiModel → @Schema

@ApiModelProperty(hidden = true) → @Schema(accessMode = READ_ONLY)

@ApiModelProperty → @Schema

@ApiOperation(value = "foo", notes = "bar") → @Operation(summary = "foo", description = "bar")

@ApiParam → @Parameter

@ApiResponse(code = 404, message = "foo") → @ApiResponse(responseCode = "404", description = "foo")

如果你在application 里,不是用springfox 的dependency, 而是自己定义多个Docket

@Bean
  public Docket publicApi() {
      return new Docket(DocumentationType.SWAGGER_2)
              .select()
              .apis(RequestHandlerSelectors.basePackage("org.github.springshop.web.public"))
              .paths(PathSelectors.regex("/public.*"))
              .build()
              .groupName("springshop-public")
              .apiInfo(apiInfo());
  }

  @Bean
  public Docket adminApi() {
      return new Docket(DocumentationType.SWAGGER_2)
              .select()
              .apis(RequestHandlerSelectors.basePackage("org.github.springshop.web.admin"))
              .paths(PathSelectors.regex("/admin.*"))
              .apis(RequestHandlerSelectors.withMethodAnnotation(Admin.class))
              .build()
              .groupName("springshop-admin")
              .apiInfo(apiInfo());
  }

那么就要改成

@Bean
  public GroupedOpenApi publicApi() {
      return GroupedOpenApi.builder()
              .group("springshop-public")
              .pathsToMatch("/public/**")
              .build();
  }
  @Bean
  public GroupedOpenApi adminApi() {
      return GroupedOpenApi.builder()
              .group("springshop-admin")
              .pathsToMatch("/admin/**")
              .addMethodFilter(method -> method.isAnnotationPresent(Admin.class))
              .build();
  }

如果只有一个Docket, 则要改成如下,用OpenAPI 而不是GroupedOpenApi

@Bean
  public OpenAPI springShopOpenAPI() {
      return new OpenAPI()
              .info(new Info().title("SpringShop API")
              .description("Spring shop sample application")
              .version("v0.0.1")
              .license(new License().name("Apache 2.0").url("http://springdoc.org")))
              .externalDocs(new ExternalDocumentation()
              .description("SpringShop Wiki Documentation")
              .url("https://springshop.wiki.github.org/docs"));
  }

同时设置参数在spring.factories 文件

springdoc.packagesToScan=package1, package2
springdoc.pathsToMatch=/v1, /api/balance/**

其他

If the swagger-ui is served behind a proxy:

  • how-can-i-deploy-springdoc-openapi-ui-behind-a-reverse-proxy

To customise the Swagger UI:

  • how-can-i-configure-swagger-ui

To hide an operation or a controller from documentation:

  • how-can-i-hide-an-operation-or-a-controller-from-documentation

refer link:

  • springboot 2.6 release note: https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.6-Release-Notes#pathpattern-based-path-matching-strategy-for-spring-mvc
  • migrate to springDoc: https://springdoc.org/#migrating-from-springfox
  • spingfox github issue: https://github.com/springfox/springfox/issues/3791
  • stackoverflow post: https://stackoverflow.com/questions/70036953/springboot-2-6-0-spring-fox-3-failed-to-start-bean-documentationpluginsboot


喜欢的朋友记得点赞、收藏、关注哦!!!

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

发现API安全风险,F5随时随地保障应用和API安全

分析数据显示&#xff0c;目前超过90%的基于Web的网络攻击都以API端点为目标&#xff0c;试图利用更新且较少为人所知的漏洞&#xff0c;而这些漏洞通常是由安全团队未主动监控的API所暴露。现代企业需要一种动态防御策略&#xff0c;在风险升级成代价高昂、令人警惕且往往无法…

【数据结构】(Python)差分数组。差分数组与树状数组结合

差分数组&#xff1a; 基于原数组构造的辅助数组。用于区间修改、单点查询。区间修改的时间复杂度O(1)。单点查询的时间复杂度O(n)。差分数组的元素&#xff1a;第一个元素等于原数组第一个元素&#xff0c;从第二个元素开始是原数组对应下标的元素与前一个元素的差&#xff0…

12.30-1-5学习周报

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 文章链接摘要Abstract一、方法介绍1.HAT-CIR2.Horde3.DWGRNet 二、实验总结 文章链接 https://arxiv.org/pdf/2405.04101 摘要 本博客介绍了论文《Continual lea…

Android OpenGl(二) Shader

一、Shader 1、什么是Shader&#xff0c;为什么要使用Shder &#xff08;1&#xff09;shader运行在gpu上的小程序 &#xff08;2&#xff09;以前使用固定管线&#xff0c;但缺点是灵活度不够&#xff0c;无法满足复杂需求&#xff0c;为了解决固定管线的缺点&#xff0c;出…

【LeetCode】200、岛屿数量

【LeetCode】200、岛屿数量 文章目录 一、并查集1.1 并查集1.2 多语言解法 二、洪水填充 DFS2.1 洪水填充 DFS 一、并查集 1.1 并查集 // go var sets int var father [90000]intfunc numIslands(grid [][]byte) int {n, m : len(grid), len(grid[0])build(grid, n, m)for i …

[最佳方法] 如何将视频从 Android 发送到 iPhone

概括 将大视频从 Android 发送到 iPhone 或将批量视频从 iPhone 传输到 Android 并不是一件容易的事情。也许您已经尝试了很多关于如何将视频从 Android 发送到 iPhone 15/14 的方法&#xff0c;但都没有效果。但现在&#xff0c;通过本文中的这 6 种强大方法&#xff0c;您可…

MetaRename for Mac,适用于 Mac 的文件批量重命名工具

在处理大量文件时&#xff0c;为每个文件手动重命名既耗时又容易出错。对于摄影师、设计师、开发人员等需要频繁处理和整理文件的专业人士来说&#xff0c;找到一款能够简化这一过程的工具是至关重要的。MetaRename for Mac 就是这样一款旨在提高工作效率的应用程序&#xff0c…

QEMU网络配置简介

本文简单介绍下qemu虚拟机网络的几种配置方式。 通过QEMU的支持&#xff0c;常见的可以实现以下4种网络形式&#xff1a; 基于网桥&#xff08;bridge&#xff09;的虚拟网络。基于NAT&#xff08;Network Addresss Translation&#xff09;的虚拟网络。QEMU内置的用户模式网…

Elasticsearch向量检索需要的数据集以及768维向量生成

Elasticsearch8.17.0在mac上的安装 Kibana8.17.0在mac上的安装 Elasticsearch检索方案之一&#xff1a;使用fromsize实现分页 快速掌握Elasticsearch检索之二&#xff1a;滚动查询(scrool)获取全量数据(golang) Elasticsearch检索之三&#xff1a;官方推荐方案search_after…

MySQL:安装配置(完整教程)

这里写目录标题 一、MySQL 简介二、下载 MySQL三、安装 MySQL四、配置环境变量五、配置 MySQL5.1 初始化 MySQL5.2 启动 MySQL 服务 六、修改 MySQL 密码七、卸载 MySQL八、结语 一、MySQL 简介 MySQL 是一款广泛使用的开源关系型数据库管理系统&#xff08;RDBMS&#xff09;…

您的公司需要小型语言模型

当专用模型超越通用模型时 “越大越好”——这个原则在人工智能领域根深蒂固。每个月都有更大的模型诞生&#xff0c;参数越来越多。各家公司甚至为此建设价值100亿美元的AI数据中心。但这是唯一的方向吗&#xff1f; 在NeurIPS 2024大会上&#xff0c;OpenAI联合创始人伊利亚…

如何用CSS3创建圆角矩形并居中显示?

在网页设计中&#xff0c;圆角矩形因其美观和现代感而被广泛使用&#xff0c;居中显示元素也是一个常见的需求。今天&#xff0c;我们将学习如何使用CSS3的border-radius属性来创建圆角矩形&#xff0c;并将其居中显示在页面上。 如果你正在学习CSS&#xff0c;那么这个实例将非…

PhPMyadmin-cms漏洞复现

一.通过日志文件拿Shell 打开靶场连接数据库 来到sql中输入 show global variables like %general%; set global general_logon; //⽇志保存状态开启&#xff1b; set global general_log_file D:/phpstudy/phpstudy_pro/WWW/123.php //修改日志保存位置 show global varia…

本地LLM部署--llama.cpp

–图源GitHub项目主页 概述 llama.cpp是以一个开源项目&#xff08;GitHub主页&#xff1a;llamma.cpp&#xff09;&#xff0c;也是本地化部署LLM模型的方式之一&#xff0c;除了自身能够作为工具直接运行模型文件&#xff0c;也能够被其他软件或框架进行调用进行集成。 其…

基本算法——分类

目录 创建项目 导入依赖 加载数据 特征选择 学习算法 对新数据分类 评估与预测误差度量 混淆矩阵 通过模型的预测结果生成 ROC 曲线数据 选择分类算法 完整代码 结论 创建项目 首先创建spring boot项目&#xff0c;我这里用的JDK8&#xff0c;springboot2.7.6&…

【系统配置】3种方式修改用户登录显示名|统信|麒麟|方德

原文链接&#xff1a;【系统配置】3种方式修改用户登录显示名&#xff5c;统信&#xff5c;麒麟&#xff5c;方德 Hello&#xff0c;大家好啊&#xff01;今天给大家带来一篇关于 通过修改 /etc/passwd 文件、usermod 命令&#xff0c;以及图形化界面三种方式修改用户登录名 的…

TTL 传输中过期问题定位

问题&#xff1a; 工作环境中有一个acap的环境&#xff0c;ac的wan口ip是192.168.186.195/24&#xff0c;ac上lan上有vlan205&#xff0c;其ip子接口地址192.168.205.1/24&#xff0c;ac采用非nat模式&#xff0c;而是路由模式&#xff0c;在上级路由器上有192.168.205.0/24指向…

Cocos2dx Lua绑定生成中间文件时参数类型与源码类型不匹配

这两天维护的一个项目&#xff0c;使用arm64-v8a指令集编译时遇到了报错&#xff0c;提示类型不匹配&#xff0c;具体报错的代码【脚本根据C源文件生成的中间文件】如下&#xff1a; const google::protobuf::RepeatedField<unsigned long long>& ret cobj->equi…

连接Milvus

连接到Milvus 验证Milvus服务器正在侦听哪个本地端口。将容器名称替换为您自己的名称。 docker port milvus-standalone 19530/tcp docker port milvus-standalone 2379/tcp docker port milvus-standalone 192.168.1.242:9091/api/v1/health 使用浏览器访问连接地址htt…

走方格(蓝桥杯2020年试题H)

【问题描述】在平面上有一些二维点阵。这些点的编号就像二维数组的编号一样&#xff0c;从上到下依次为第1~n行&#xff0c;从左到右依次为第1~m列&#xff0c;每个点可以用行号和列号表示。 现在有个人站在第1行第1列&#xff0c;他要走到第n行第m列&#xff0c;只能向右或者向…