You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MapStruct代码重复问题:仅需为Token字段应用generateToken方法

解决MapStruct自动为login字段调用generateToken的问题

问题根源在于你在@Mapper注解中指定了uses = MapperGenerateToken.class,MapStruct会自动扫描该类中的转换方法,当发现generateToken的输入输出类型与login字段的类型匹配时,就会自动将其应用到login字段的转换上。

以下是两种可行的解决方式:

方式一:移除@Mapper的uses属性(推荐)

直接去掉@Mapper中的uses配置,仅在token字段的@Mapping中通过expression显式调用generateToken方法。这样MapStruct不会自动将该方法应用到其他字段。

修改后的Mapper代码:

public interface TelemarketerAccountMapper {
    TelemarketerAccountMapper INSTANCE = Mappers.getMapper(TelemarketerAccountMapper.class);

    @Mapping(expression = "java(MapperGenerateToken.generateToken(assistant.getLogin()))", target = "token")
    @Mapping(source = "assistant.login", target = "login")
    AuthenticatedTelemarketerAccount map(TelemarketerAccount assistant);
}

生成的代码会变为:

@Override
public AuthenticatedTelemarketerAccount map(TelemarketerAccount assistant) {
    if (assistant == null) {
        return null;
    }

    AuthenticatedTelemarketerAccount authenticatedTelemarketerAccount = new AuthenticatedTelemarketerAccount();

    authenticatedTelemarketerAccount.setLogin(assistant.getLogin());
    authenticatedTelemarketerAccount.setToken(MapperGenerateToken.generateToken(assistant.getLogin()));

    return authenticatedTelemarketerAccount;
}

方式二:使用@Named限定转换方法

如果需要保留uses = MapperGenerateToken.class的配置(比如该类中有其他需要复用的转换方法),可以通过@Named注解标记generateToken,并在token字段上显式指定使用该方法,同时为login字段指定默认的 identity 转换。

步骤1:为generateToken添加@Named注解

import org.mapstruct.Named;

public class MapperGenerateToken {
    @Named("generateToken")
    public static String generateToken(String login) {
        // 你的token生成逻辑
        return login + "_token";
    }
}

步骤2:修改Mapper接口

import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Named;

@Mapper(uses = MapperGenerateToken.class)
public interface TelemarketerAccountMapper {
    TelemarketerAccountMapper INSTANCE = Mappers.getMapper(TelemarketerAccountMapper.class);

    @Mapping(target = "token", source = "login", qualifiedByName = "generateToken")
    @Mapping(target = "login", source = "login", qualifiedByName = "identity")
    AuthenticatedTelemarketerAccount map(TelemarketerAccount assistant);

    // 定义identity转换方法,直接返回原对象
    @Named("identity")
    default <T> T identity(T value) {
        return value;
    }
}

这样MapStruct会仅对token字段使用generateToken方法,login字段则通过identity方法直接赋值,不会调用generateToken。

内容的提问来源于stack exchange,提问作者Willian Tártaro

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 18:30:41