Есть ли какая-то стратегия Джексона-Джона (с использованием аннотаций или иным способом), которая будет выполнять некоторую логику до и после десериализации поля? - PullRequest
9 голосов
/ 02 апреля 2011

Мне нужно выполнить некоторый код после каждой десериализации в полях POJO. Есть ли какой-нибудь способ, которым я могу сделать это с помощью какой-либо стратегии аннотации Джексона (или другой)?

  1. Один из способов - создать собственный десериализатор для каждого полятип, который будет реализовывать PostLogicDeserializerInterface или расширять некоторые PostLogicDeserializerAbstract.Но это создаст множество загроможденного кода, который будет трудно поддерживать (вместо простого использования @JsonProperty).Поэтому я думаю, что это не очень хорошая идея.

  2. Я видел, что вы можете использовать @JsonDeserialize на уровне классов, но только для классов значений.Из документации:

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

Так что я думаю, что это тоже не сработает.

  1. Использование некоторой пользовательской логики в методах установки POJOs - плохая практика!А с другой стороны, я думаю, что Джексон использует отражение для задания полей в любом случае ... Не очень хорошая стратегия.

Моя цель - определить процент полейкоторые были установлены десериализатором.Мне нужно иметь счетчик, который будет увеличиваться при каждой вызванной десериализации (заполненное поле).И как только десериализация всего класса (POJO) закончится, мне потребуется выполнить некоторую логику, используя рефлексию.

То, как я сейчас реализовал , это

  • После того, как POJO десериализован картографом Джексона, я прохожу каждое поле с помощью отражения
  • проверить, установлено ли оно, fi, если оно равно нулю, или -1 для примитивных чисел (ранее начальные значения).(одна из особенностей этого подхода заключается в том, что вы не можете проверить логическое значение, если оно установлено)
  • использовать отражение для какого-либо другого вида проверки (давайте назовем его логическим X)
  • выполнить логику, котораязависит от процента установленных полей и логики X.

Я бы предпочел некоторую стратегию Джексона, так как мне не нужно проверять POJO с отражением.Это скорее будет сделано на месте (во время десериализации POJO).

Приветствия,
Despot

1 Ответ

4 голосов
/ 02 апреля 2011

На данный момент нет какой-либо конкретной функции для пост- или предварительной обработки; и этот вид приближается к границам того, что должна делать привязка данных. Если бы мне пришлось сделать это для определенных полей, я бы, вероятно, просто добавил бы это в setter, так как это просто и работает; но требует одинаковой логики во всех соответствующих установщиках.

@ JsonDeserialize также можно использовать для отдельных свойств (поле, установщик), так что вы можете создать собственный десериализатор: и так как вы хотите постобработку, вы можете просто найти «настоящий» десериализатор (в идеале, сделав JsonDeserializer реализовать либо ContextualDeserializer, либо ResolvableDeserializer - здесь это может не иметь значения, но в общем случае это делается здесь, чтобы избежать проблем с циклическими зависимостями), делегируйте его и измените значение. Это предполагает, что это значение, о котором вы заботитесь больше, чем поле.

Наконец, есть также способы изменения BeanDeserializer экземпляров (путем регистрации BeanDeserializerModifier) - вы можете подклассы соответствующих компонентов (я думаю, SettableBeanProperty ...) подключить дополнительную обработку или даже заменить десериализатор на использовать, сохраняя ссылку на оригинальный десериализатор по умолчанию.

Но, в конце концов, ваш случай звучит как что-то, что лучше всего обрабатывается чем-то другим: например, API Bean Validation (jsr-303) кажется потенциально хорошим соответствием для логики постобработки. Так как это несколько ортогонально к привязке данных, это может быть превосходной альтернативой, поскольку оно не зависит от привязки данных (Джексон), может быть использовано много раз.

...