Пример Lombok @SuperBuilder с аннотациями JSON - PullRequest
0 голосов
/ 10 октября 2018

Может кто-нибудь предоставить мне рабочий пример с экспериментальной аннотацией lombok @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;
}

Спасибо

Ответы [ 2 ]

0 голосов
/ 10 октября 2018

Рабочее решение в 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;
}
0 голосов
/ 10 октября 2018

Обновлено 2018-11-10: выпущен Lombok 1.18.4

Для работы Lombok @Builder и @SuperBuilder с Джексоном необходимо добавить заголовок класса строителя вручнуюи поместите @JsonPOJOBuilder(withPrefix="") на него.Затем Lombok сгенерирует только остаток класса строителя.Это необходимо, потому что по умолчанию Джексон использует методы-установщики в качестве префикса «with», а в строителях Lombok нет префикса (а Lombok его нет и, вероятно, никогда не будет настраиваться в этом отношении).

Когда @SuperBuilder был введен в Lombok 1.18.2, он не был настраиваемым (то есть вы не могли вручную добавить заголовок класса построителя).В результате, использование @SuperBuilder с Джексоном было не просто возможно.

Это изменилось с Lombok 1.18.4 (см. этот запрос на получение ): @SuperBuilder теперь (по крайней мере, частично)) настраиваемый, и это позволяет нам добавить аннотацию.Помните, что код, сгенерированный @SuperBuilder, довольно сложен и сильно загружен обобщениями.Чтобы случайно не испортить код, вам нужно взглянуть на вывод delombok и скопировать / вставить заголовок класса оттуда.Здесь вам нужно добавить заголовок класса реализации компоновщика и добавить к нему аннотацию:

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

Обратите внимание, что вам нужно расширить видимость SubABuilderImpl по крайней мере для частного пакета.

Аннотация @JsonDeserialize должна также ссылаться на класс реализации компоновщика, а не на абстрактный компоновщик:

@JsonDeserialize(builder = SubA.SubABuilderImpl.class)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...