简体   繁体   English

Dozer String to enum mapping

[英]Dozer String to enum mapping

I have such enum: 我有这样的枚举:

public enum PartnershipIndicator {
    VENDOR("VENDOR"), COPARTNER("COPARTNER"), BUYER("BUYER");

    String code;

    private PartnershipIndicator(String code) {
        this.code = code;
    }

    public String getCode() {
        return code;
    }

    public static PartnershipIndicator valueOfCode(String code) {
        for (PartnershipIndicator status : values()) {
            if (status.getCode().equals(code)) {
                return status;
            }
        }
        throw new IllegalArgumentException(
            "Partnership status cannot be resolved for code " + code);
    }

    @Override
    public String toString() {
        return code;
    }
}

I need to convert it to String and vice versa. 我需要将其转换为String,反之亦然。 Now, it is done by custom converter. 现在,它由自定义转换器完成。 But i want to do it via dozer mappings (if it is possible). 但我想通过推土机映射(如果有可能)这样做。 If i do not write any mappings to the dozer confing, i get 如果我不写任何映射到推土机confing,我得到

org.dozer.MappingException: java.lang.NoSuchMethodException: by.dev.madhead.demo.test_java.model.PartnershipIndicator.<init>()

exception. 例外。 I cannot add default public constructor to enum, as it is not possible. 我不能将默认的公共构造函数添加到枚举中,因为它是不可能的。 So, i wrote a trick with internal code and valueOfCode() / toString(). 所以,我用内部代码和valueOfCode()/ toString()写了一个技巧。 It does not work. 这是行不通的。 Then, i've mapped it in dozer config: 然后,我在dozer配置中映射它:

<mapping>
    <class-a>java.lang.String</class-a>
    <class-b create-method="valueOfCode">by.dev.madhead.demo.test_java.model.PartnershipIndicator</class-b>
</mapping>

It does not work. 这是行不通的。 I tried valueOfCode(), one-way mappings. 我尝试了valueOfCode(),单向映射。 Nothing works. 什么都行不通。 Enum to String conversion does not work too, i get empty Strings. Enum to String转换也不起作用,我得到空字符串。 Any ideas? 有任何想法吗?

Not sure if this is still an issue, but maybe help for anyone searching. 不确定这是否仍然是一个问题,但也许对任何搜索的人都有帮助。 But here is implemented solution to this: 但是这里实现了解决方案:

@Override
public Object convert(Object destination, Object source, Class<?> destinationClass,    Class<?> sourceClass) {
    if(source == null)
        return null;
    if(destinationClass != null){
        if(destinationClass.getSimpleName().equalsIgnoreCase("String")){
            return this.getString(source);
        }else if( destinationClass.isEnum()){

            return this.getEnum(destinationClass, source);

        }else{
            throw new MappingException(new StrBuilder("Converter ").append(this.getClass().getSimpleName())
                       .append(" was used incorrectly. Arguments were: ")
                       .append(destinationClass.getClass().getName())
                       .append(" and ")
                       .append(source).toString());
        }
    }
    return null;
}

private Object getString(Object object){
    String value = object.toString();
    return value;
}
private Object getEnum(Class<?> destinationClass, Object source){
    Object enumeration = null;

    Method [] ms = destinationClass.getMethods();
    for(Method m : ms){
        if(m.getName().equalsIgnoreCase("valueOf")){
            try {
                enumeration = m.invoke( destinationClass.getClass(), (String)source);
            }
            catch (IllegalArgumentException e) {
                e.printStackTrace();
            }
            catch (IllegalAccessException e) {
                e.printStackTrace();
            }
            catch (InvocationTargetException e) {
                e.printStackTrace();
            }
            return enumeration;
        }
    }
    return null;
}

The StrBuilder class when building the exception message is from the apaches common-lang libs. 构建异常消息时的StrBuilder类来自apaches common-lang libs。 But other than that a simple reflection to solve this issue. 但除此之外,还有一个简单的反思来解决这个问题。 Just add to a class that implements CustomConverter and then in your dozer mapping xml file add the following configuration: 只需添加到实现CustomConverter的类,然后在您的dozer映射xml文件中添加以下配置:

<configuration>
    <custom-converters>
        <converter type="com.yourcompany.manager.utils.dozer.converters.EnumStringBiDirectionalDozerConverter">
            <class-a>java.lang.Enum</class-a>
            <class-b>java.lang.String</class-b>
        </converter>
    </custom-converters>
</configuration>

Note that you can only list a configuration once between all of your mapping files (if you have multiple) otherwise dozer will complain. 请注意,您只能在所有映射文件之间列出一次配置(如果您有多个),否则dozer会抱怨。 What I typically do is place my custom converter configurations in one file for simplicity. 我通常做的是将我的自定义转换器配置放在一个文件中以简化操作。 Hope this helps! 希望这可以帮助!

There isn't a default enum to String mapping in Dozer. Dozer中没有String映射的默认枚举。 See Data type conversion from Dozer docs. 请参阅Dozer文档中的数据类型转换 So you have two options: 所以你有两个选择:

  • You can write a custom converter that uses generics to handle any enum. 您可以编写一个使用泛型来处理任何枚举的自定义转换器。
  • Or, you could submit a patch to Dozer to add enum<->String mapping to the default mappings. 或者,您可以向Dozer提交补丁,以将枚举< - > String映射添加到默认映射。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM