java - Overriding Jackson's serializationdeserialization config for immutables compability - Stack Overflow

I have a number of Immutables classes, like:@Value.Immutableinterface Foo {String bar();}To make the

I have a number of Immutables classes, like:

@Value.Immutable
interface Foo {
    String bar();
}

To make these compatible with Jackson, I need to label these with @JsonDeserialize and @JsonSerialize, per the Immutables manual:

@Value.Immutable
@JsonDeserialize(as = ImmutableFoo.class)
@JsonSerialize(as = ImmutableFoo.class)
interface Foo {
    String bar();
}

This is a bit cumbersome at development time and noisy in the code. I'd like to configure Jackson such that any time it encounters a class annotated with @Value.Immutable that the serializer it chooses is ImmutableX for class name X and similarly for deserialization.

How do I go about configuring Jackson to do this?

I have a number of Immutables classes, like:

@Value.Immutable
interface Foo {
    String bar();
}

To make these compatible with Jackson, I need to label these with @JsonDeserialize and @JsonSerialize, per the Immutables manual:

@Value.Immutable
@JsonDeserialize(as = ImmutableFoo.class)
@JsonSerialize(as = ImmutableFoo.class)
interface Foo {
    String bar();
}

This is a bit cumbersome at development time and noisy in the code. I'd like to configure Jackson such that any time it encounters a class annotated with @Value.Immutable that the serializer it chooses is ImmutableX for class name X and similarly for deserialization.

How do I go about configuring Jackson to do this?

Share Improve this question asked Mar 26 at 2:33 Mark ElliotMark Elliot 77.1k23 gold badges144 silver badges162 bronze badges 3
  • If it was possible, why wouldn't Jackson already do it? – Louis Wasserman Commented Mar 26 at 2:37
  • This section seems to be about reducing annotation clutter. Is this what you are looking for? – Sweeper Commented Mar 26 at 2:40
  • You can probably bundle the two into a simplified custom annotation, e.g. @JsonImmutable, but I don't think there's any way for Jackson to see the existing Immutable annotation without resorting to hackery like replacing or shadowing the class to alter the retention policy. – shmosel Commented Mar 26 at 2:56
Add a comment  | 

1 Answer 1

Reset to default 0

You can do as this section says - add @JsonSerialize to a your own @Value.Style annotation.

@Target({ElementType.PACKAGE})
@Retention(RetentionPolicy.RUNTIME)
@JsonSerialize
@Value.Style(/* add more styling here if you need... */)
@interface JacksonImmutable {}

// package-info.java:
@JacksonImmutable
package com.example;

Then all the @Value.Immutable interfaces can be serialised. This also works for deserialisation if you are always using the concrete ImmutableXXX types, but if you want to work with the interfaces, it is a lot more difficult.

One way would be to find all the interface-implementation pairings using Reflections and add it to a custom SimpleModule.

var mapper = new ObjectMapper();
SimpleModule module = new SimpleModule("My Module", Version.unknownVersion());
var reflections = new Reflections(
        new ConfigurationBuilder()
                .forPackages("") // specify a package prefix here if you know where all your immutable classes are
                .addScanners(Scanners.TypesAnnotated, Scanners.SubTypes)
);
for (var type : reflections.getTypesAnnotatedWith(Value.Immutable.class)) {
    if (!type.isInterface()) { continue; }
    if (!type.getPackage().isAnnotationPresent(JacksonImmutable.class)) { continue; }
    helper(type, module, reflections);
}
mapper.registerModule(module);

// where the "helper" method (used for capturing the wildcards) is:
private static <T> void helper(Class<T> type, SimpleModule module, Reflections reflections) {
    var implClass = reflections.getSubTypesOf(type).stream()
            .filter(x -> x.getSimpleName().equals("Immutable" + type.getSimpleName())).findFirst();
    implClass.ifPresent(aClass -> module.addAbstractTypeMapping(type, aClass));
}

Though I'm not sure if doing all this is worth it just to avoid a few lines of annotations.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744167566a4561377.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信