使用mapstruct映射带参数的集合

时间:2016-04-04 10:04:18

标签: java mapstruct

要使用mapstruct映射某个对象,我需要一些自定义的后期处理,这需要一个额外的参数来完成它的工作:

@Mapper
public abstract class AlertConfigActionMapper {

    @Mappings({ @Mapping(target = "label", ignore = true)})
    public abstract AlertConfigActionTO map (AlertConfigAction action, Locale userLanguage);

    @AfterMapping
    public void setLabel (AlertConfigAction  action, @MappingTarget AlertConfigActionTO to, Locale userLanguage) {
        for (AlertConfigActionLabel label : action.getAlertConfigActionLabels()) {
            if (label.getLanguage().equals(userLanguage)) {
                to.setLabel(label.getLabel());
                break;
            } else if (label.getLanguage().equals(Locale.ENGLISH)) {
                to.setLabel(label.getLabel());
            }
        }

    }
}

这很好用。 当我向此映射器添加以下方法时,问题就开始了:

public abstract ArrayList<AlertConfigActionTO> mapList (List<AlertConfigAction> actions, Locale userLanguage);

我也需要传递这个参数(userLanguage),但是在这种情况下mapstruct似乎“分解”:我为这部分生成以下代码(这自然会产生编译错误):

@Override
public List<AlertConfigActionTO> mapList(List<AlertConfigAction> actions, Locale userLanguage) {
    if ( actions == null && userLanguage == null ) {
        return null;
    }

    List<AlertConfigActionTO> list = new List<AlertConfigActionTO>();

    return list;
}

我确定它与参数有关,因为如果我删除它(从所有映射方法中),那么mapList方法就会正确生成。

在这种情况下,需要做些什么才能允许自定义参数?

3 个答案:

答案 0 :(得分:8)

你所描述的是不可能的(还)。您可以在issue tracker中打开功能请求吗?我们应该提供将参数表示为某种“上下文”的方法,该上下文在调用堆栈中传递。

作为暂时的解决方法,您可以查看在调用映射例程之前使用的ThreadLocal以及在映射后自定义中访问的id。它不优雅 - 你需要确保清理本地线程以避免内存泄漏 - 但它应该可以解决问题。

答案 1 :(得分:1)

我认为这是不可能的。至少不那样。问题是你准备了接口/抽象类 - 休息是由引擎完成的。并且该引擎需要具有一个参数的方法......有装饰器,但它们的方式相同。我会尝试注入语言。创建bean,将其标记为会话作用域,然后查找。使用Spring,您可以使用ScopedProxyMode ...不确定CDI是如何实现的。

其他选项是更多解决方法,然后解决方案 - 也许AlertConfigAction可以传递该信息?

答案 2 :(得分:1)

我知道这个问题很老,但是我遇到了这个问题,从mapstruct 1.2版本开始,您可以使用@Context

来解决它

因此,声明列表的映射需要像这样:

public abstract ArrayList<AlertConfigActionTO> mapList (List<AlertConfigAction> actions, @Context Locale userLanguage);

现在,您只需要添加另一个非抽象映射,如下所示:

public AlertConfigActionTO mapConcrete (AlertConfigAction action, @Context Locale userLanguage){
      return map (action, userLanguage);
}