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

Java21、Spring Boot3.3.3、QuickBooks升级后连接及反序列化异常求助

技术栈升级后QuickBooks集成问题排查

近期完成技术栈升级:Java 11 → Java 21,Spring Boot 2.4.3 → 3.3.3,QuickBooks SDK 6.0.7 → 6.4.1。升级后出现两个问题:

  • 跳转QuickBooks Online后无法回调至我方应用
  • 执行查询代码时触发反序列化错误

报错代码片段

public String getCompanyName(String accessToken, String realmId) throws Exception {
    DataService dataService = serviceFactory.getDataService(accessToken, realmId);
    String query = "select * from companyinfo";
    QueryResult executeQuery = dataService.executeQuery(query); // 报错行
    String comapnyDisplayName = "QB Company";
    List<CompanyInfo> entities = null;
    if (executeQuery != null) {
        entities = (List<CompanyInfo>) executeQuery.getEntities();
        if (entities != null && !entities.isEmpty()) {
            comapnyDisplayName = entities.get(0).getCompanyName();
        }
    }
    return comapnyDisplayName;
}

报错日志

Caused by: com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type `com.intuit.ipp.data.MonthEnum` from String "January": not one of the values accepted for Enum class: [OCTOBER, SEPTEMBER, JUNE, MARCH, MAY, APRIL, JULY, JANUARY, FEBRUARY, DECEMBER, AUGUST, NOVEMBER]
 at [Source: UNKNOWN; byte offset: #UNKNOWN] (through reference chain: com.intuit.ipp.data.CompanyInfo["FiscalYearStartMonth"])
    at com.fasterxml.jackson.databind.exc.InvalidFormatException.from(InvalidFormatException.java:67)
    at com.fasterxml.jackson.databind.DeserializationContext.weirdStringException(DeserializationContext.java:1958)
    at com.fasterxml.jackson.databind.DeserializationContext.handleWeirdStringValue(DeserializationContext.java:1245)
    at com.fasterxml.jackson.databind.deser.std.EnumDeserializer._deserializeAltString(EnumDeserializer.java:447)
    at com.fasterxml.jackson.databind.deser.std.EnumDeserializer._fromString(EnumDeserializer.java:304)
    at com.fasterxml.jackson.databind.deser.std.EnumDeserializer.deserialize(EnumDeserializer.java:273)
    at com.fasterxml.jackson.databind.deser.impl.FieldProperty.deserializeAndSet(FieldProperty.java:138)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:310)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:177)
    at com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.readRootValue(DefaultDeserializationContext.java:342)
    at com.fasterxml.jackson.databind.ObjectMapper._readValue(ObjectMapper.java:4881)
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3035)
    at com.fasterxml.jackson.databind.ObjectMapper.treeToValue(ObjectMapper.java:3499)
    at com.intuit.ipp.serialization.QueryResponseDeserializer.deserialize(QueryResponseDeserializer.java:134)
    at com.intuit.ipp.serialization.QueryResponseDeserializer.deserialize(QueryResponseDeserializer.java:48)
    at com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.readRootValue(DefaultDeserializationContext.java:342)
    at com.fasterxml.jackson.databind.ObjectMapper._readValue(ObjectMapper.java:4881)
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3035)
    at com.fasterxml.jackson.databind.ObjectMapper.treeToValue(ObjectMapper.java:3499)
    at com.intuit.ipp.serialization.IntuitResponseDeserializer.getQueryResponse(IntuitResponseDeserializer.java:327)
    at com.intuit.ipp.serialization.IntuitResponseDeserializer.deserialize(IntuitResponseDeserializer.java:198)
    at com.intuit.ipp.serialization.IntuitResponseDeserializer.deserialize(IntuitResponseDeserializer.java:54)
    at com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.readRootValue(DefaultDeserializationContext.java:342)
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4905)
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3848)
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3816)
    at com.intuit.ipp.serialization.JSONSerializer.deserialize(JSONSerializer.java:302)
    ... 95 more

问题原因分析

反序列化错误原因

核心冲突是QuickBooks SDK与Spring Boot 3.x自带的Jackson版本不兼容:

  • Spring Boot 3.3.3默认使用Jackson 2.15+,而QuickBooks SDK 6.4.1依赖的Jackson版本较低,或SDK内部MonthEnum的注解配置在高版本Jackson下失效。
  • 日志中枚举值明明包含JANUARY却无法匹配字符串"January",是因为高版本Jackson对枚举反序列化的大小写匹配规则更严格,而SDK的枚举未配置@JsonValue或@JsonProperty来映射字符串值与枚举常量。
  • Java 21升级本身不直接触发该问题,但Spring Boot 3.x基于Java 17+构建,强制升级的Jackson版本才是关键触发点。

回调失败原因

大概率和Spring Boot 3.x的OAuth2配置变更有关:

  • Spring Boot 2.x到3.x的OAuth2客户端/资源服务器配置有较大调整,包路径、配置属性等均有变更,旧的回调路径、权限规则不再生效。
  • 也可能是QuickBooks SDK 6.4.1的OAuth流程有更新,与Spring Boot的OAuth集成逻辑不匹配,导致回调请求被拦截或无法正确路由。

解决方向

  1. 反序列化错误修复
    • 查阅QuickBooks SDK 6.4.1官方文档,确认是否有Jackson 2.15+兼容补丁,或在项目构建文件中强制对齐SDK依赖的Jackson版本。
    • 自定义Jackson模块,为MonthEnum添加大小写不敏感的反序列化规则,或手动映射字符串"January"到MonthEnum.JANUARY。
  2. 回调失败修复
    • 对照Spring Boot 3.x OAuth2客户端文档,重新配置回调路径、授权端点等参数,确保符合新版本规范。
    • 检查Spring Security过滤器链,将回调路径加入白名单,避免被拦截。
    • 查看QuickBooks SDK 6.4.1的OAuth流程变更,调整授权请求参数或回调逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 04:28:11