Q: Может ли mapstruct понять, что выражение возвращает String, чтобы оно могло использовать мой dateFormat, который я предоставляю? - PullRequest
1 голос
/ 01 апреля 2019

Я пытаюсь заставить Mapstruct понять, что исходное выражение - это строка, которую можно отформатировать в java.util.LocalDate, но я не уверен, что все делаю правильно.Я попытался следовать указаниям в документах mapstruct.

@Mapping(componentModel = "cdi", uses=DateMapper.class)
public abstract class RedactedClassName

@Mapping(target = "birthDate",
            expression = "java(fileLine.substring(redactedpackagename.Constants.BIRTH_DATE_START_POS, redatcedpackagename.Constants.BIRTH_DATE_END_POS))")
    abstract PersonBio fileLineToPersonBio(String fileLine);

со следующим форматером

public class DateMapper {

    public String asString(LocalDate date) {

        return date != null ? date.format(DateTimeFormatter.ofPattern("yyyyMMdd")) : null;
    }

    public LocalDate asDate(String date) {
        return date != null ? LocalDate.parse(date, DateTimeFormatter.ofPattern("yyyyMMdd")) : null;
    }
}

создает

    @Override
    PersonBio fileLineToPersonBio(String fileLine) {
        if ( fileLine == null ) {
            return null;
        }

        PersonBio personBio = new PersonBio();

        personBio.setBirthDate( fileLine.substring(redactedpackagename.Constants.BIRTH_DATE_START_POS, redactedpackagename.Constants.BIRTH_DATE_END_POS) );

        return personBio;
    }

Редактировать: я изменил этот постнемного к тому, что я думаю, должно работать, но это все еще не работает.

Ответы [ 2 ]

2 голосов
/ 03 апреля 2019

Поскольку выводом вашего java-выражения является строка, вы ожидаете, что mapstruct вызовет метод asDate класса DateMapper?

То, что вы ожидаете получить в сгенерированном коде, выглядит примерно так:

...
personBio.setBirthDate( new DateMapper().asDate(fileLine.substring(redactedpackagename.Constants.BIRTH_DATE_START_POS, redactedpackagename.Constants.BIRTH_DATE_END_POS)));
..

Вы правы, это не работает.Я не знаю, почему ...

Вместо этого вы можете импортировать маппер и использовать его в выражении Java, а также проверять ввод с помощью StringUtils:

@Mapper(imports = {DateMapper.class, StringUtils.class})
public interface PersonBioMapper {

  @Mapping(target = "birthDate",
      expression = "java(new DateMapper().asDate(StringUtils.substring(fileLine, redactedpackagename.Constants.BIRTH_DATE_START_POS, redatcedpackagename.Constants.BIRTH_DATE_END_POS)))")
  PersonBio fileLineToPersonBio(String fileLine);
}

Другой способ (более читабельный)?) это как сказать Филиппу, сделать собственное отображение:

@Mapper
public interface PersonBioMapper {

  default PersonBio fileLineToPersonBio(String fileLine) {
    PersonBio personBio = new PersonBio();
    personBio.setBirthDate(new DateMapper().asDate(StringUtils.substring(fileLine,redactedpackagename.Constants.BIRTH_DATE_START_POS, redactedpackagename.Constants.BIRTH_DATE_END_POS)));

    return personBio;
  }
}
0 голосов
/ 02 апреля 2019

MapStruct не проверяет выражение во время генерации. Это означает, что вы должны убедиться, что ваше выражение выводит правильный код.

Я бы попытался подойти к проблеме, которую вы пытаетесь решить, с другой стороны. Вместо использования выражения используйте для него пользовательское сопоставление, которое создаст дату из строки.

Подробнее о выражении вы можете прочитать в разделе Выражения документации.

...