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

GET请求响应反序列化为自定义POJO后字段值为null的问题排查

问题描述

我尝试将GET请求的响应存储到自定义的Bean类中,但发现POJO内声明的变量值为null。以下是相关代码及响应:

GET请求代码

ValidatableResponse response = given().header("Authorization", token).header("Content-type", "application/json")
                .when().log().all().pathParam("CalendarId", testCaseBean.getCalendarId().toString()).urlEncodingEnabled(false)
                .queryParam("from", testCaseBean.getStartDate()).queryParam("to", testCaseBean.getEndDate())
                .queryParam("monthEnd", testCaseBean.getMonthEndBusinessDay())
                .get(EndPoint.GET_CALENDAR_DETAILS_BY_MULTIPLE_CALENDAR_CODE).then().log().all();

IndexCalendarDateResponseBean actualRIOutput = CommonUtils.getJSONMapper()
        .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
        .readValue(response.extract().asString(), IndexCalendarDateResponseBean.class);

IndexCalendarDateResponseBean类代码

package com.tar.indexes.bean;

import java.time.LocalDate;
import java.util.List;

import com.tar.indexes.marketdata.api.dto.IndexCalendarDateResponseWrapper;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class IndexCalendarDateResponseBean {
    
    List<IndexCalendarDateResponseWrapper> calendarId;

}

InCalendarDateResponseWrapper类代码

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;

import java.time.LocalDate;

@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
@ToString
public class InCalendarDateResponseWrapper {

    private String calendarId;

    private LocalDate calDat;

    private LocalDate prevBus;

    private LocalDate nextBus;

    private Boolean bus;

    private Boolean  monthEnd;

}

API响应示例

{
    "EU": [
        {
            "calendarId": "EU",
            "calDat": "2022-11-01",
            "prevBus": "2022-10-31",
            "nextBus": "2022-11-02",
            "bus": true,
            "monthEnd": false
        }
    ],
    "AU": [
        {
            "calendarId": "AU",
            "calDat": "2022-11-01",
            "prevBus": "2022-10-31",
            "nextBus": "2022-11-02",
            "bus": true,
            "monthEnd": false
        }
    ]
}

执行以下调试代码时:

String t = actualRIOutput.getCalendarId().get(0).getCalendarId();
System.out.println(t);

得到的t值为null而非预期的EU,请问问题出在哪里?


问题原因及解决方案

核心问题:POJO结构与API响应格式不匹配

你的API响应是以动态日历ID(如EU、AU)为键的JSON对象,每个键对应一个InCalendarDateResponseWrapper对象的数组;但你定义的IndexCalendarDateResponseBean用了List<IndexCalendarDateResponseWrapper> calendarId,这个结构和响应完全不匹配,Jackson无法将JSON对象映射到List类型的字段上,所以calendarId字段会被赋值为null,后续调用get(0)自然会出现问题(甚至可能抛出空指针异常)。

解决方案

修改POJO结构使其匹配响应格式,有两种可选方案:

方案1:修改IndexCalendarDateResponseBean为Map结构

将IndexCalendarDateResponseBean改为:

package com.tar.indexes.bean;

import java.util.List;
import java.util.Map;

import com.tar.indexes.marketdata.api.dto.InCalendarDateResponseWrapper;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class IndexCalendarDateResponseBean {
    
    // 键为日历ID(如EU、AU),值为对应日期列表
    private Map<String, List<InCalendarDateResponseWrapper>> calendarData;
}

反序列化后通过键获取对应数据:

// 获取EU对应的日期列表
List<InCalendarDateResponseWrapper> euCalendar = actualRIOutput.getCalendarData().get("EU");
if(euCalendar != null && !euCalendar.isEmpty()){
    String calendarId = euCalendar.get(0).getCalendarId();
    System.out.println(calendarId); // 输出EU
}

方案2:直接反序列化为Map类型

如果不需要额外的Bean类,可直接将响应字符串反序列化为Map:

import com.fasterxml.jackson.core.type.TypeReference;

// 省略其他代码
Map<String, List<InCalendarDateResponseWrapper>> calendarMap = CommonUtils.getJSONMapper()
        .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
        .readValue(response.extract().asString(), new TypeReference<Map<String, List<InCalendarDateResponseWrapper>>>() {});

// 获取EU对应的第一个元素的calendarId
String t = calendarMap.get("EU").get(0).getCalendarId();
System.out.println(t); // 输出EU

额外注意点

  1. 代码中引用的IndexCalendarDateResponseWrapper和实际类名InCalendarDateResponseWrapper不一致,需要统一类名,避免编译或运行错误。
  2. 确保Jackson支持LocalDate反序列化,需添加jackson-datatype-jsr310依赖,并在ObjectMapper中注册JavaTimeModule:
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;

// 省略其他代码
CommonUtils.getJSONMapper()
        .registerModule(new JavaTimeModule())
        .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 00:25:31