这是我的源对象:

public class Record {

    public final long captureTime;
    public final String environnement;
    public final String bundle;
    public final String type;
    public final String id;
    public final Map<String,Object> meta;

}

这是我的目标对象:
public class MappedRecord {

    public final long captureTime;
    public final String environnement;
    public final String bundle;
    public final String type;
    public final String id;
    public final String ip;
    public final String server;

}

我的映射器如下所示:
public interface RecordMapper {

    RecordMapper MAPPER = Mappers.getMapper( RecordMapper.class );


    @Mappings({
        @Mapping(source = "captureTime", target = "captureTime"),
        @Mapping(source = "environnement", target = "environnement"),
        @Mapping(source = "bundle", target = "bundle"),
        @Mapping(source = "type", target = "type"),
        @Mapping(source = "id", target = "id"),
        @Mapping(expression = "java((String) r.meta.get(\"ip\"))", target = "ip"),
        @Mapping(expression = "java((String) r.meta.get(\"server\"))", target = "server"),
    })

    MappedRecord toMappedRecord(Record r);

}

现在它运行良好,但我想知道是否有更“优雅”的方式将 Map 条目设置为源。因为这样我没有设法使用“qualifiedByName”属性添加转换函数,看起来它只能在指定“源”时工作。我是不是误会了什么?

我尝试了以下方法但没有令人满意的结果:
  • 覆盖我的 Record 类中特定字段的 getter
  • 添加具有“qualifiedByName”属性的转换函数。就像是:
    @Named("metaGetter")
    default String dataGetter (String property) {
        return (String) r.meta.get(property);
    }
    

    但显然这不会编译,因为属性名称作为正确的来源无效。

  • 谢谢你的时间。

    最佳答案

    编写自己的限定符:

    public class MappingUtil {
        @Qualifier
        @Target(ElementType.METHOD)
        @Retention(RetentionPolicy.SOURCE)
        public @interface Ip {
        }
        @Qualifier
        @Target(ElementType.METHOD)
        @Retention(RetentionPolicy.SOURCE)
        public static @interface Server {
        }
        @Ip
        public String ip(Map<String, Object> in) {
    
            return (String)in.get("ip");
        }
        @Server
        public String server(Map<String, Object> in) {
    
            return (String)in.get("server");
        }
    }
    

    然后添加到映射中:
    @Mapper( uses = MappingUtil.class )
    public interface SourceTargetMapper {
    
        SourceTargetMapper MAPPER = Mappers.getMapper( SourceTargetMapper.class );
    
        @Mappings( {
            @Mapping(source = "map", target = "ip", qualifiedBy = MappingUtil.Ip.class ),
            @Mapping(source = "map", target = "server", qualifiedBy = MappingUtil.Server.class ),
        } )
        Target toTarget( Source s );
    }
    

    关于java - MapStruct : Dealing with HashMap entries as source,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/44390808/

    10-09 03:35