MapStruct : Dealing with HashMap entries as source

寵の児 提交于 2021-02-09 08:11:33

问题


Here is my source object:

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;

}

Here is my destination object:

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;

}

And my mapper looks like the following:

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);

}

For now it works well but I would like to know if there is a more "elegant" way to set Map entries as source. Because with this I did not manage to add transformation functions using the "qualifiedByName" property, it looks like it can only work when a "source" is specified. Did I misunderstand something ?

I tried the following approaches without satisfying results :

  • Overwrite getter for specific fields in my Record class
  • Add a transformation function with the "qualifiedByName" property. Something like:

    @Named("metaGetter")
    default String dataGetter (String property) {
        return (String) r.meta.get(property);
    }
    

    But obviously this does not compile as the property name is not valid as a proper source.

Thanks for your time.


回答1:


Write your own qualifier:

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");
    }
}

and then just add to the mapping:

@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 );
}


来源:https://stackoverflow.com/questions/44390808/mapstruct-dealing-with-hashmap-entries-as-source

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!