@JsonSerialize и @JsonDeserialize не работают, когда включены в аннотацию - PullRequest
0 голосов
/ 02 июля 2019

Я пытаюсь создать пользовательскую аннотацию для токенизации заданного свойства всегда, когда оно помечено, поэтому у меня следующая структура:

@JsonComponent
public class TokenSerializer {

    @JsonSerialize(using = IdToTokenSerializer.class) // This does not work 
    @JsonDeserialize(using = TokenToIdDeserializer.class) // This does not work 
    @Retention(RetentionPolicy.RUNTIME)
    public static @interface TokenizedId {
        Class<?> value();
    }

    public static class IdToTokenSerializer extends JsonSerializer<Long> implements ContextualSerializer {
        ...
    }

    public static class TokenToIdDeserializer extends JsonDeserializer<Long> implements ContextualDeserializer {
        ...
    }
}

Почему я так использую? Потому что @TokenizedId предоставит класс, который условно будет рассмотрен на сериализаторе / десериализаторе, чтобы что-то сделать.Это значение настраивается с помощью ContextualDeserializer, извлекающего класс из @TokenizedId.

Проблема заключается в том, что и сериализатор, и десериализатор не работают, когда я аннотирую так:

@TokenizedId(MyClass.class)
private Long id;

Но они работают, когда я использую вот так (удаляя @JsonSerialize и @JsonDeserialize из @TokenizedId):

@JsonSerialize(using = IdToTokenSerializer.class)
@JsonDeserialize(using = TokenToIdDeserializer.class)
@TokenizedId(MyClass.class)
private Long id;

Лично мне не понравился этот подход, так как разработчикам всегда нужно помнитьиспользуйте эти три аннотации, когда они хотят токенизировать некоторый идентификатор, а также мне хотелось бы, чтобы @TokenizedId всегда был связан с этими сериализаторами.

Есть ли способ заставить работать сериализатор / десериализатор при аннотировании надругая аннотация?

1 Ответ

1 голос
/ 02 июля 2019

Мне удалось заставить аннотацию работать так, как я хотел, посмотрев некоторую подсказку о библиотеке Джексона, я нашел аннотацию @JacksonAnnotationsInside:

/**
 * Meta-annotation (annotations used on other annotations)
 * used for indicating that instead of using target annotation
 * (annotation annotated with this annotation),
 * Jackson should use meta-annotations it has.
 * This can be useful in creating "combo-annotations" by having
 * a container annotation, which needs to be annotated with this
 * annotation as well as all annotations it 'contains'.
 * 
 * @since 2.0
 */
@Target({ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@JacksonAnnotation
public @interface JacksonAnnotationsInside
{

}

Включение этого в мою аннотацию решило проблему:

@JacksonAnnotationsInside
@JsonSerialize(using = IdToTokenSerializer.class) 
@JsonDeserialize(using = TokenToIdDeserializer.class)
@Retention(RetentionPolicy.RUNTIME)
public static @interface TokenizedId {
    Class<?> value();
}
...