java - 强制 MapStruct 使用自定义方法而不是 dto 值

标签 java spring-boot mapstruct

我有一个想要映射的 UserDTO 和 User 实体。创建新用户时,某些字段(例如:passwordmodifiedBy)必须通过某种自定义方法生成(例如:password 是随机生成的)生成并编码,但 modifiedBy 用户名是从安全服务中检索的)。为此,我将一些服务自动连接到映射器中。其中许多返回 String,而 MapStruct 无法理解在每种情况下使用哪一个,而只是使用它在接受 String 作为输入的所有内容上找到的第一个。

@Mapper(componentModel = "spring", uses = PasswordEncoder.class)
public interface UserMapper {

@Mapping(target = "password", qualifiedByName = "PASS")
User mapUser(UserDto dto);

@Named("PASS")
default String getPass(PasswordEncoder passwordEncoder){
    return passwordEncoder.encode(some_random_generator);
    }
}

这会生成在任何接受 String 的 setter 中仅使用 PasswordEncoder 中的方法的代码,并且不使用 getPass(...) 方法根本不。 但是,我需要它仅在 password 字段上使用我的 getPass(...) 方法。

最佳答案

目前无法将使用的映射器或服务传递给默认方法。有mapstruct/mapstruct#1637为此开放。另外,您也不能真正执行 @Mapper(uses = PasswordEncoder.class ) 因为这会导致所有 StringString 通过密码编码器。不过,您可以做的是创建自己的自定义 PasswordEncoderMapper 并在其上使用 @Named,这样您就可以掌控一切。

这可能看起来像这样:

@Qualifier // org.mapstruct.Qualifier
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.CLASS)
public @interface EncodedMapping {
}

public class PasswordEncoderMapper {

    protected final PasswordEncoder passwordEncoder;

    public PasswordEncoderMapper(PasswordEncoder passwordEncoder) {
        this.passwordEncoder = passwordEncoder;
    }

    @EncodedMapping
    public String encode(String value) {
        return passwordEncoder.encode(value);
    }
}

@Mapper(componentModel = "spring", uses = PasswordEncoderMapper.class)
public interface UserMapper {

    @Mapping(target = "password", qualifiedBy = EncodedMapping.class)
    User mapUser(UserDto dto);
}

关于modifiedBy 属性。您应该将其作为 @ObjectFactory 的一部分或通过使用表达式来完成。

使用表达式可以如下所示:

@Mapper(componentModel = "spring", uses = PasswordEncoderMapper.class, imports = SecurityUtils.class)
public interface UserMapper {

    @Mapping(target = "password", qualifiedBy = EncodedMapping.class)
    @Mapping(target = "modifiedBy", expression = "java(SecurityUtils.getCurrentUserId())")
    User mapUser(UserDto dto);
}

关于java - 强制 MapStruct 使用自定义方法而不是 dto 值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54286464/

相关文章:

java - Jasypt 停止维护了吗?使用 Spring Boot 进行加密时使用什么

java - 通过方法 'setDelegate'参数0表示的不满足的依赖关系;我能做些什么?

java - 对 DataStore 异常执行查询

java - Oracle中如何同时更新两个表?

java - 如何将convertAndSendToUser()与外部代理(例如Spring4中的RabbitMQ)一起使用?

mysql - Liquibase Hibernate diff 异常

Java:通用数组创建

Java akka 将常见的东西放到一处

java - IntelliJ 想法 : Maven compilation warning about supported annotation processor source version 'RELEASE_6' on Java 11

java - 防止更新时在 Mapstruct 中进行空检查