无法获得基本的Jackson Mixin工作

时间:2012-06-07 18:43:50

标签: java annotations jackson

我正在尝试使用Jackson 2.0 mixins序列化一个没有注释的类。

以下简化的源代码。请注意,我没有使用getter / setter,但似乎我仍然可以使用mixins according to some fairly sketchy documentation

public class NoAnnotation {
   private Date created;
   private String name;
   private int id;
   private List<URL> urls = new ArrayList();

   // make one with some data in it for the test
   static NoAnnotation make() {
      NoAnnotation na= new NoAnnotation();
      na.created = new Date();
      na.name = "FooBear";
      na.id = 23456;

      try {
         na.urls.add(new URL("http://www.eclipse.org/eclipselink/moxy.php"));
         na.urls.add(new URL("http://jaxb.java.net"));
      } catch (MalformedURLException e) {
         throw new RuntimeException(e);
      }
      return na;
   }

   // my Mixin "Class"
   static class JacksonMixIn {
      JacksonMixIn(@JsonProperty("created") Date created,
                   @JsonProperty("name") String name,
                   @JsonProperty("id") int id, 
                   @JsonProperty("urls") List<URL> urls)
         { /* do nothing */ }
   }

   // test code
   public static void main(String[] args) throws Exception {
      NoAnnotation na = NoAnnotation.make();
      ObjectMapper objectMapper = new ObjectMapper();
      objectMapper.addMixInAnnotations(NoAnnotation.class, JacksonMixIn.class);
      String jsonText = objectMapper.writeValueAsString(na);
      System.out.println(jsonText);
   }
}

当我运行主要时,我得到

Exception in thread "main" com.fasterxml.jackson.databind.JsonMappingException: No serializer found for class com.flyingspaniel.so.NoAnnotation and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationConfig.SerializationFeature.FAIL_ON_EMPTY_BEANS) )
    at com.fasterxml.jackson.databind.ser.impl.UnknownSerializer.failForEmpty(UnknownSerializer.java:51)
    at com.fasterxml.jackson.databind.ser.impl.UnknownSerializer.serialize(UnknownSerializer.java:25)
    at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:108)
    at com.fasterxml.jackson.databind.ObjectMapper._configAndWriteValue(ObjectMapper.java:2407)
    at com.fasterxml.jackson.databind.ObjectMapper.writeValueAsString(ObjectMapper.java:1983)
    at com.flyingspaniel.so.NoAnnotation.main(NoAnnotation.java:49)

我猜我在某个地方遗漏了一个基本的“setThis”步骤,但不知道是什么。谢谢!

编辑:当我按照例外中的说明操作并添加一行

objectMapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);

我不再获得异常,但结果是一个空的JSON字符串,“{}”。

EDIT2:如果我将字段设为公开,那么它可以正常工作,但这不是一个合理的对象设计。

3 个答案:

答案 0 :(得分:6)

如果您想以正确的方式使用注释混合声明它:

static class JacksonMixIn {
    @JsonProperty Date created;
    @JsonProperty String name;
    @JsonProperty int id;
    @JsonProperty List<URL> urls;
}

通过这种方式,您可以控制要序列化的字段,只需在混合中包含/排除它们。

答案 1 :(得分:5)

我明白了。如果要访问私有字段,则需要通过添加以下行来使用“可见性”:

 objectMapper.setVisibilityChecker(VisibilityChecker.Std.defaultInstance().withFieldVisibility(Visibility.ANY));

对于受保护的字段,您还可以使用Visibility.PROTECTED_AND_PUBLIC

答案 2 :(得分:1)

如前所述in your self-answer,更改字段可见性检查器将解决这种情况。作为修改 ObjectMapper 的替代方法,这可以通过使用 @JsonAutoDetect 注释,通过纯粹基于注释的解决方案来完成:

@JsonAutoDetect(fieldVisibility = Visibility.ANY)
static class JacksonMixIn {
   JacksonMixIn(@JsonProperty("created") Date created,
                @JsonProperty("id") int id)
      { /* do nothing */ }
}