You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Dozer 5.2.0映射继承类时自定义转换器调用异常问题

解决Dozer 5.2.0中子类转换器未被优先调用的问题

这个问题我之前也碰到过,Dozer 5.2.0的转换器匹配逻辑确实会出现这种父类转换器“抢”了子类转换器的情况,具体原因和解决办法如下:

问题根源

Dozer在查找匹配的转换器时,默认会按照**“宽泛匹配”**的逻辑遍历配置的转换器列表:只要源对象是class-a的实例(包括子类)、目标对象是class-b的实例(包括子类),就会使用该转换器。因为B是A的子类,所以当你先配置了A-C的转换器时,Dozer会先匹配到这个宽泛的父类转换器,而不会继续往后找更精确的B-C转换器。

解决方案

1. 调整转换器的配置顺序(最简单的办法)

把子类的转换器配置放在父类转换器的前面,因为Dozer是按配置的先后顺序查找转换器的,先找到符合条件的就会直接使用。这样当转换B到C时,会先匹配到BDozerConvertor,而不会走到ADozerConvertor。

修改后的配置如下:

<!-- 先配置子类B的转换器 -->
<converter type="BDozerConvertor">
  <class-a>B</class-a>
  <class-b>C</class-b>
</converter>
<!-- 再配置父类A的转换器 -->
<converter type="ADozerConvertor">
  <class-a>A</class-a>
  <class-b>C</class-b>
</converter>

2. 重写转换器的isApplicable方法(更严谨的控制)

如果调整顺序后还是有问题,或者你想要更精确地控制转换器的适用范围,可以在自定义转换器中重写isApplicable方法,明确指定该转换器只处理精确的类型匹配,拒绝父类/子类的宽泛匹配。

以BDozerConvertor为例:

public class BDozerConvertor extends DozerConverter<B, C> {
    // 构造方法指定精确的源类型和目标类型
    public BDozerConvertor() {
        super(B.class, C.class);
    }

    // 重写isApplicable,只匹配精确的B->C转换
    @Override
    public boolean isApplicable(Object source, Object destination, Class<?> sourceClass, Class<?> destClass) {
        return sourceClass == B.class && destClass == C.class;
    }

    // 实现具体的转换逻辑
    @Override
    public C convertTo(B source, C destination) {
        // 你的B转C逻辑
        return destination;
    }

    @Override
    public B convertFrom(C source, B destination) {
        // 你的C转B逻辑
        return destination;
    }
}

这样配置后,BDozerConvertor只会处理B类型到C类型的精确转换,不会再被父类类型的转换触发,同时ADozerConvertor依然可以处理A类型(非B子类的A实例)到C的转换。

内容的提问来源于stack exchange,提问作者Dorin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 10:02:16