1. 概述

在这个教程中,我们将学习如何使用MapStruct将一个枚举(enum) 的值映射到另一个枚举的值。同时,我们还将了解在源枚举值在目标枚举中没有对应项时如何抛出异常。

2. MapStruct 库

MapStruct 是一个简化 Java Bean 映射的代码生成工具。 最新的 MapStruct 库可以在 Maven 中央仓库找到。

现在,让我们在 pom.xml 文件中添加依赖:

<dependency>
    <groupId>org.mapstruct</groupId>
    <artifactId>mapstruct</artifactId>
    <version>1.6.0.Beta1</version> 
</dependency>

此外,为了自动在项目的目标文件夹中生成方法,我们需要在 maven-compiler-plugin 插件中添加 annotationProcessorPaths

<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.6.0.Beta1</version>
            </path>
        </annotationProcessorPaths>
    </configuration>
</plugin>

3. 问题介绍

首先,创建我们的源枚举,命名为 InputLevel,它有三个可能的值:HIGHMEDIUMLOW

enum InputLevel {

    LOW, MEDIUM, HIGH

}

接下来,添加目标枚举。这个枚举仅包含两个值:HIGHLOW

enum OutputLevel {

    LOW, HIGH

}

目标是将 InputLevel 转换为 OutputLevel。例如,输入 InputLevel.LOW 应得到 OutputLevel.LOW。然而,MEDIUM 没有对应的值。因此,我们希望在这种情况下抛出异常。

4. 当源无对应目标时抛出异常

我们将使用 @Mapper 注解并创建一个 Mapper 接口。从 MapStruct 库的 1.5.0.Beta1 版本开始,我们可以使用 @ValueMapping 注解来实现这一目标:

@Mapper
interface LevelMapper {

    @ValueMapping(source = MappingConstants.ANY_REMAINING, target = MappingConstants.THROW_EXCEPTION)
    OutputLevel inputLevelToOutputLevel(InputLevel inputLevel);

}

如上所述,我们配置了注解,使得映射源枚举中的任何值如果没有在目标枚举中找到对应项,就会抛出异常。

现在,快速检查一下当给定 InputLevel.HIGH 时,方法是否正确返回 OutputLevel.HIGH

LevelMapper levelMapper = Mappers.getMapper(LevelMapper.class);

@Test
void givenHighInputLevel_WhenInputLevelToOutputLevel_ThenHighOutputLevel() {
    assertEquals(OutputLevel.HIGH, levelMapper.inputLevelToOutputLevel(InputLevel.HIGH));
}

最后,确认当我们尝试将 InputLevel.MEDIUM 转换为 OutputLevel 时,会抛出异常。具体来说,会抛出一个 IllegalArgumentException

@Test
void givenMediumInputLevel_WhenInputLevelToOutputLevel_ThenThrows() {
    assertThrows(IllegalArgumentException.class, () -> levelMapper.inputLevelToOutputLevel(InputLevel.MEDIUM));
}

5. 总结

在这篇文章中,我们使用 MapStruct 库将源枚举的值映射到目标枚举,并配置了映射器在源枚举值在目标枚举中没有对应项时抛出异常。

如往常一样,完整的代码可在 GitHub 查看。