当前位置: 首页 > 知识库问答 >
问题:

用MapStruct映射嵌套的原始列表

翟泰
2023-03-14

我正在尝试映射我的遗留API对象(我无法更改它),该对象具有嵌套的原始list类型属性。列表的元素与DTO列表的元素不兼容,应显式映射为嵌套。不幸的是,MapStruct似乎认为原始list与所有类型化列表兼容,并忽略了我试图指定的任何映射,而生成的代码不能正常工作,随后在序列化程序的某个地方产生错误。

我的API对象具有嵌套的原始类型列表:

@Getter
public class ApiObject {
    protected Long uid;
    protected String name;
    List values; // Raw type list. Elements not compatible with DTO Value type.
}

我的DTO对象具有DTO值类型元素的泛型类型列表:

@Setter
public class DtoObject {
    protected Long uid;
    protected String name;
    List <Value> values; // Should be mapped with ApiObject.values
}
@Mapping(target = "values", source = "values", qualifiedByName = "myCustomValueMapper")
public abstract DtoObject map(final ApiObject apiObject);

...但MapStruct仍然忽略myCustomValueMapper,生成的映射器impl对象如下所示(注意分配给DTO值对象的不兼容API值对象):

@Override
public DtoObject map(APiObject apiObject) {
    if ( apiObject == null ) {
        return null;
    }

    DtoObject dtoObject = new DtoObject();

    List list = apiObject.getValues();
    if ( list != null ) {
        dtoObject.setValues( new ArrayList<Value>( list ) );  // This code produces error later, in serializer.
    }
    else {
        dtoObject.setValues( null );
    }
    dtoObject.setUid( apiObject.getUid() );
    dtoObject.setName( apiObject.getName() );

    return dtoObject;
}

在MapStruct中是否存在为嵌套原始列表的元素指定映射的可能性,或者可能是实现兼容映射的任何变通方法?

共有1个答案

曹均
2023-03-14

可以使用默认方法显式管理列表中项的转换:

@Mapper
public interface ApiMapper {

    @Mapping(target = "values", source = "values")
    DtoObject map(final ApiObject apiObject);

    default List<Value> mapToValueList(List list) {
        List<Value> values = new ArrayList<>();
        for (Object o: list) {
            Value value = new Value();
            // here goes code to convert o -> Value
            // ...
            values.add(value);
        }
        return values;
    }
}

生成的代码如下所示:

public class ApiMapperImpl implements ApiMapper {

    @Override
    public DtoObject map(ApiObject apiObject) {
        if ( apiObject == null ) {
            return null;
        }

        DtoObject dtoObject = new DtoObject();
        if ( dtoObject.getValues() != null ) {
            List<Value> list = mapToValueList( apiObject.getValues() );
            if ( list != null ) {
                dtoObject.getValues().addAll( list );
            }
        }
        return dtoObject;
    }
}

list list=mapToValueList(apiObject.getValues()); 将调用接口上的默认方法(注意,ApiMapperImpl实现了ApiMapper接口)。

 类似资料:
  • 我如何在下面的场景中使用Mapstruct进行bean映射。 现在我想把sourceId映射到targetId,courseName映射到subjectName,studentName映射到memberName(list到list)。

  • 我尝试使用MapStruct编写映射器类,如下所示: 目前它显示了“未知属性”“customer.customerid”和“usertypes.usertype.userid”等错误。有人能帮我用MapStruct映射所有这些元素吗? 问题2:我们如何绘制跟踪图?1)customerId usertypes->user->userid 2)pdtPrice offers->OffersType->

  • 我的问题是如何将对象包含嵌套对象映射到DTO,而不是嵌套对象的值,例如,如果有2个这样的类: 调用TestClassDTOToTestClass()并发送TestClassDTO包含NestedClassDTO.之后。。返回的TestClass为空NestedClass。。有没有可能不用自己编写地图绘制程序来绘制地图? 嘘

  • 我创建映射如下所示。如何将平面dto对象属性(街道、城市等)映射到域对象中的嵌套地址。当我试着去做的时候,我发现了一个错误: [错误]诊断:返回类型中的属性“Address.PostalCode”未知。@Mapping(来源=“City”,目标=“Address.City”), 还有类...

  • 假设我有这些实体: null

  • 有人能帮忙填写上面的评论部分吗?或者是否有其他选项来映射这些对象? 编辑:我尝试了下面的解决方案,但是接口实现类本身发生了变化。