Mapstruct:HashMap 作为对象的源
Mapstruct: HashMap as source to Object
如何使用 HashMap<String, Object>
作为对象的来源?
这是我的目标对象:
public class ComponentStyleDTO{
private String attribute;
private Object value;
}
我尝试使用我发现的 this 方法,该方法也在文档中,但对我来说失败了。
我的映射器:
@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);
}
我的工具:
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;
}
}
}
下面是我的使用方法:
HashMap<String, Object> hmap = new HashMap<String, Object>();
hmap.put(attr.getKey(), attr.getValue());
ComponentStyleDTO componentDTO = componentStyleMapper.hashMapToComponentStyleDTO(hmap);
但返回的属性和值都是空的。知道我可能做错了什么吗?
恕我直言,最好的方法是最简单的方法:
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;
}
或
default List<ComponentStyleDTO> hashMapToComponentStyleDTO(HashMap<String, Object> hashMap){
return hashMap.entrySet()
.stream()
.map(e -> new ComponentStyleDTO(e.getKey(), e.getValue()))
.collect(Collectors.toList());
}
不确定您要实现的目标。如果您的映射更复杂,也许最好的方法确实是使用 .
中的方法
另一方面,它对您不起作用的原因是您没有为您的映射定义源。在您链接的示例中,有一个 POJO 作为源参数,源是该 POJO 中的一个映射。为了使其正常工作,您的映射器需要如下所示:
@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);
}
注意事项:当使用非默认 componentModel
时,您不应使用 Mappers
工厂来获取映射器实例。如果你这样做,你将在与其他映射器一起工作时获得 NPE。
供日后参考。从 Mapstruct 1.5 开始,我认为这个用例是开箱即用的。参见 mapstruct release note
如何使用 HashMap<String, Object>
作为对象的来源?
这是我的目标对象:
public class ComponentStyleDTO{
private String attribute;
private Object value;
}
我尝试使用我发现的 this 方法,该方法也在文档中,但对我来说失败了。
我的映射器:
@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);
}
我的工具:
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;
}
}
}
下面是我的使用方法:
HashMap<String, Object> hmap = new HashMap<String, Object>();
hmap.put(attr.getKey(), attr.getValue());
ComponentStyleDTO componentDTO = componentStyleMapper.hashMapToComponentStyleDTO(hmap);
但返回的属性和值都是空的。知道我可能做错了什么吗?
恕我直言,最好的方法是最简单的方法:
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;
}
或
default List<ComponentStyleDTO> hashMapToComponentStyleDTO(HashMap<String, Object> hashMap){
return hashMap.entrySet()
.stream()
.map(e -> new ComponentStyleDTO(e.getKey(), e.getValue()))
.collect(Collectors.toList());
}
不确定您要实现的目标。如果您的映射更复杂,也许最好的方法确实是使用
另一方面,它对您不起作用的原因是您没有为您的映射定义源。在您链接的示例中,有一个 POJO 作为源参数,源是该 POJO 中的一个映射。为了使其正常工作,您的映射器需要如下所示:
@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);
}
注意事项:当使用非默认 componentModel
时,您不应使用 Mappers
工厂来获取映射器实例。如果你这样做,你将在与其他映射器一起工作时获得 NPE。
供日后参考。从 Mapstruct 1.5 开始,我认为这个用例是开箱即用的。参见 mapstruct release note