Java MapStruct:将HashMap条目作为源处理
这是我的源对象:Java MapStruct:将HashMap条目作为源处理,java,mapstruct,Java,Mapstruct,这是我的源对象: 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 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 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);
}
目前,它工作得很好,但我想知道是否有一种更“优雅”的方法将映射条目设置为源。因为我没有使用“qualifiedByName”属性添加转换函数,所以它看起来只有在指定了“source”时才能工作。我误解了什么吗
我尝试了以下方法,但没有取得令人满意的结果:
- 覆盖我的记录类中特定字段的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");
}
}
谢谢你的回答。这确实有帮助。但是,我不喜欢属性在MappingUtil类中硬编码的事实:/n在您看来,这真的是唯一的方法吗?@nbchn没有硬编码的值,就无法进行映射。MapStruct在这里非常安全,因为如果字段名更改,它将引发编译错误。在发布之前,我已经测试了这个解决方案,它正常工作。我想我别无选择。谢谢你宝贵的帮助。我使用@Named注释对映射器上的所有内容做了一些更紧凑的操作:)我尝试级联转换函数(类似于映射映射--[server]-->String server--[toLowerCase]-->String lowerCasedServer),但没有成功,似乎只应用了第一个。我必须将所有转换放在一个函数中。有什么线索吗?@nbchn目前,您无法链接此类转换调用,您必须通过单一方法来完成。关于硬编码,我建议您注意这是MapStruct在
Map
和Bean之间进行映射的一个特性请求。@Filip谢谢您提供的信息。我期待着看到这些美好的进化。到目前为止,我非常喜欢这个产品。干得好:)
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 );
}