Как я могу сказать Джексону игнорировать свойство, для которого у меня нет контроля над исходным кодом? - PullRequest
102 голосов
/ 14 сентября 2011

Короче говоря, одна из моих сущностей имеет GeometryCollection , которая выдает исключение, когда вы вызываете "getBoundary" (почему это еще одна книга, а сейчас давайте скажем, что это так и работает) ,

Есть ли способ, которым я могу сказать Джексону не включать этот конкретный геттер? Я знаю, что могу использовать @JacksonIgnore, когда владею / управляю кодом. Но это не так, Джексон завершает достижение этой точки путем непрерывной сериализации родительских объектов. Я видел вариант фильтрации в документации Джексона. Это правдоподобное решение?

Спасибо!

Ответы [ 8 ]

146 голосов
/ 15 сентября 2011

Вы можете использовать Jackson Mixins .Например:

class YourClass {
  public int ignoreThis() { return 0; }    
}

С этим миксином

abstract class MixIn {
  @JsonIgnore abstract int ignoreThis(); // we don't need it!  
}

С этим:

objectMapper.getSerializationConfig().addMixInAnnotations(YourClass.class, MixIn.class);

Редактировать:

Благодаря комментариям, сДжексон 2.5+, API изменился и должен вызываться с objectMapper.addMixIn(Class<?> target, Class<?> mixinSource)

61 голосов
/ 17 сентября 2013

Еще одна возможность, если вы хотите игнорировать все неизвестные свойства, вы можете настроить маппер следующим образом:

mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
24 голосов
/ 23 июля 2015

Использование Java Class

new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)

Использование аннотации

@JsonIgnoreProperties(ignoreUnknown=true)
8 голосов
/ 02 апреля 2017

Подход на основе аннотаций лучше.Но иногда требуется ручное управление.Для этой цели вы можете использовать без метод ObjectWriter .

ObjectMapper mapper   = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
ObjectWriter writer   = mapper.writer().withoutAttribute("property1").withoutAttribute("property2");
String       jsonText = writer.writeValueAsString(sourceObject);
8 голосов
/ 15 сентября 2011

Смешанные аннотации здесь работают довольно хорошо, как уже упоминалось. Другая возможность, выходящая за пределы свойства @JsonIgnore, заключается в использовании @JsonIgnoreType, если у вас есть тип, который никогда не следует включать (т.е. если все экземпляры свойств GeometryCollection следует игнорировать). Затем вы можете либо добавить его напрямую (если вы управляете типом), либо использовать дополнение, например:

@JsonIgnoreType abstract class MixIn { }
// and then register mix-in, either via SerializationConfig, or by using SimpleModule

Это может быть более удобно, если у вас много классов, у всех из которых есть один метод доступа 'IgnoredType getContext ()' или около того (что имеет место для многих платформ)

5 голосов
/ 14 июня 2015

У меня была похожая проблема, но она была связана с двунаправленными отношениями Hibernate.Я хотел показать одну сторону отношений и программно игнорировать другую, в зависимости от того, с какой точкой зрения я имел дело.Если вы не можете сделать это, вы получите неприятные StackOverflowException с.Например, если бы у меня были эти объекты

public class A{
  Long id;
  String name;
  List<B> children;
}

public class B{
  Long id;
  A parent;
}

, я хотел бы программно игнорировать поле parent в B, если я смотрю на A, и игнорировать поле children в A, если я смотрюв B.

я начал использовать миксин, чтобы сделать это, но это очень быстро становится ужасным;вокруг вас так много бесполезных классов, которые существуют исключительно для форматирования данных.Я закончил тем, что написал свой собственный сериализатор для более понятной обработки: https://github.com/monitorjbl/json-view.

Он позволяет программно указать, какие поля игнорировать:

ObjectMapper mapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addSerializer(JsonView.class, new JsonViewSerializer());
mapper.registerModule(module);

List<A> list = getListOfA();
String json = mapper.writeValueAsString(JsonView.with(list)
    .onClass(B.class, match()
        .exclude("parent")));

Это также позволяет вамлегко определить очень упрощенные представления с помощью подстановочных сопоставителей:

String json = mapper.writeValueAsString(JsonView.with(list)
    .onClass(A.class, match()
        .exclude("*")
         .include("id", "name")));

В моем исходном случае потребность в простых представлениях, подобных этому, заключалась в том, чтобы показать минимальный минимум о родителе / ​​потомке, но это также стало полезным для нашей ролибезопасностьМенее привилегированные представления объектов необходимы для получения меньшего количества информации об объекте.

Все это исходит от сериализатора, но я использовал Spring MVC в своем приложении.Чтобы правильно обрабатывать эти случаи, я написал интеграцию, которую вы можете включить в существующие классы контроллеров Spring:

@Controller
public class JsonController {
  private JsonResult json = JsonResult.instance();
  @Autowired
  private TestObjectService service;

  @RequestMapping(method = RequestMethod.GET, value = "/bean")
  @ResponseBody
  public List<TestObject> getTestObject() {
    List<TestObject> list = service.list();

    return json.use(JsonView.with(list)
        .onClass(TestObject.class, Match.match()
            .exclude("int1")
            .include("ignoredDirect")))
        .returnValue();
  }
}

Оба доступны в Maven Central.Я надеюсь, что это поможет кому-то еще, это особенно уродливая проблема с Джексоном, у которой не было хорошего решения для моего случая.

0 голосов
/ 11 декабря 2018

Если вы хотите ВСЕГДА исключить определенные свойства для любого класса, вы можете использовать метод setMixInResolver:

    @JsonIgnoreProperties({"id", "index", "version"})
    abstract class MixIn {
    }

    mapper.setMixInResolver(new ClassIntrospector.MixInResolver(){
        @Override
        public Class<?> findMixInClassFor(Class<?> cls) {
            return MixIn.class;  
        }

        @Override
        public ClassIntrospector.MixInResolver copy() {
            return this;
        }
    });
0 голосов
/ 01 сентября 2015

Еще один хороший момент - использовать @JsonFilter.Некоторые подробности здесь http://wiki.fasterxml.com/JacksonFeatureJsonFilter

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...