1. Обзор
В этой статье мы узнаем, как использовать собственный маппер с библиотекой MapStruct .
Библиотека MapStruct используется для отображения между типами компонентов Java . Используя пользовательский сопоставитель с MapStruct , мы можем настроить методы сопоставления по умолчанию.
2. Зависимости Maven
Давайте добавим библиотеку mapstruct в наш Maven pom.xml
:
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>1.3.1.Final</version>
</dependency>
Чтобы увидеть автоматически сгенерированные методы внутри целевой папки
проекта , мы должны добавить annotationProcessorPaths
в плагин maven-compiler-
plugin:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<annotationProcessorPaths>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>1.3.1.Final</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
3. Пользовательский картограф
Пользовательские преобразователи используются для решения конкретных требований преобразования. Чтобы достичь этого, мы должны определить метод для преобразования. Затем мы должны уведомить MapStruct о методе. Наконец, MapStruct вызовет метод для преобразования исходного объекта в целевой.
Например, давайте представим, что у нас есть приложение, которое вычисляет отчет об индексе массы тела (ИМТ) пользователя. Чтобы рассчитать ИМТ, мы должны собрать значения тела пользователя. Чтобы преобразовать имперские единицы в метрические, мы можем использовать пользовательские методы сопоставления.
Есть два способа использования пользовательского картографа с MapStruct. Мы можем либо вызвать пользовательский метод, введя его в свойствеqualifiedByName
аннотации @Mapping
, либо создать для него аннотацию. ``
Прежде чем мы начнем, мы должны определить класс DTO для хранения имперских значений:
public class UserBodyImperialValuesDTO {
private int inch;
private int pound;
// constructor, getters, and setters
}
Далее давайте определим класс DTO для хранения значений метрик:
public class UserBodyValues {
private double kilogram;
private double centimeter;
// constructor, getters, and setters
}
3.1. Пользовательский картограф с методом
Чтобы начать использовать собственные карты, давайте создадим интерфейс с аннотацией @Mapper
:
@Mapper
public interface UserBodyValuesMapper {
//...
}
Во-вторых, давайте создадим наш пользовательский метод с типом возвращаемого значения, который мы хотим, и аргументом, который нам нужно преобразовать. Мы должны использовать аннотацию @ Named
с параметром value, чтобы сообщить MapStruct о пользовательском методе сопоставления:
@Mapper
public interface UserBodyValuesMapper {
@Named("inchToCentimeter")
public static double inchToCentimeter(int inch) {
return inch * 2.54;
}
//...
}
И, наконец, давайте определим метод интерфейса картографа с помощью аннотации @Mapping
. В этой аннотации мы сообщим MapStruct о типе источника, типе цели и методе, который он будет использовать:
@Mapper
public interface UserBodyValuesMapper {
UserBodyValuesMapper INSTANCE = Mappers.getMapper(UserBodyValuesMapper.class);
@Mapping(source = "inch", target = "centimeter", qualifiedByName = "inchToCentimeter")
public UserBodyValues userBodyValuesMapper(UserBodyImperialValuesDTO dto);
@Named("inchToCentimeter")
public static double inchToCentimeter(int inch) {
return inch * 2.54;
}
}
Давайте протестируем наш пользовательский маппер:
UserBodyImperialValuesDTO dto = new UserBodyImperialValuesDTO();
dto.setInch(10);
UserBodyValues obj = UserBodyValuesMapper.INSTANCE.userBodyValuesMapper(dto);
assertNotNull(obj);
assertEquals(25.4, obj.getCentimeter(), 0);
3.2. Пользовательский картограф с аннотацией
Чтобы использовать пользовательский преобразователь с аннотацией, мы должны определить аннотацию вместо аннотации @Named
. Затем мы должны сообщить MapStruct о вновь созданной аннотации, указав
параметрqualByName аннотации @Mapping
.
Давайте посмотрим, как мы определяем аннотацию:
@Qualifier
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.CLASS)
public @interface PoundToKilogramMapper {
}
Давайте добавим аннотацию @PoundToKilogramMapper
к нашему методу poundToKilogram
:
@PoundToKilogramMapper
public static double poundToKilogram(int pound) {
return pound * 0.4535;
}
Теперь давайте определим метод интерфейса картографа с помощью аннотации @Mapping
. В аннотации сопоставления мы сообщим MapStruct об исходном типе, целевом типе и классе аннотации, который он будет использовать:
@Mapper
public interface UserBodyValuesMapper {
UserBodyValuesMapper INSTANCE = Mappers.getMapper(UserBodyValuesMapper.class);
@Mapping(source = "pound", target = "kilogram", qualifiedBy = PoundToKilogramMapper.class)
public UserBodyValues userBodyValuesMapper(UserBodyImperialValuesDTO dto);
@PoundToKilogramMapper
public static double poundToKilogram(int pound) {
return pound * 0.4535;
}
}
Наконец, давайте протестируем наш пользовательский картограф:
UserBodyImperialValuesDTO dto = new UserBodyImperialValuesDTO();
dto.setPound(100);
UserBodyValues obj = UserBodyValuesMapper.INSTANCE.userBodyValuesMapper(dto);
assertNotNull(obj);
assertEquals(45.35, obj.getKilogram(), 0);
4. Вывод
В этой статье мы узнали, как использовать пользовательский преобразователь с библиотекой MapStruct.
Реализации этих примеров и тестов доступны на GitHub .