alibaba / alibaba/fastjson2

[BUG] 类型没有写全导致无法正确反序列化

Open
#4,038 0 comments 0 reactions 0 assignees View on GitHub
bug
Dominant language
Java
Stars
4.4k
Forks
613
Avg merge
1d 22h
Merged PRs (30d)
6

Description

### 问题描述
*简要描述您碰到的问题。*

### 环境信息
*请填写以下信息:*

- OS信息: [e.g.:CentOS 8.4.2105 4Core 3.10GHz 16 GB]
- JDK信息: [e.g.:Openjdk 21]
- 版本信息:[e.g.:Fastjson2 2.0.61]

### 重现步骤
*如何操作可以重现该问题:*

1. 使用 `toJSONBytes` 方法
2. 转为字符串会发现有些没有类型
3. 导致无法正确反序列化为对象
```java
JSON.toJSONBytes(details, new Filter[]{FloatPlainFilter.INSTANCE}, JSONWriter.Feature.WriteClassName)
```

问题发生在 `org.springframework.ai.chat.model.Generation` 类的 `getOutput` 方法,会将其序列化为以下内容

很明显 output 没有标注类型。包括 result 也没有类型

```json
"results": [
{
"metadata": {
"@type": "org.springframework.ai.chat.metadata.DefaultChatGenerationMetadata",
"contentFilters":Set[],
"empty": true,
"finishReason": "STOP"
},
"output": {
"media": [],
"messageType": "ASSISTANT",
"metadata": {
"role": "ASSISTANT",
"messageType": "ASSISTANT",
"finishReason": "STOP",
"refusal": "",
"annotations": [],
"index": 0,
"id": "chatcmpl-1",
"reasoningContent": ""
},
"text": "您好,关于“校园卡”我查询到了以下几种不同业务:1. 充值 2. 补办 3. 退费。请问您具体需要办理哪一项?",
"toolCalls": []
}
}
]
```

下面是我的类
```java
public static class MessageDetails {
/**
* 模型返回结果
*/
private List results;
}
```

### 期待的正确结果
应该写入类型,这样才能正确的反序列化。

### 相关日志输出
反序列化之后,内容丢失了

Image

Image

#### 附加信息
Generation 在 `spring-ai-model-1.1.2.jar` 包内,可以使用此包来复现。

以下是 Generation 类的内容

```java
/*
* Copyright 2023-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.springframework.ai.chat.model;

import java.util.Objects;

import org.springframework.ai.chat.messages.AssistantMessage;
import org.springframework.ai.chat.metadata.ChatGenerationMetadata;
import org.springframework.ai.model.ModelResult;

/**
* Represents a response returned by the AI.
*/
public class Generation implements ModelResult {

private final AssistantMessage assistantMessage;

private ChatGenerationMetadata chatGenerationMetadata;

public Generation(AssistantMessage assistantMessage) {
this(assistantMessage, ChatGenerationMetadata.NULL);
}

public Generation(AssistantMessage assistantMessage, ChatGenerationMetadata chatGenerationMetadata) {
this.assistantMessage = assistantMessage;
this.chatGenerationMetadata = chatGenerationMetadata;
}

@Override
public AssistantMessage getOutput() {
return this.assistantMessage;
}

@Override
public ChatGenerationMetadata getMetadata() {
ChatGenerationMetadata chatGenerationMetadata = this.chatGenerationMetadata;
return chatGenerationMetadata != null ? chatGenerationMetadata : ChatGenerationMetadata.NULL;
}

@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof Generation that)) {
return false;
}
return Objects.equals(this.assistantMessage, that.assistantMessage)
&& Objects.equals(this.chatGenerationMetadata, that.chatGenerationMetadata);
}

@Override
public int hashCode() {
return Objects.hash(this.assistantMessage, this.chatGenerationMetadata);
}

@Override
public String toString() {
return "Generation[" + "assistantMessage=" + this.assistantMessage + ", chatGenerationMetadata="
+ this.chatGenerationMetadata + ']';
}

}

```

Contributor guide

Open the contributing guide

Research direction

Start with the toJSONBytes call using FloatPlainFilter.INSTANCE and JSONWriter.Feature.WriteClassName, then inspect how the external spring-ai-model-1.1.2 Generation.getOutput method is serialized. Reproduce the MessageDetails round trip with the shown JSON and verify that output and result retain their type metadata and deserialize without losing content.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
backend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.