简体   繁体   English

Mapstruct:HashMap 作为对象的源

[英]Mapstruct: HashMap as source to Object

How could I use a HashMap<String, Object> as source to an object?如何使用HashMap<String, Object>作为HashMap<String, Object>源?

Here is my target object:这是我的目标对象:

public class ComponentStyleDTO{
    private String attribute;
    private Object value;
}

I've tried to use this approach that I found and that is also in the documentation, but it's failing for me.我尝试使用我发现的这种方法,这也在文档中,但对我来说失败了。

My Mapper:我的映射器:

@Mapper(unmappedTargetPolicy = ReportingPolicy.IGNORE, componentModel = "spring", uses = ComponentStyleMapperUtil.class)
public interface ComponentStyleMapper {

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

    @Mappings({@Mapping(target = "attribute", qualifiedBy = ComponentStyleMapperUtil.Attribute.class),
    @Mapping(target = "value", qualifiedBy = ComponentStyleMapperUtil.Value.class)})
    ComponentStyleDTO hashMapToComponentStyleDTO(HashMap<String, Object> hashMap);
}

My Util:我的实用程序:

public class ComponentStyleMapperUtil{
    @Qualifier
    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.SOURCE)
    public @interface Attribute {
    }

    @Qualifier
    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.SOURCE)
    public @interface Value {
    }


    @Attribute
    public String attribute(HashMap<String, Object> in){

        return (String) in.entrySet().stream().findFirst().get().getKey();
    }

    @Value
    public Object value(HashMap<String, Object> in) {
        Object value = in.entrySet().stream().findFirst().get().getValue();

        if(value instanceof String){
            return value;
        }else if(value instanceof LinkedHashMap){
            List<ComponentStyleDTO> childs = new ArrayList<ComponentStyleDTO>();
            HashMap<String, Object> child = (HashMap<String, Object>) value;
            for(String key: child.keySet()){
                ComponentStyleDTO schild = new ComponentStyleDTO();
                schild.setAttribute(key);
                schild.setValue((String) child.get(key));
                childs.add(schild);
            }
            return childs;
        }else{
            return value;
        }

    }

}

And here's how I'm using this:这是我如何使用它:

    HashMap<String, Object> hmap = new HashMap<String, Object>();
    hmap.put(attr.getKey(), attr.getValue());
    ComponentStyleDTO componentDTO = componentStyleMapper.hashMapToComponentStyleDTO(hmap);

But it's returning me empty in attribute and value.但它让我在属性和值上都是空的。 Any idea of what I could be doing wrong?知道我可能做错了什么吗?

IMHO The best way is the simpliest way: 恕我直言,最好的方法是最简单的方法:

default ComponentStyleDTO hashMapToComponentStyleDTO(HashMap<String, Object> hashMap){
    ComponentStyleDTO result = new ComponentStyleDTO();
    result.setAtribute1(hashMap.get("atribute1"));
    result.setAtribute2(hashMap.get("atribute2"));
    result.setAtribute3(hashMap.get("atribute3"));
    ...
    return result;
}

or 要么

default List<ComponentStyleDTO> hashMapToComponentStyleDTO(HashMap<String, Object> hashMap){
    return hashMap.entrySet()
                  .stream()
                  .map(e -> new ComponentStyleDTO(e.getKey(), e.getValue()))
                  .collect(Collectors.toList());
}

Not sure what you are trying to achieve. 不确定您要达到的目标。 If your mapping is more complex maybe the best way is indeed to go with the approach in https://stackoverflow.com/a/54601058/1115491 . 如果您的映射更加复杂,也许最好的方法确实是使用https://stackoverflow.com/a/54601058/1115491中的方法。

That a side, the reason why it is not working for you is that you have not defined the source for your mapping. 一方面,它对您不起作用的原因是您尚未定义映射源。 In the example you linked there is a POJO as source parameter and the source is a map in that POJO. 在链接的示例中,有一个POJO作为源参数,而源是该POJO中的映射。 In order to make it work your mapper needs to look like: 为了使其正常工作,您的映射器需要如下所示:

@Mapper(unmappedTargetPolicy = ReportingPolicy.IGNORE, componentModel = "spring", uses = ComponentStyleMapperUtil.class)
public interface ComponentStyleMapper {

    @Mapping(target = "attribute", source = "hashMap", qualifiedBy = ComponentStyleMapperUtil.Attribute.class)
    @Mapping(target = "value", source = "hashMap", qualifiedBy = ComponentStyleMapperUtil.Value.class)
    ComponentStyleDTO hashMapToComponentStyleDTO(HashMap<String, Object> hashMap);
}

NB : When using the non default componentModel you should not use the Mappers factory for getting an instance of the mapper. 注意 :使用非默认componentModel ,不应使用Mappers工厂获取映射器的实例。 If you do that you will get an NPE when working with other mappers. 如果这样做,在与其他映射器一起使用时,您将获得一个NPE。

For future reference.备查。 As of Mapstruct 1.5 I think this usecase is supported out of the box.从 Mapstruct 1.5 开始,我认为这个用例是开箱即用的。 See mapstruct release note请参阅mapstruct 发行说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 MapStruct:将HashMap条目作为源处理 - MapStruct : Dealing with HashMap entries as source MapStruct 嵌套对象,仅当源元素不为空时才创建目标对象 - MapStruct nested object, create target object only if source element is not null Mapstruct 将源的单个 object 多个属性映射到目标的一个属性 - Mapstruct A single object multiple attribute of the source is mapped to an attribute of the target 在 MapStruct 中使用多源 Object 设置默认值策略 - Setting Default Value Strategy with Multiple Source Object in MapStruct 如何将字符串类型的 map 源 object 用于 MapStruct 中的目标 UUID? - How to map the source object of type String to target UUID in MapStruct? Mapstruct 映射:如果所有源参数属性都是 null,则返回 null object - Mapstruct Mapping : Return null object if all source parameters properties are null 如何通过使用 -MapStruct 从源 object 复制值来填充目标 object 内的 map? - How to fill in map inside target object by copying values from source object using -MapStruct? Mapstruct - 从源 object 的一组字段中准备一个列表,并将其设置为目标 object - Mapstruct - Prepare a list from a group of fields from the source object and set it to target object 是否可以使用 MapStruct 从 HashMap 转换为 List - Is it possible to convert from HashMap to List using MapStruct mapstruct 将一个 id 映射到一个对象 - mapstruct map an id to an object
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM