#java #spring #spring-boot #mapstruct
Вопрос:
Я хочу, чтобы map accountNo
argument
отображал значение с определенным ключом (я имею в виду ключ hashmap) с помощью mapstrcut. Есть идеи?
Событие — моя цель
private Map<String, Object> argument;
private LocalDateTime dateTime;
AccountRequest — мой источник
private String accountNo;
private LocalDateTime dateTime;
У меня есть картограф, как показано ниже, но я тоже хочу противоположный.
@Mapping(target = "accountNo", expression = "java(event.getArgument().get(key).toString())")
AccountRequest eventToAccountRequest(Event event, String key);
Event accountRequestToEvent(AccountRequest accountRequest); // this is my question
Ответ №1:
В настоящее время нет готовой поддержки для отображения из компонента в карту. Однако существует открытый запрос функции для этой функции.
Это означает, что для вашего примера вам нужно будет сделать это в пользовательском сопоставлении.
например
@Mapping(target = "argument", source = "accountNo", qualifiedByName = "accountNoToArgument")
Event accountRequestToEvent(AccountRequest accountRequest);
@Named("accountNoToArgument")
default Map<String, Object> accountNotToArgument(String accountNo) {
return accountNo == null ? null : Collections.singletonMap("accountNo", accountNo);
}
Это гарантирует, что остальные параметры автоматически сопоставляются с помощью MapStruct.
Примечание о лучшем отображении для eventToAccountRequest
. Вместо использования выражения вы можете улучшить его с помощью пользовательского метода сопоставления и @Context
. например
@Mapping(target = "accountNo", source = "argument", qualifiedByName = "argumentToAccountNo")
AccountRequest eventToAccountRequest(Event event, @Context String key);
@Named("argumentToAccountNo"
default String argumentToAccountNo(Map<String, Object> argument, @Context key) {
return argument == null : null : argument.get(key).toString();
}
Используя это, вы избежите потенциального NPE, если event.getArgument()
значение равно null.
Комментарии:
1. Спасибо, @Filip вы упомянули важные моменты, цените это.
Ответ №2:
Почему бы не использовать сопоставитель по умолчанию. Что-то вроде:
default Event accountRequestToEvent(AccountRequest accountRequest) {
Event event = new Event();
event.setArguement(Collections.singletonMap(accountRequest.getAccountNo(), "value"));
return event;
}
Комментарии:
1. Я искал способ map-struct с аннотациями, но я думаю, что это невозможно для отображения
Map
.2. Затем вам нужно создать функцию для преобразования строки в карту, определить там источник и пункт назначения, а затем это будет автоматически выбрано вашей уже определенной функцией: accountRequestToEvent @Faramarz-Afzali
3. Спасибо за вашу помощь, Хосейн.