Dozer映射中的常量

7
有人知道如何使用Dozer将常量值放入属性中吗?在Dozer的文档中没有找到相关信息。
5个回答

3

我不是完全明白您的意思 - 如果您想让Dozer在将BeanA映射到BeanB时始终使用常量填充BeanB.someField?

您可能需要为此映射注册自定义转换器


是的,那正是我想要的。我在想是否有可能直接完成而不需要自定义转换器。 - Pau
我相信你唯一的方法是使用自定义转换或在调用Dozer时手动处理它。Dozer实际上只处理从一个bean到另一个bean的映射,不允许插入其他逻辑(这是有意义的,因为它并不打算做到那样)。 - matt b

2
如何利用事件机制呢?您可以注册一个监听器,在您的监听器的 mappingFinished() 中设置值。有关详细信息,请参阅 Dozer文档中的事件。当然,您需要使用某种形式的 if ... instanceof 条件来保护设置代码。

这对我非常有效,尽管我将我的钩子放在 preWritingDestinationValue 上,因此这些值充当默认值,而不是覆盖已经映射的内容。 - tzrlk

1
一种可能的实现方式是:


public class ConstantsCustomConvertor implements ConfigurableCustomConverter{

    private String pararamter;
    @Override
    public Object convert(Object existingDestinationFieldValue, Object sourceFieldValue, Class<?> destinationClass, Class<?> sourceClass) {     
        return pararamter;
    }

    @Override
    public void setParameter(String parameter) {
        this.pararamter = parameter;

    }
}

例子:

<field custom-converter-param="CONTANT_VALUE" custom-converter="org.yourcompany.ConstantsCustomConvertor">
    <a>a-class-dummyfieldname</a>
    <b>b-class-fieldname</b>
</field>    

这个自定义转换器假设b-class-fieldname是字符串类型。


可能更清晰地将其重命名为“OneWayConstantConverter”。如果尝试进行双向映射(即不是单向映射),也可以考虑抛出异常。 - Steve Chambers
我现在已经发布了一个答案,以类似的方式完成它,但确保它仅用于单向映射,并使用class作为源字段来消除需要虚拟字段的需求。 - Steve Chambers

1

最近的Dozer版本使这变得更容易。您可以指定自定义转换器,还可以为给定字段映射指定该转换器的参数。创建一个单一的“ConstantConverter”应该是微不足道的,它将始终将输入参数放入输出字段中。


1
实际上,使用自定义转换器并不容易。您要么需要为包含该字段的整个类编写转换器(这违背了首先使用Dozer的目的),要么需要使用丑陋的解决方案来将转换器附加到单个字段上(而该字段仅存在于其中一个类中)。尽管如此,在某些情况下这可能是一个好方法(取决于对象的结构方式)。 - Lajcik

0

假设您只想进行单向映射,以下内容适用于字符串常量:

/**
 * Custom one-way Dozer converter mapping to constant string value specified by a parameter.
 */
public class OneWayStringConstantConverter extends DozerConverter<Class, String> {

    public OneWayBooleanConstantConverter() {
        super(Class.class, String.class);
    }

    @Override
    public String convertTo(Class aClass, String aString) {
        // Return constant value specified by the parameter (source is ignored)
        return getParameter();
    }

    @Override
    public Class convertFrom(String aString, Class aClass) {
        throw new UnsupportedOperationException(
                "OneWayStringConstantConverter should only be used in one-way mappings");
    }
}

...被调用者:

  <field custom-converter="full.path.to.OneWayStringConstantConverter"
         custom-converter-param="My constant string value">
     <a>class</a> <!-- Source not used: Converter only sets target of a one-way mapping -->
     <b>targetField</b>
  </field>

建议使用class值作为虚拟的“源字段”,因为它尚未被使用,而getClass()方法保证存在于任何对象上。

我需要对布尔值进行操作,所以使用了这个:

/**
 * Custom one-way Dozer converter which maps to the constant boolean value (true or false)
 * specified by a parameter.
 */
public class OneWayBooleanConstantConverter extends DozerConverter<Class, Boolean> {

    public OneWayBooleanConstantConverter() {
        super(Class.class, Boolean.class);
    }

    @Override
    public Boolean convertTo(Class aClass, Boolean aBoolean) {
        // Return constant boolean value specified by the parameter (source is ignored)
        return Boolean.parseBoolean(getParameter());
    }

    @Override
    public Class convertFrom(Boolean aBoolean, Class aClass) {
        throw new UnsupportedOperationException(
                "OneWayBooleanConstantConverter should only be used in one-way mappings");
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接