Как преобразовать строковое поле в значение hashmap с помощью mapstruct java?

#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. Спасибо за вашу помощь, Хосейн.