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

Spring AI中GenAI响应转DTO时如何忽略空ChatResponse字段?

问题解决:Spring AI GenAI响应映射DTO时空对象反序列化失败

核心问题分析

从错误日志可以看出,org.springframework.ai.chat.model.ChatResponse类没有公开的默认构造函数,当GenAI返回的JSON中chatResponse为空对象{}时,Jackson无法实例化该类,导致反序列化失败。同时你希望该字段不存在或为空时不赋值(即设为null)。

解决方案

方案1:自定义ChatResponse替代框架内部类(推荐)

Spring AI的ChatResponse是框架内部类,可能未提供序列化所需的构造器或公开字段,建议自定义一个业务所需的DTO类:

  1. 创建自定义的MyChatResponse类,包含你需要的字段并添加默认构造器:
public class MyChatResponse {
    // 根据业务需求添加字段,例如复制ChatResponse中的messages、metadata等
    private List<ChatMessage> messages;
    private Map<String, Object> metadata;

    // 必须添加默认构造器,供Jackson反序列化使用
    public MyChatResponse() {}

    // 带参构造器、getter和setter方法
    // ...
}
  1. 修改ChatPromptDTO,将原ChatResponse替换为自定义类:
public class ChatPromptDTO {
    private String question;
    private String answer;
    // 替换为自定义类
    private MyChatResponse chatResponse;

    // getter和setter方法
    // ...
}
  1. 可选:添加@JsonInclude注解,确保空对象不被序列化/反序列化:
import com.fasterxml.jackson.annotation.JsonInclude;

public class ChatPromptDTO {
    private String question;
    private String answer;
    
    @JsonInclude(JsonInclude.Include.NON_EMPTY)
    private MyChatResponse chatResponse;

    // getter和setter方法
    // ...
}

方案2:手动处理JSON响应,替换空对象为null

如果不想自定义类,可以在获取响应后手动修改JSON字符串,将空的chatResponse对象替换为null,再进行反序列化:

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.core.JsonProcessingException;

@Override
public ChatPromptDTO getResponseAsEntity(String message) {
    // 获取原始JSON响应
    String jsonContent = chatClient.prompt(message).call().content();
    
    // 将空的chatResponse对象替换为null
    String processedJson = jsonContent.replace("\"chatResponse\": {}", "\"chatResponse\": null");
    
    // 手动反序列化为DTO
    ObjectMapper objectMapper = new ObjectMapper();
    try {
        return objectMapper.readValue(processedJson, ChatPromptDTO.class);
    } catch (JsonProcessingException e) {
        throw new RuntimeException("反序列化响应失败", e);
    }
}

方案3:自定义Jackson反序列化器

通过自定义反序列化逻辑,遇到空对象时直接返回null,避免尝试实例化ChatResponse:

  1. 创建自定义反序列化器:
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import org.springframework.ai.chat.model.ChatResponse;

import java.io.IOException;

public class ChatResponseDeserializer extends JsonDeserializer<ChatResponse> {
    @Override
    public ChatResponse deserialize(JsonParser parser, DeserializationContext context) throws IOException {
        JsonNode node = parser.getCodec().readTree(parser);
        // 若节点为空对象,返回null
        if (node.isEmpty()) {
            return null;
        }
        // 若有有效数据,可尝试反序列化(注意:若ChatResponse无公开构造器,此步骤可能失败)
        // 此处可根据实际需求调整,比如返回null或抛出异常
        return null;
    }
}
  1. 在DTO字段上添加注解指定反序列化器:
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;

public class ChatPromptDTO {
    private String question;
    private String answer;
    
    @JsonDeserialize(using = ChatResponseDeserializer.class)
    private ChatResponse chatResponse;

    // getter和setter方法
    // ...
}

内容的提问来源于stack exchange,提问作者Gokul Krishnan J

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 22:07:09