swagger springfox:IllegalStateException: Model already registered with different name using 解决方案

这篇博客介绍了如何通过修改Springfox Schema 3.0.0的源代码来解决类型注册冲突的问题。作者下载了Springfox的源代码,定位到TypeNameIndexingAdapter.java的第50-60行,然后修改了checkTypeRegistration方法,减少了不必要的检查。接着,使用Gradle打包生成了3.0.1-SNAPSHOT版本的jar,并将其添加到项目中,通过pom.xml配置为系统依赖,并确保Spring Boot Maven插件在打包时包含此系统依赖。

通过堆栈跟踪可以发现是Maven: io.springfox:springfox-schema:3.0.0中的问题

以更改源代码并替换jar包的形式修复该问题

首先下载源代码

 https://github.com/springfox/springfox.git

找到代码

springfox-schema/src/main/java/springfox/documentation/schema/TypeNameIndexingAdapter.java


行号: 50-60

问题代码:

  private boolean checkTypeRegistration(
      String typeName,
      String typeId) {
    if (knownNames.containsKey(typeId)) {
      if (!knownNames.get(typeId).equals(typeName)) {
        LOGGER.debug("Rewriting type {} with model id: {} is not allowed, because it is already registered",
                 typeName,
                 typeId);
        throw new IllegalStateException("Model already registered with different name.");
      } else {
        return true;
      }
    }

    return false;
  }

尝试改为:

private boolean checkTypeRegistration(String typeName, String typeId) {
    return this.knownNames.containsKey(typeId);
}

根目录gradle-install打包,类似maven-install

虽然会报错,但是springfox-schema-3.0.1-SNAPSHOT.jar还是生成了

放置到 resources/libs/springfox-schema-3.0.1-SNAPSHOT.jar

编辑pom.xml

添加或替换:

...
    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-schema</artifactId>
        <version>3.0.1-SNAPSHOT</version>
        <scope>system</scope>
        <systemPath>${basedir}/src/main/resources/libs/springfox-schema-3.0.1-SNAPSHOT.jar</systemPath>
    </dependency>
...
<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
                <!-- maven打包时会将外部引入的jar包(比如在根目录下或resource文件下新加外部jar包)打包到项目jar -->
                <includeSystemScope>true</includeSystemScope>
            </configuration>
        </plugin>
    </plugins>
</build>

可以了 

springfox-schema-3.0.1-SNAPSHOT.jar-Java文档类资源-优快云下载

### 解决 `Model already registered with different name` 的方法 在使用 SwaggerSpringfox 进行接口文档生成时,如果出现模型注册冲突问题(即提示 `Model already registered with different name`),通常是因为框架尝试将两个不同名称的类映射到相同的模型 ID 上。这会导致内部模型注册失败,并抛出 `IllegalStateException` 异常[^1]。 此类问题的根本原因在于 Springfox 在扫描模型类时,对泛型、继承或相同字段结构的不同类产生了相同的唯一标识符(model id)。例如,当多个返回值封装类(如 `BaseResponse<T>`)中包含不同的泛型类型时,Springfox 可能会误认为它们是同一个模型并尝试重复注册。 #### 修改类型注册逻辑 为了解决该问题,可以修改模型注册过程中的检查逻辑。原始的 `checkTypeRegistration` 方法会对类型名称和 ID 做一致性校验,若发现已有 ID 对应了不同的名称,则抛出异常: ```java private boolean checkTypeRegistration(String typeName, String typeId) { if (knownNames.containsKey(typeId)) { if (!knownNames.get(typeId).equals(typeName)) { LOGGER.debug("Rewriting type {} with model id: {} is not allowed, because it is already registered", typeName, typeId); throw new IllegalStateException("Model already registered with different name."); } else { return true; } } return false; } ``` 一种可行的解决方案是放宽此限制,仅判断是否已经注册过该 ID,而不再比较类型名是否一致: ```java private boolean checkTypeRegistration(String typeName, String typeId) { return this.knownNames.containsKey(typeId); } ``` 这样可以避免因不同类具有相同 model id 而导致的注册失败问题[^1]。 #### 其他规避方式 - **使用 `@ApiModel` 注解显式指定 model id**: 为每个可能冲突的类添加 `@ApiModel` 注解,并设置唯一的 `value` 属性,以确保每个类有独立的 model id。 ```java @ApiModel(value = "ExternalEmailParamV1") public class ExternalEmailParam { // ... } ``` - **升级至 Springdoc(OpenAPI 实现)**: 如果项目允许技术栈变更,建议迁移到 [Springdoc](https://springdoc.org/),它是基于 OpenAPI 3.0 的新一代文档生成工具,不会遇到此类模型注册冲突问题,并且支持更广泛的 Spring Boot 功能。 - **排除部分模型的自动注册**: 在配置文件中通过 `springfox.documentation.ignore` 设置忽略某些不必要或容易引起冲突的模型类。 ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

上海好程序员

给上海好程序员加个鸡腿!!!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值