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 for @JsonCreator(mode = Mode.DELEGATING) #144

Open
nfekete opened this issue May 16, 2018 · 0 comments
Open

Support for @JsonCreator(mode = Mode.DELEGATING) #144

nfekete opened this issue May 16, 2018 · 0 comments

Comments

@nfekete
Copy link

nfekete commented May 16, 2018

There's a pattern for json serialization through Jackson that Immutables is using that works in Jackson but it's not currently supported by gwt-jackson.

The Immutables pattern looks like this. You define an abstract class/interface, annotate it with @Immutable, and Immutables will generate an immutable implementation of the abstract class/interface with Jackson serialization and deserialization support (in case Jackson is found on the classpath).

From an interface similar to this:

@JsonTypeInfo( use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY)
@JsonSerialize
public interface Person {
    String getName();
    ImmutablePerson withName(String name);
}

it generates a class similar to this (ommitting the things irrelevant to this issue):

public static class ImmutablePerson implements Person {

    private final String name;
    
    private ImmutablePerson(String name) {
        this.name = name;
    }

    @Override
    public String getName() {
        return name;
    }
    
    @Override
    public ImmutablePerson withName(String name) {
        return new ImmutablePerson(name);
    }
    
    @JsonCreator(mode = Mode.DELEGATING)
    static ImmutablePerson fromJson(MutablePerson delegate) {
        return new ImmutablePerson(delegate.name);
    }
    
    @JsonTypeInfo(use=Id.NONE)
    @JsonDeserialize
    @JsonAutoDetect(fieldVisibility = Visibility.NONE)
    static class MutablePerson implements Person {
        
        String name;
        
        @Override
        public String getName() {
            throw new UnsupportedOperationException();
        }
        public void setName(String name) {
            this.name = name;
        }
        @Override
        public ImmutablePerson withName(String name) {
            throw new UnsupportedOperationException();
        }
    } 
}

Note the @JsonCreator pattern that it's using on the fromJson method. It basically tells Jackson, that whenever the ImmutablePerson class is encountered when deserializing, it should use that factory method by deserializing the current JSON object under deserialization and calling the factory method with the delegate deserialized object as the argument.

Note that the json type that is used as a delegate here is marked with @JsonTypeInfo(use=Id.NONE), and this is actually important, as only types declared like this are usable for @JsonCreator(mode = Mode.DELEGATING) factory method. gwt-jackson doesn't support this use case, it will fail on

default:
logger.log( TreeLogger.Type.ERROR, "JsonTypeInfo.Id." + typeInfo.use() + " is not supported" );
throw new UnableToCompleteException();

I will provide a PR with a JUnit test for this issue.

nfekete added a commit to nfekete/gwt-jackson that referenced this issue May 16, 2018
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

1 participant