You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot整合Gson使用LocalDateTime遇权限异常求解决

解决方案

问题根源

  1. 模块访问限制:Java 9+模块化系统默认禁止未命名模块通过反射访问java.time包的私有字段,而openapi-generator生成的okhttp-gson客户端默认Gson配置依赖反射处理LocalDateTime,因此抛出InaccessibleObjectException。
  2. Gson配置未生效:生成的客户端代码默认自行创建Gson实例,未使用Spring容器中注册的自定义Gson,导致你配置的LocalDateTimeDeserializer从未被实际调用。

解决步骤

一、临时绕过模块限制(不推荐长期使用)

添加JVM启动参数,开放java.time包的反射访问权限:

--add-opens java.base/java.time=ALL-UNNAMED

此方法仅临时解决异常,不符合Java模块化设计原则,建议仅用于测试或临时场景。

二、让生成的客户端使用自定义Gson实例(根本解决)

1. 正确配置Spring管理的Gson

创建Gson配置类,确保注册LocalDateTime的序列化/反序列化器:

@Configuration
public class GsonConfig {

    @Bean
    public Gson gson() {
        DateTimeFormatter isoFormatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME;

        return new GsonBuilder()
                // 注册LocalDateTime反序列化器
                .registerTypeAdapter(LocalDateTime.class, (JsonDeserializer<LocalDateTime>) (json, type, context) -> 
                        LocalDateTime.parse(json.getAsString(), isoFormatter))
                // 注册LocalDateTime序列化器
                .registerTypeAdapter(LocalDateTime.class, (JsonSerializer<LocalDateTime>) (src, type, context) -> 
                        new JsonPrimitive(isoFormatter.format(src)))
                .create();
    }
}

2. 让生成的ApiClient支持注入自定义Gson

方式A:重新生成客户端时配置openapi-generator

在openapi-generator-maven-plugin的配置中添加以下参数,让生成的ApiClient支持传入自定义Gson:

<plugin>
    <groupId>org.openapitools</groupId>
    <artifactId>openapi-generator-maven-plugin</artifactId>
    <version><!-- 使用最新稳定版 --></version>
    <executions>
        <execution>
            <goals>
                <goal>generate</goal>
            </goals>
            <configuration>
                <inputSpec>${project.basedir}/src/main/resources/openapi.json</inputSpec>
                <generatorName>java</generatorName>
                <library>okhttp-gson</library>
                <dateLibrary>java8-localdatetime</dateLibrary>
                <configOptions>
                    <!-- 启用Gson自定义支持 -->
                    <gsonCustomizer>true</gsonCustomizer>
                    <!-- 生成适配Spring Boot的代码 -->
                    <useSpringBoot>true</useSpringBoot>
                </configOptions>
            </configuration>
        </execution>
    </executions>
</plugin>

重新生成代码后,ApiClient会提供接收Gson参数的构造函数,此时在Spring中注册ApiClient Bean并注入自定义Gson:

@Bean
public ApiClient apiClient(Gson gson) {
    ApiClient apiClient = new ApiClient(gson);
    // 配置基础URL、拦截器等其他参数
    apiClient.setBaseUrl("your-api-base-url");
    return apiClient;
}
方式B:手动修改已生成的ApiClient(无需重新生成)

如果已生成代码不想重新生成,可手动修改ApiClient类:

  • 添加setGson方法:
    public void setGson(Gson gson) {
        this.gson = gson;
    }
    

然后在Spring配置中注入自定义Gson到ApiClient:

@Bean
public ApiClient apiClient(Gson gson) {
    ApiClient apiClient = new ApiClient();
    apiClient.setGson(gson);
    apiClient.setBaseUrl("your-api-base-url");
    return apiClient;
}

3. 确保业务代码使用注入的ApiClient

所有生成的XXXApi类需使用自定义的ApiClient实例,而非默认的ApiClient.create():

@Service
public class BusinessService {
    private final UserApi userApi;

    // 通过构造函数注入自定义ApiClient
    public BusinessService(ApiClient apiClient) {
        this.userApi = new UserApi(apiClient);
    }

    // 调用API方法
    public User getUserById(Long id) throws ApiException {
        return userApi.getUserById(id);
    }
}

三、升级openapi-generator版本

检查当前使用的openapi-generator-maven-plugin版本,旧版本可能存在java8-localdatetime场景下的反射问题。升级到最新稳定版(如7.x系列),新版本可能已优化Gson配置,避免直接反射访问java.time的私有字段。


内容的提问来源于stack exchange,提问作者tweetysat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 05:30:52