Сериализация одного класса двумя различными способами с помощью Jackson

в одном из наших проектов мы используем java webapp, разговаривающий с экземпляром MongoDB. В базе данных мы используем DBRefs для отслеживания некоторых объектных отношений. Мы (de)сериализуем объекты POJO с помощью jackson (используя mongodb-jackson-mapper).

однако мы используем те же POJOs, чтобы затем (de)сериализоваться во внешний мир, где наш передний конец имеет дело с представлением JSON.

теперь нам нужен способ сериализации для внешнего мира, чтобы содержать ссылочный объект из DBRef (чтобы пользовательский интерфейс мог представить полный объект), в то время как мы, очевидно, хотим иметь DBRef записан в базу данных, а не весь объект.

прямо сейчас я написал непроверенный статический код вложенного класса:

public static class FooReference {
    public DBRef<Foo> foo;

    // FIXME how to ensure that this doesn't go into the database?
    public Foo getFoo() {
        return foo.fetch();
    }
}

В идеале я хотел бы способ аннотировать это, чтобы я мог (de)сериализовать его либо с результатом getFoo (), либо без него, вероятно, в зависимости от некоторого объекта конфигурации. Возможно ли это? Видите ли вы лучший способ сделать это? это?

2 ответов


глядя на параметры, кажется, вы можете аннотировать свойства, которые будут отображаться только в случае заданного View перешло к ObjectMapper используется для сериализации. Таким образом, вы можете отредактировать класс:

public static class FooReference {
    public DBRef<Foo> foo;

    @JsonView(Views.WebView.class)
    public Foo getFoo() {
        return foo.fetch();
    }
}

а также предлагаем:

class Views {
    static class WebView { }
}

а затем сериализовать после создания конфигурации с правильным представлением:

SerializationConfig conf = objectMapper.getSerializationConfig().withView(Views.WebView.class);
objectMapper.setSerializationConfig(conf);

который затем сериализует его. Не указывая представление при сериализации с помощью оболочки MongoDB, метод будет проигнорирован. Свойства без аннотации JsonView сериализуются по умолчанию, поведение можно изменить, указав:

objectMapper.configure(SerializationConfig.Feature.DEFAULT_VIEW_INCLUSION, false);

используйте пользовательский JSONSerializer и примените свою логику в serialize способ:

public static class FooReference {
    public DBRef<Foo> foo;

    @JsonSerialize(using = CustomSerializer.class)
    public Foo getFoo() {
        return foo.fetch();
    }
}

public class CustomSerializer extends JsonSerializer<Object> {
   public void serialize(Object value, JsonGenerator jgen, SerializerProvider provider)
       throws IOException, JsonProcessingException {
     // jgen.writeObjectField ...
   }
}