龙目岛@SuperBuilder带有json注释的示例

2022-09-02 21:00:10

有人可以给我一个关于龙目岛@SuperBuilder实验注释的工作示例吗?

我无法让它运行,并且没有可用的代码示例作为文档。

目前我的代码如下所示:

超类:

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXISTING_PROPERTY, property = "type")
@JsonSubTypes({
  @JsonSubTypes.Type(value = SubA.class),
  @JsonSubTypes.Type(value = AnotherSub.class)
})
@Getter
@Accessors(fluent = true, chain = true)
@SuperBuilder
public abstract class AbstractA {

    @JsonProperty
    protected final String superProperty;
}

子类:

@Getter
@EqualsAndHashCode(callSuper = true)
@Accessors(fluent = true, chain = true)
@SuperBuilder
@JsonDeserialize(builder = SubA.SubABuilder.class) // class not found?
@JsonTypeName("SubA")
public class SubA extends AbstractA {

    @JsonProperty
    private final String fieldA;
}

谢谢


答案 1

更新于2018-11-10:龙目岛1.18.4发布

更新于2020-10-18:龙目岛1.18.16发布

龙目岛 1.18.16 包含新的@Jacksonized注释。有了它,你可以简单地写:

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXISTING_PROPERTY, property = "type")
@JsonSubTypes({
  @JsonSubTypes.Type(value = SubA.class),
  @JsonSubTypes.Type(value = AnotherSub.class)
})
@Jacksonized
@SuperBuilder
// more annotations...
public abstract class AbstractA {

    @JsonProperty
    protected final String superProperty;
}

@Jacksonized
@SuperBuilder
@JsonTypeName("SubA")
// more annotations...
public class SubA extends AbstractA {

    @JsonProperty
    private final String fieldA;
}

这将自动插入所有必要的 Jackson 注释,并对生成的构建器进行一些调整。无需再定制。

对于 1.18.4 和 1.18.12 之间的早期龙目岛版本,这是要走的路:

对于龙目岛和与杰克逊合作,您必须手动添加构建器类标头并在其上放置一个。然后,龙目岛将仅生成构建器类的其余部分。这是必要的,因为Jackson的默认设置是构建者的setter方法以“with”作为前缀,但Lombok的构建器没有任何前缀(Lombok不是,也可能永远不会在这方面进行配置)。@Builder@SuperBuilder@JsonPOJOBuilder(withPrefix="")

在龙目岛1.18.2中引入时,它是不可自定义的(即,您无法手动添加构建器类标头)。因此,与杰克逊一起使用并不容易。@SuperBuilder@SuperBuilder

龙目岛1.18.4改变了这一点(请参阅此拉取请求):现在(至少部分)可自定义,这允许我们添加注释。请注意,生成的代码非常复杂,并且加载了大量泛型。为了避免意外弄乱代码,您应该查看delombok输出并从那里复制/粘贴类标头。在这里,您需要添加构建器实现类标头并将注释放在其上:@SuperBuilder@SuperBuilder

@JsonPOJOBuilder(withPrefix="")
static final class SubABuilderImpl extends SubABuilder<SubA, SubABuilderImpl> {
}

请注意,您必须将 可见性至少扩大到包私有。SubABuilderImpl

注释还必须引用生成器实现类,而不是抽象生成器:@JsonDeserialize

@JsonDeserialize(builder = SubA.SubABuilderImpl.class)

答案 2

Eclipse中的一个工作解决方案,请注意,Lombok IntelliJ集成并不支持所有功能,因此代码在Eclipse和javac中编译良好,但IntelliJ认为它已经损坏,但执行代码没有问题。

public static ObjectMapper createObjectMapper() {

    final ObjectMapper mapper = new ObjectMapper();
    mapper.setAnnotationIntrospector(new JacksonAnnotationIntrospector() {

        @Override
        public JsonPOJOBuilder.Value findPOJOBuilderConfig(final AnnotatedClass ac) {
            if (ac.hasAnnotation(JsonPOJOBuilder.class)) {
                return super.findPOJOBuilderConfig(ac);
            }
            return new JsonPOJOBuilder.Value("build", "");
        }
    });

    return mapper;
}

public static void main(final String[] args) throws Exception {
    final ObjectMapper objectMapper = createObjectMapper();

    final String serializedForm = objectMapper.writeValueAsString(SubA.builder().build());
    System.out.println(serializedForm);
    final SubA anA = objectMapper.readValue(serializedForm, SubA.class);
    System.out.println(anA);
}


@Getter
@EqualsAndHashCode(callSuper = true)
@Accessors(fluent = true, chain = true)
@SuperBuilder
@JsonDeserialize(builder = SubA.SubABuilderImpl.class)
@JsonTypeName("SubA")
public static class SubA extends AbstractA {

    @JsonProperty
    private final String fieldA;
}


@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "type")
@JsonSubTypes({
    @JsonSubTypes.Type(value = SubA.class)
})
@Getter
@Accessors(fluent = true, chain = true)
@SuperBuilder
public static abstract class AbstractA {

    @JsonProperty
    protected final String superProperty;
}

推荐