user3018350
user3018350

Reputation:

Jackson - @JsonCreator return generics

I want to integrate vavr validation library in my command dto's in a way that when command dto is deserialized from request, return type of the static factory will be Try but jackson is throwing following error :

Type definition error: [simple type, class com.foo.command.FooCommand]; nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of com.foo.command.FooCommand (no Creators, like default construct, exist): cannot deserialize from Object value (no delegate- or property-based Creator)

Here is FooCommand

@AllArgsConstructor(access = AccessLevel.PRIVATE)
public final class FooCommand {
    private String foo;
    private String bar;

    @JsonCreator
    public static Try<FooCommand> of(
            @JsonProperty("foo") String foo,
            @JsonProperty("bar") String bar
    ) {
        return Try.of(() -> {
            //Validate values
        });
    }
}

I am using spring 5 and it's annotated to deserialize request body automatically into controller parameter. Is something like this possible ? Thanks in advance.

Upvotes: 1

Views: 889

Answers (1)

neXus
neXus

Reputation: 2243

I had a similar problem that I fixed by using Converters: Using Jackson, how can I deserialize values using static factory methods that return wrappers with a generic type?

I haven't yet found how to apply the converters automatically, so you have to annotate every occurrence of the wrapped type in your requests.

public class Request {
    @JsonDeserialize(converter = FooCommandConverter.class)
    Try<FooCommand> command;
}

You can write a Converter like so:

public class FooCommandConverter
        extends StdConverter<FooCommandConverter.DTO, Try<FooCommand>> {

    @Override
    public Try<FooCommand> convert(FooCommandConverter.DTO dto) {
        return FooCommand.of(
            dto.foo,
            dto.bar
        );
    }

    public static class DTO {
        public String foo;
        public String bar;
    }
}

Upvotes: 0

Related Questions