Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ignore custom serializer in root #1397

Open
reinaldo-besen opened this issue Oct 5, 2016 · 2 comments
Open

Ignore custom serializer in root #1397

reinaldo-besen opened this issue Oct 5, 2016 · 2 comments

Comments

@reinaldo-besen
Copy link

Hello,

I would suggest improvement, the option to disregard the application of specific serializer on the type of the object when it is the root.

Example:

class MyClass
{
    String field;
    MyClass reference;
}
SimpleModule module = new SimpleModule();
module.addSerializer(MyClass.class, new CustomSeserializer());
MyClass o = new MyClass();
mapper.writeValueAsString(o);

In this scenario I wish the object to be serialized without using the custom serializer, it is the root object, but that the field use the serializer.

I know the fact that via annotation in the field is a way to solve, but this setting is applied via runtime programming and must apply to all properties of type.

Now I resolved this situation by creating a custom serializer generic testing if the root is to call or not the specific serializers.

The suggestion is to create a global setting in SerializationFeature class to set this setting.

Thanks for your help.

@cowtowncoder
Copy link
Member

Ok, I think I understand the request.

I don't know if there is an easy way to achieve this, since serializer/deserializer resolution system has no knowledge of context, to make this determination. But perhaps there is a way; if I can think of something I will add notes here.

From custom serializer it would actually be possible to determine, since createContextual() will be called with null as BeanProperty argument.

@Krivda
Copy link

Krivda commented Nov 17, 2019

just if somebody happen to be here, i've implemented this idea in this way

public abstract class RootAwareBeanSerializer<T> extends BeanSerializerBase {
...
    public void serialize(Object bean, JsonGenerator jgen,
                          SerializerProvider provider) throws IOException {

        if (bean == null || !this.javaType.isTypeOrSubTypeOf(bean.getClass()))
        {
            @SuppressWarnings("unchecked")
            T object = (T) bean;

            jgen.writeStartObject();
            if (this.isRoot) {
                serializeRoot(object, jgen, provider);
            } else {
                serializeNonRoot(object, jgen, provider);
            }
            jgen.writeEndObject();
        }
    }


    protected abstract void serializeNonRoot(T bean, JsonGenerator jgen, SerializerProvider provider) throws IOException;

    public void serializeRoot(T bean, JsonGenerator jgen, SerializerProvider provider) throws IOException {

        serializeFields(bean, jgen, provider);
    }

    @Override
    public JsonSerializer<?> createContextual(SerializerProvider provider, BeanProperty property) throws JsonMappingException {

        // property == null is a criterion for serialization's root object
        if (property == null) {

            JsonSerializer ser = super.createContextual(provider, property);
            if (ser instanceof RootAwareBeanSerializer) {
                ((RootAwareBeanSerializer) ser).markAsRoot();
            }
            return  ser;
        } else {
            return super.createContextual(provider, property);
        }
    }

    private void markAsRoot() {
        isRoot = true;
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants