java - 无法让 JsonIdentityInfo 正常工作
问题描述
我有两个对象之间的关系。我有一个 Spring CLI 与使用 Jackson 的 RESTful Web 服务进行通信。我正在使用 @JsonIdentityInfo 注释,但它无法在两个类之间创建关系。另外我正在使用 WebClient
第一个对象包含以下代码:
import com.fasterxml.jackson.annotation.*;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
@JsonSerialize(as= FuncUnit.class)
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "fu_id", scope=FuncUnit.class)
@Setter @Getter
public class FuncUnit {
@JsonProperty(value = "description")
private String description;
@Id @JsonProperty(value = "fu_id", required = true)
private Long fu_id;
// standard constructors
public FuncUnit (long fuId)
{
fu_id = fuId;
}
public FuncUnit() {}
}
第二个对象是:
@JsonSerialize(as=Engine.class)
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id", scope = Engine.class)
@Setter @Getter
public class Engine {
@JsonProperty(value = "id", required = true)
private Long id;
@JsonProperty(value = "func_unit")
private FuncUnit func_unit;
public Engine() {}
}
现在我收到的json如下:
[
{
"id": 111,
"functional_unit": {
"description": "",
"fu_id": 11,
},
},
{
"id": 112,
"functional_unit": 11,
}
]
而我写的webClient代码如下。(我也尝试过不使用 ExchangeStrategies,得到了相同的结果):
ExchangeStrategies exchangeStrategies = ExchangeStrategies.builder()
.codecs(configurer ->
configurer.defaultCodecs().jackson2JsonDecoder(new Jackson2JsonDecoder(new ObjectMapper(), MediaType.APPLICATION_JSON)))
.build();
String url = cliUtils.getBaseUrl();
WebClient webClient = WebClient.builder().exchangeStrategies(exchangeStrategies).build();
UriComponentsBuilder builder = UriComponentsBuilder.newInstance().fromHttpUrl(url);
List<Engine> units = webClient.get()
.uri(builder.build().toUri())
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.retrieve()
.bodyToFlux(Engine.class)
.collectList()
.block();
调用 webClient 代码时,我没有收到任何错误,但只有一个引擎具有 FuncUnit。另一个引擎包含一个 null 作为 FuncUnit。
解决方案
简短回答:改用 .bodyToMono(new ParameterizedTypeReference<List>(){}) 。
长答案:我确实遇到了一些问题。经过大量研究,没有一个解决方案对我有用。比如exchangeStrategy上的Customized ObjectMapper。
我们知道 JsonIdentityInfo 将第一个实例序列化为完整对象,将其他相同对象序列化为引用,以防止循环引用问题。
[
{
"id": 111,
"functional_unit": { // <----- First, Fully serialized
"description": "",
"fu_id": 11,
},
},
{
"id": 112,
"functional_unit": 11, // <----- Second, reference Id
}
]
但是,这个问题不是因为序列化/反序列化,而是因为 Flux 的行为。尽管我们使用flux.collectList() 来获取所有列表项,但它们实际上是一一返回(非阻塞)并收集所有。第二个和后面的相同项目将无法看到第一个引用并注入引用。所以我尝试使用 Mono<List<>> 强制它们一起返回并且它起作用了。
推荐阅读
- elasticsearch - 将 jaeger 与 kubernetes 集群上的 elasticsearch 后端存储连接起来
- angular - 与他人共享 Angular 应用程序的简单方法?
- sql - PostgreSQL 中 VALUES 子句的行为
- python - 在 sc = SparkContext("local", "SparkFile App") 中使用 python 在 windows10 中的 pyspark 出错
- svg - 打印到 PDF 时光栅化的 SVG 图案
- mysql - 无法使用 Intellij 创建池的初始连接,导致 SpringBoot 中没有创建数据库?
- ponylang - 是否可以修改函数参数?(如 C++ 中的 & )
- java - 为什么spring源代码中的“NestedExceptionUtils”被声明为抽象类?
- ios - 剪辑按钮以查看
- python - 从日期时间列中提取月份中的日期作为数组