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

Support @JsonCreator for enum classes #118

Open
kukido opened this issue Jul 17, 2017 · 6 comments
Open

Support @JsonCreator for enum classes #118

kukido opened this issue Jul 17, 2017 · 6 comments

Comments

@kukido
Copy link

kukido commented Jul 17, 2017

Hi! We would like to add support for @JsonCreator annotations in our enumerations. What would be the best way to approach that?

@nmorel
Copy link
Owner

nmorel commented Jul 19, 2017

I didn't know that was possible!
What's the use case ?

@kukido
Copy link
Author

kukido commented Jul 19, 2017

I added a PR with a test case. SO discussion: https://stackoverflow.com/questions/12468764/jackson-enum-serializing-and-deserializer

A workaround would be to have a custom deserializer for enum type. It works as expected.

@WORMSS
Copy link

WORMSS commented Jan 30, 2018

Was this ever addressed?

As we were unaware of the limitations of JsonCreator on an enum and unfortunately have used code similar to the below

    @JsonCreator
    public static MyEnum parse(String value) {
        for(final MyEnum me : values()) {
            if(me.getSomeValue() == value) {
                return me;
            }
        }
        Log.error("Unknown MyEnum:", value);
        return UNKNOWN;
    }

The main part here is we return UNKNOWN, which is the default value of the enum, if the value coming from the server does not match an enum we have in the system.

We thought @JsonCreator would be our saviour. We thought it had been tested and passed, but I guess we forgot to try "value that the enum doesn't have" and now running into problems.

I have read about putting a custom deserialiser to get around this, but not seen anything about putting a custom deserialiser on an enum anywhere.

@kukido
Copy link
Author

kukido commented Feb 2, 2018

We decided to use a workaround, considering a number of enumerations affected.

Here's what you need for the workaround:

Enumeration JSON deserializer

public class GwtCapabilityDeserializer extends JsonDeserializer<Capability> {

    private static final GwtCapabilityDeserializer INSTANCE = new GwtCapabilityDeserializer();

    /**
     * @return an instance of {@link GwtCapabilityDeserializer}
     */
    public static GwtCapabilityDeserializer getInstance() {
        return INSTANCE;
    }

    private GwtCapabilityDeserializer() {
    }

    @Override
    protected Capability doDeserialize(JsonReader reader, JsonDeserializationContext ctx, JsonDeserializerParameters params) {
        return Capability.fromString(reader.nextString());
    }
}

Key Enumeration JSON Deserializer (optional)

public class GwtProviderTypeKeyDeserializer extends KeyDeserializer<ProviderType> {

    private static final GwtProviderTypeKeyDeserializer INSTANCE = new GwtProviderTypeKeyDeserializer();

    /**
     * @return an instance of {@link GwtProviderTypeKeyDeserializer}
     */
    public static GwtProviderTypeKeyDeserializer getInstance() {
        return INSTANCE;
    }

    private GwtProviderTypeKeyDeserializer() {
    }

    @Override
    protected ProviderType doDeserialize(String key, JsonDeserializationContext ctx) {
        return ProviderType.get(key);
    }
}

CustomDeserializersConfiguration

import com.github.nmorel.gwtjackson.client.AbstractConfiguration;

public class CustomDeserializersConfiguration extends AbstractConfiguration {
    @Override
    protected void configure() {
        // types
        type(Capability.class).deserializer(GwtCapabilityDeserializer.class);

        // keys
        key(ProviderType.class).deserializer(GwtProviderTypeKeyDeserializer.class);
    }
}

Update gwt module

<module>
    <!-- gwt-jackson dependency -->
    <inherits name="com.github.nmorel.gwtjackson.GwtJackson"/>
    <inherits name="com.github.nmorel.gwtjackson.guava.GwtJacksonGuava" />

    <!-- custom deserializers for gwt-jackson -->
    <extend-configuration-property name="gwtjackson.configuration.extension" value="com.example.gwt.serde.CustomDeserializersConfiguration" />
</module>

@WORMSS
Copy link

WORMSS commented Feb 2, 2018

Ok, when I am back at work on Monday, I will need to give it a try.. But I will admit, I have No idea what any of the code above does or how to use it.

@isorashi
Copy link

isorashi commented Nov 2, 2018

Is there any update on this? I pulled in 0.15.4 to my project but it seems like enums with a static @JsonCreator method are still using the standard enum deserializer. I know it's possible to write a custom one deserializer (and have done so), but would prefer to use the methods specified by our generated model.

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

4 participants