Сопоставление атрибутов Java POJO

У меня есть вариант использования, когда я получаю некоторые атрибуты в запросе, подобном этому,

"filters": [
  {
    "field": "fName",
    "value": "Tom"
  },
  {
    "field": "LName",
    "value": "Hanks"
  }
]

У меня нет определенной модели для этого. Я просто получаю эти атрибуты в запросе и запускаю запрос на эластичный поиск с использованием этих атрибутов. Мои записи в эластичном поиске имеют одинаковые имена атрибутов.

Теперь мне нужно поддерживать устаревшее приложение, в котором имена атрибутов совершенно разные. Например: fName становится firstName, а lName становится lastName.

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

ПРИМЕЧАНИЕ. У меня нет POJO, определенных для этих записей.

Как этого добиться эффективно? Я думал об использовании Orika mapper, но не уверен, как это будет работать без предварительного определения классов.


person User0911    schedule 01.08.2018    source источник
comment
Я столкнулся с аналогичной проблемой при синхронизации информации между двумя системами. У них были очень разные соглашения об именах, и один из них несколько раз менял соглашения об именах за последние несколько лет. (Пришлось все это синхронизировать). Я решил это с помощью файла конфигурации, который сопоставил новые поля со старыми полями. Когда пришел запрос на синхронизацию, я нашел подходящее поле, переключил его на поле, с которым он был связан, и отправил его. Для ответа я снова взял отображение, используя альтернативное имя, и отправил ответ. Может что-то подобное поможет?   -  person gkgkgkgk    schedule 07.08.2018
comment
Конечно. На самом деле у меня не так много исследований по этому поводу, но я обнаружил, что это было лучшее решение, потому что оно могло быть изменено человеком, которому я распространял приложение, если им нужно когда-либо добавлять / удалять поля. Другой подход, который я использовал (от которого я отказался, потому что он был слишком жестко закодирован), заключался в написании настраиваемого сериализатора / десериализатора объектов и отправке через него ответа на запрос.   -  person gkgkgkgk    schedule 07.08.2018
comment
@gkgkgkgk хорошо, есть ли у вас какие-либо сведения или указатели для решения конфигурации?   -  person User0911    schedule 07.08.2018
comment
К сожалению, я не ... Но конфиг не должен быть слишком сложным в настройке. Я в основном написал файл json с сопоставлениями между новым и старым именами, а затем в моем коде нашел значение поля, содержащее поле, которое я искал. Затем я взял сопоставленное значение и использовал его. Я могу написать базовый поток / псевдокод, если это будет полезно   -  person gkgkgkgk    schedule 08.08.2018
comment
Я понимаю, что в настоящее время у вас нет определенного POJO, но каков ваш желаемый результат для выполнения эластичного поиска? Это POJO с полями fName, lName, заполненными значениями на основе запроса?   -  person Magdrop    schedule 08.08.2018
comment
Что мешает написать преобразователь запроса JSON в ваш нормализованный JSON?   -  person Mạnh Quyết Nguyễn    schedule 08.08.2018
comment
Я бы также предпочел пропустить сопоставление объектов и напрямую сопоставить JSON с нормализованным JSON ... В конце концов, это то, что вы хотите ... Вам не нужно изобретать классы / объекты, которые не приносят вам пользы, и дополнительно использовать сопоставление утилита просто для выполнения того, что вы уже могли сделать с помощью простого преобразования json ... возможно, вам поможет следующий ответ: Преобразователь JSON в JSON упоминая также ElasticSearch как вариант использования   -  person Roland    schedule 08.08.2018


Ответы (3)


Что мешает написать преобразователь запроса JSON в ваш нормализованный JSON?

Нормальный поток, о котором я могу думать, таков:

Request JSON -> POJO -> POJO with normalized value -> Normalized JSON

Итак, ваш POJO выглядит так:

public class Filter {

     List<FieldFilter> filters;

     public static class FieldFilter {
         private String field;
         private String value;
     }
}

Теперь у вас будет карта трансформации вроде:

Map<String, String> fieldNameMapping = new HashMap<>();
fieldNameMapping.put("fName", "firstName");
fieldNameMapping.put("firstName", "firstName");

// The process of populating this map can be done either by a static initializer, or config/properties reader

Затем вы трансформируете свой POJO:

Filter filterRequest;
List<FieldFilters> normlizedFilters = 
    filterReq.getFilters().stream()
             .map(f -> new FieldFilter(fieldNameMapping.get(f.getField()), f.getValue())
             .collect(toList());

Затем преобразуйте класс Filter в ваш нормализованный JSON.

person Mạnh Quyết Nguyễn    schedule 08.08.2018

У нас похожий сценарий, и мы используем apache JOLT. Если вы хотите попробовать несколько примеров, вы можете обратиться к jolt-demo-online-утилита

person Vivek Shukla    schedule 08.08.2018

Вместо этого используйте преобразователь JSON в JSON. Хорошие ответы по этому поводу можно найти здесь: Преобразователь JSON в JSON и здесь: Эквивалент XSLT для JSON

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

person Roland    schedule 08.08.2018