java 如何在自定义序列化程序中访问默认 jackson 序列化
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/31056215/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to access default Hymanson serialization in a custom serializer
提问by DavidA
I want to create a custom serializer which does a tiny bit of work and then leaves the rest for default serialization.
我想创建一个自定义序列化程序,它只做一点工作,然后将其余部分留给默认序列化。
For example:
例如:
@JsonSerialize(using = MyClassSerializer.class)
public class MyClass {
...
}
public class MyClassSerializer extends JsonSerializer<MyClass> {
@Override
public void serialize(MyClass myClass, JsonGenerator generator,
SerializerProvider provider)
throws JsonGenerationException, IOException {
if (myClass.getSomeProperty() == someCalculationResult) {
provider.setAttribute("special", true);
}
generator.writeObject(myClass);
}
}
With the idea of creating other custom serializers for aggregated objects which behave differently based on the 'special' attribute value. However, the above code does not work, as it unsurprisingly goes into an infinite recursion.
本着为聚合对象创建其他自定义序列化程序的想法,这些对象的行为基于“特殊”属性值而有所不同。但是,上面的代码不起作用,因为它毫不奇怪地进入了无限递归。
Is there a way to tell Hymanson to use default serialization once I have set the attribute? I don't really want enumerate all the properties like many custom serializers as the class is fairly complex and I don't want to have to do dual maintenance with the serializer every time I change the class.
一旦我设置了属性,有没有办法告诉 Hymanson 使用默认序列化?我真的不想像许多自定义序列化程序一样枚举所有属性,因为该类相当复杂,而且我不想每次更改类时都必须对序列化程序进行双重维护。
回答by Sam Berry
A BeanSerializerModifier
will provide you access to the default serialization.
ABeanSerializerModifier
将为您提供对默认序列化的访问。
Inject a default serializer into the custom serializer
将默认序列化程序注入自定义序列化程序
public class MyClassSerializer extends JsonSerializer<MyClass> {
private final JsonSerializer<Object> defaultSerializer;
public MyClassSerializer(JsonSerializer<Object> defaultSerializer) {
this.defaultSerializer = checkNotNull(defaultSerializer);
}
@Override
public void serialize(MyClass myclass, JsonGenerator gen, SerializerProvider provider) throws IOException {
if (myclass.getSomeProperty() == true) {
provider.setAttribute("special", true);
}
defaultSerializer.serialize(myclass, gen, provider);
}
}
Create a BeanSerializerModifier
for MyClass
创建BeanSerializerModifier
于MyClass
public class MyClassSerializerModifier extends BeanSerializerModifier {
@Override
public JsonSerializer<?> modifySerializer(SerializationConfig config, BeanDescription beanDesc, JsonSerializer<?> serializer) {
if (beanDesc.getBeanClass() == MySpecificClass.class) {
return new MyClassSerializer((JsonSerializer<Object>) serializer);
}
return serializer;
}
}
Register the serializer modifier
注册序列化器修饰符
ObjectMapper om = new ObjectMapper()
.registerModule(new SimpleModule()
.setSerializerModifier(new MyClassSerializerModifier()));
回答by LawrenceMouarkach
@JsonSerialize(using = MyClassSerializer.class)
public class MyClass {
...
}
public class MyClassSerializer extends JsonSerializer<MyClass> {
@Override
public void serialize(MyClass myClass, JsonGenerator generator,
SerializerProvider provider)
throws JsonGenerationException, IOException {
if (myClass.getSomeProperty() == someCalculationResult) {
provider.setAttribute("special", true);
}
provider.defaultSerializeValue(myClass, generator);
}
}
if you are just writing an object as normal use the above
如果您只是像往常一样编写对象,请使用上述内容
回答by Alex Block
You can use @JsonGetter instead of using a custom serializer if that's the only change you want to make.
如果这是您想要进行的唯一更改,您可以使用 @JsonGetter 而不是使用自定义序列化程序。
public class MyClass{
@JsonGetter("special")
protected boolean getSpecialForHymanson() {
return myClass.getSomeProperty() == someCalculationResult;
}
}
回答by Pawel Zieminski
To add to the chosen answer, the serializer implementation may also have to implement ContextualSerializer
and ResolvableSerializer
interfaces. Please take a look at a related issue here
https://github.com/FasterXML/Hymanson-dataformat-xml/issues/259
要添加到所选答案中,序列化器实现可能还必须实现ContextualSerializer
和ResolvableSerializer
接口。请在此处查看相关问题
https://github.com/FasterXML/Hymanson-dataformat-xml/issues/259
public class MyClassSerializer extends JsonSerializer<MyClass>
implements ContextualSerializer, ResolvableSerializer {
private final JsonSerializer<Object> defaultSerializer;
public MyClassSerializer(JsonSerializer<Object> defaultSerializer) {
this.defaultSerializer = checkNotNull(defaultSerializer);
}
@Override
public void serialize(MyClass myclass, JsonGenerator gen, SerializerProvider provider)
throws IOException {
if (myclass.getSomeProperty() == true) {
provider.setAttribute("special", true);
}
defaultSerializer.serialize(myclass, gen, provider);
}
@Override
public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property)
throws JsonMappingException {
if (defaultSerializer instanceof ContextualSerializer) {
JsonSerializer<?> contextual = ((ContextualSerializer)defaultSerializer).createContextual(prov, property);
return new MyClassSerializer((JsonSerializer<Object>)contextual);
}
return new MyClassSerializer(defaultSerializer);
}
@Override
public void resolve(SerializerProvider provider) throws JsonMappingException {
if (defaultSerializer instanceof ResolvableSerializer) {
((ResolvableSerializer)defaultSerializer).resolve(provider);
}
}
}
}