【问题标题】:Mapstruct mapping with condition and nullValuePropertyMappingStrategy具有条件和 nullValuePropertyMappingStrategy 的 Mapstruct 映射
【发布时间】:2020-03-11 20:02:44
【问题描述】:

如果标题不清楚,我很抱歉,让我通过示例代码说明一下:

UpdateProfileDto

public class UpdateProfileDto {

    @NotEmpty
    private String firstName;

    @NotEmpty
    private String lastName;

    @Size(max = 20)
    private String currentPassword;

    @Size(max = 20)
    private String newPassword;

    @Size(max = 20)
    private String confirmNewPassword;

    // getters and setters
}

编码映射

@Qualifier
@Target(ElementType.METHOD)
@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(config = MapperConfig.class, componentModel = "spring", uses = PasswordEncoderMapper.class)
public interface UserMapper {

    @Mappings({
            @Mapping(target = "firstName", source = "firstName"),
            @Mapping(target = "lastName", source = "lastName"),
            @Mapping(target = "fullName", expression = "java(user.getFirstName() + \" \" + user.getLastName())"),
            @Mapping(target = "password",
                    source = "newPassword",
                    nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE,
                    qualifiedBy = EncodedMapping.class)
    })
    void updateUserFromDto(UpdateUserProfileDto updateUserProfileDto, @MappingTarget User user);
}

生成的 UserMapperImpl

@Generated(
    value = "org.mapstruct.ap.MappingProcessor",
    date = "2020-03-11T13:51:34+0800",
    comments = "version: 1.3.0.Final, compiler: javac, environment: Java 1.8.0_231 (Oracle Corporation)"
)
@Component
public class UserMapperImpl implements UserMapper {

    @Autowired
    private PasswordEncoderMapper passwordEncoderMapper;

    @Override
    public void updateUserFromDto(UpdateUserProfileDto updateUserProfileDto, User user) {
        if ( updateUserProfileDto == null ) {
            return;
        }

        if ( updateUserProfileDto.getFirstName() != null ) {
            user.setFirstName( updateUserProfileDto.getFirstName() );
        }
        else {
            user.setFirstName( null );
        }
        if ( updateUserProfileDto.getLastName() != null ) {
            user.setLastName( updateUserProfileDto.getLastName() );
        }
        else {
            user.setLastName( null );
        }
        if ( updateUserProfileDto.getNewPassword() != null ) {
            user.setPassword( passwordEncoderMapper.encode( updateUserProfileDto.getNewPassword() ) );
        }

        user.setFullName( user.getFirstName() + " " + user.getLastName() );
    }
}

从生成的UserMapperImpl 中,我不仅要检查newPassword 是否有值...,还要检查currentPasswordnewPassword 是否有值并继续user.setPassword()

我的意思是这样的:

...
if ( updateUserProfileDto.getCurrentPassword() != null && updateUserProfileDto.getNewPassword() != null ) {
    user.setPassword( passwordEncoderMapper.encode( updateUserProfileDto.getNewPassword() ) );
}
...

问题

如何更改我的映射器接口UserMapper,以便在设置目标user.password 之前检查currentPasswordnewPassword,并且仍将使用PasswordEncoderMapper.encode(password)

如果我尝试使用expression 而不是source 并检查currentPasswordnewPassword 是否都有值,然后将user.password 设置为newPassword。否则,它不会对user.password使用NullValuePropertyMappingStrategy做任何事情...但似乎不允许混合expressionNullValuePropertyMappingStrategy

谢谢!

【问题讨论】:

    标签: spring-boot mapstruct


    【解决方案1】:

    我会从以下方法开始

    @Mapper(config = MapperConfig.class, componentModel = "spring")
    public abstract class UserMapper { // using class instead of interface to be able to inject beans
    
        @Autowired
        private PasswordEncoderMapper passwordEncoderMapper;
    
        @Mappings({
                // your non-password mappings
        })
        void updateUserFromDto(UpdateUserProfileDto updateUserProfileDto, @MappingTarget User user);
    
    
        @AfterMapping
        void setPassword(UpdateUserProfileDto updateUserProfileDto, @MappingTarget User user) {
            if (updateUserProfileDto.getCurrentPassword() != null && updateUserProfileDto.getNewPassword() != null) {
                user.setPassword(passwordEncoderMapper.encode( updateUserProfileDto.getNewPassword()));
            }
        }
    }
    

    【讨论】:

    • 还可以为新密码添加存在检查,以检查当前密码和新密码。这样 MapStruct 将使用存在检查。
    猜你喜欢
    • 1970-01-01
    • 2020-04-24
    • 2015-11-12
    • 2020-08-02
    • 2020-05-10
    • 2023-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多