gpt4 book ai didi

java - 自定义序列化程序,可回退到默认序列化

转载 作者:行者123 更新时间:2023-12-01 20:13:05 26 4
gpt4 key购买 nike

我有一个情况,一个对象可能需要以不同的方式序列化。具体来说,REST 端点采用 header ,如果 header 为 true,则我们以一种方式序列化,如果为 false,则以另一种方式序列化。我认为如果我们将 header 属性放入对象中,自定义序列化程序可能非常适合此目的,但使用它时遇到了一些麻烦。

(请注意,由于使用了一些泛型以及代码的结构方式,仅创建不同的对象就需要大量重构,因此我正在尝试找到更快的解决方案。)

例如,我的序列化器如下所示:

public class FooSerializer extends StdSerializer<Foo>
{
@Override
public void serialize(
final Foo foo,
final JsonGenerator jsonGenerator,
final SerializerProvider serializerProvider)
throws IOException
{
if (foo.isFlattened())
{
jsonGenerator.writeObject(flatten(foo));
}
else
{
jsonGenerator.writeObject(foo);
}
}

private Map<String,Object> flatten(Foo foo)
{
// ... some logic that builds the Map...
}
}

被序列化的类将被相应地注释:

@JsonSerialize(using = FooSerializer.class)
public class Foo
{
// ... things...
}

问题几乎立即变得明显:jsonGenerator.writeObject调用ObjectMapper来序列化对象...然后它将再次调用我的序列化器,给我们一个可爱的无限最终出现循环和堆栈溢出。

我能想到解决此问题的唯一选择是使用反射,循环对象的属性,并使用 jsonGenerator 将它们写入新对象。这感觉有点矫枉过正,尤其是当 jackson 应该能够为我做到这一点时。问题是我找不到一种方法来告诉 ObjectMapper 忽略类上的序列化程序。

有更好的方法吗?我想我可以创建一个自定义 ObjectMapper ,它以某种方式忽略类上注释的序列化器,并将其用作 jsonGenerator 的编解码器......但不完全确定在ObjectMapper上拉动什么杠杆。

最佳答案

正如所怀疑的,有一种方法可以禁用特定的注释。在本例中,我想禁用 Foo 类上的 JsonSerialize 注释。所以,我这样做是为了打破无限循环:

public class FooSerializer extends StdSerializer<Foo>
{
@Override
public void serialize(
final Foo foo,
final JsonGenerator jsonGenerator,
final SerializerProvider serializerProvider)
throws IOException
{
ObjectMapper mapper = new ObjectMapper();
JacksonAnnotationIntrospector annotationIntrospector =
new JacksonAnnotationIntrospector()
{
@Override
protected <A extends Annotation> A _findAnnotation(
final Annotated annotated,
final Class<A> annotationClass)
{
if (annotated.hasAnnotation(JsonSerialize.class) &&
annotated.getRawType() == Foo.class)
{
return null;
}

return super._findAnnotation(annotated, annotationClass);
}
};
mapper.setAnnotationIntrospector(annotationIntrospector);
jsonGenerator.setCodec(mapper);

if (foo.isFlattened())
{
jsonGenerator.writeObject(flatten(foo));
}
else
{
jsonGenerator.writeObject(foo);
}
}

private Map<String,Object> flatten(Foo foo)
{
// ... some logic that builds the Map...
}
}

关于java - 自定义序列化程序,可回退到默认序列化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58963529/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com