我有一个端点,在调用时会出现此错误:
2024-10-23 12:21:14,135 SEVERE [org.ecl.yas.int.SerializationContextImpl] (executor-thread-3) Generating incomplete JSON
2024-10-23 12:21:14,136 ERROR [io.qua.ver.htt.run.QuarkusErrorHandler] (executor-thread-3) HTTP Request to /api/contacts/scores/compound/gambit-digital.com failed, error id: 971b0a13-4991-45ff-b720-dfb50644855f-20: jakarta.json.bind.JsonbException: Unable to serialize property 'finalScores' from at.hksolutions.gambit.boundary.jaxrs.FinalScoreResponse
端点看起来像这样:
@GET
@Path("mypath")
@Produces(MediaType.APPLICATION_JSON)
public FinalScoreResponse getFinalScores() {
.....
// Some logic
// Serialization fails:
return new FinalScoreResponse(finalScores, cache.lastUpdated);
}
A
FinalScoreResponse
看起来像这样:
public record FinalScoreResponse(
List<FinalScore> finalScores,
Date lastUpdated
) {
}
我尝试过的:
FinalScoreResponse
只包含 lastUpdated
- 有效List<FinalScore>
- 有效因此,该问题显然与
List<FinalScore>
无法在 FinalScoreResponse 中序列化有关。但这很奇怪,因为它本身可以被序列化。
A
FinalScore
看起来像这样:
public record FinalScore(
String id,
String name,
double score,
int normalizedScore,
String lifecycleStage
) {
}
有什么解决方案可以让它在
FinalScoreResponse
内序列化吗?
注意:我可以确认逻辑和端点被正确调用,这只是序列化问题。
问题是我的
List<FinalScore> finalScores
在用于响应之前被错误地用 objectMapper.readValue(json)
反序列化。我最终没有得到 FinalScore
对象的列表,而是得到了未知类型的原始 List
对象。有趣的是,这在反序列化期间并没有抛出错误:
List<FinalScore> finalScores = cacheService.fromJson(json);
发生这种情况是由于 Java 的类型擦除,它在运行时删除通用类型信息,导致 JSON 被反序列化为原始
List<Object>
。如果不指定目标类型,反序列化框架无法推断列表应包含 FinalScore
对象。
要解决此问题,我需要使用
TypeReference
显式提供正确的类型信息。这是更新的 fromJson
方法:
objectMapper.readValue(json, new TypeReference<List<FinalScore>>() {});
这可确保 JSON 正确反序列化为
List<FinalScore>
,避免类型擦除问题并防止任何意外的运行时行为。