【问题标题】:Create a custom Jackson annotation创建自定义 Jackson 注释
【发布时间】:2012-10-16 19:09:58
【问题描述】:

一个项目需要大量使用以下Jackson注解组合。那么,有没有办法创建另一个注释以避免丑陋的复制/粘贴:

public class A {
    @JsonProperty("_id")
    @JsonSerialize(using=IdSerializer.class)
    @JsonDeserialize(using=IdDeserializer.class)
    String id;
}

public class B {
    @JsonProperty("_id")
    @JsonSerialize(using=IdSerializer.class)
    @JsonDeserialize(using=IdDeserializer.class)
    String id;
}

public class C {
    @CustomId // don't repeat that configuration endlessly
    String id;
}

更新:我试过了,没有成功:-(

@Retention(RetentionPolicy.RUNTIME)
@JacksonAnnotationsInside
@JsonProperty("_id")
@JsonSerialize(using=IdSerializer.class, include=JsonSerialize.Inclusion.NON_NULL)
@JsonDeserialize(using=IdDeserializer.class)
public @interface Id {}

public class D {
    @Id
    private String id;
}

【问题讨论】:

    标签: java annotations marshalling jackson


    【解决方案1】:

    使用@JacksonAnnotationsInside解决问题:

    public class JacksonTest {
    
        @Retention(RetentionPolicy.RUNTIME)
        @JacksonAnnotationsInside
        @JsonProperty("_id")
        @JsonSerialize(using=IdSerializer.class, include=Inclusion.NON_NULL)
        @JsonDeserialize(using=IdDeserializer.class)
        public @interface Id {
        }
    
        public static class Answer {
            @Id
            String id;
            String name;
    
            public Answer() {}
        }
    
        @Test
        public void testInside() throws IOException {
            ObjectMapper mapper = new ObjectMapper();
            VisibilityChecker<?> checker = mapper.getSerializationConfig().getDefaultVisibilityChecker();
            mapper.setVisibilityChecker(checker.withFieldVisibility(JsonAutoDetect.Visibility.ANY));
    
            String string = "{ 'name' : 'John' , '_id' : { 'sub' : '47cc'}}".replace('\'', '"');
            Answer answer = mapper.reader(Answer.class).readValue(string);
            Assertions.assertThat(answer.id).isEqualTo("47cc");
        }
    }
    

    【讨论】:

      【解决方案2】:

      我猜你可以编写自己的注释类

      package org.codehaus.jackson.annotate ;
      
      public @ interface JsonProperty
      {
            String value ( ) default "_id" ;
      }
      
      public @ interface JsonSerialize
      {
            Class using ( ) default IdSerializer.class ;
      }
      
      ...
      

      编译这些类并确保它们在原始版本之前的类路径中。这会减少但不会消除复制/粘贴。

      那么你的代码示例就变成了

      public class A {
          @JsonProperty
          @JsonSerialize
          @JsonDeserialize
          String id;
      }
      
      public class B {
          @JsonProperty
          @JsonSerialize
          @JsonDeserialize
          String id;
      }
      

      我知道这并不是你真正想要的,但这是一个开始。

      【讨论】:

      • 我不明白,您能否提供一个示例来说明它的外观?谢谢。
      • 好的。这似乎是有趣的第一步。任何想法只收集序列化器和反序列化器?非常感谢。
      • @yvesamsellem 我不明白你的评论。
      • 我明白你的意思。即使它不完美,它也会有所帮助。我只是想知道 Jackson 是否有办法(也许是注释)将 @Serialize@Deserialize 信息分组。这些是相互联系的,而且,IMO,他们很少会没有另一个。再次感谢。
      • @yvesamsellem 所以 IdSerializer.class 不是一个合适的默认值,因为在其他地方您可能会使用不同的序列化程序,但在您使用 Serialize 的任何地方,您也可以使用具有相同 using 值的 Deserialize。我不知道 Jackson 是否有这样的东西,但您可以使用带有 BCEL 之类的自定义类加载器以编程方式添加 Serialize 和 Deserialize 注释。
      猜你喜欢
      • 2010-10-03
      • 1970-01-01
      • 1970-01-01
      • 2017-05-05
      • 1970-01-01
      • 1970-01-01
      • 2018-11-17
      • 1970-01-01
      相关资源
      最近更新 更多