简体   繁体   English

如何将集合中包含的对象映射到字段,反之亦然? 推土机

[英]How do I map an object contained in a collection to a field and viceversa? Dozer

I'm struggling from two days now with this trouble and I can't get it. 我从现在开始两天都在为这个麻烦而苦苦挣扎,我无法理解。 I have: 我有:

public class ClientBo{
  ...
  List<PersonBo> person;
  ...
}

and

public class ClientVo{
   ...
   PersonVo person;
   ...
}

What I need to do is to configure somehow dozer, so i can map from List of PersonBo to single field PersonVo(Vo an Bo have same field names). 我需要做的是配置推土机,这样我就可以从PersonBo列表映射到单个字段PersonVo(Vo a Bo具有相同的字段名称)。

Dozer has a build in function that converts from collection to single field, but not the other way. 推土机具有内置功能,可将集合从集合转换为单个字段,但不能以其他方式转换。 http://dozer.sourceforge.net/documentation/faq.html#mult-fields-to-single-field http://dozer.sourceforge.net/documentation/faq.html#mult-fields-to-single-field

The only solution that i figured out is : 我发现的唯一解决方案是:

<mapping type="one-way">
    <class-a>...ClientBo</class-a>
    <class-b>...ClientVo</class-b>
    <field>
        <a>person[0]</a>
        <b>person</b>
    </field>
</mapping>
<mapping type="one-way">
    <class-a>...ClientVo</class-a>
    <class-b>...ClientBo</class-b>
    <field custom-converter="mapper.CustomObjectToList">
        <a>person</a>
        <b>person</b>
    </field>
</mapping>

and

   public class CustomObjectToList implements CustomConverter{

        public Object convert(Object existingDestinationFieldValue, Object sourceFieldValue, Class<?> destinationClass, Class<?> sourceClass) {
            if(sourceFieldValue==null)
                return null;

            if(sourceFieldValue instanceof List && ((List<?>) sourceFieldValue).size()>0){
               /* This if is an attempt to get the first element of the
                list and return it as a single field, but id doesn't work*/
                Object o = ((List<?>)sourceFieldValue).get(0);
                return o;


            }else{
                /*Here a single field is put in a List and returned*/
                ArrayList<Object> result = new ArrayList<>();
                result.add(sourceFieldValue);
                return result;
            }
        }
    }

Is there any way so I can remove 有什么办法可以删除

   <mapping type="one-way">
       <class-a>...ClientBo</class-a>
       <class-b>...ClientVo</class-b>
       <field>
            <a>person[0]</a>
            <b>person</b>
       </field>
   </mapping>

and get the job done by a custom converter? 并通过定制转换器完成工作? It should be more generic as possible, so it can fit in similar contexts. 它应该尽可能通用,以便可以在类似的情况下使用。

Thanks! 谢谢!

1. Did you try testing your CustomConverter? 1.您是否尝试过测试CustomConverter?

Because if you tried printing out any of the variables you would have got a ClassCastException , like this: 因为如果您尝试打印任何变量,都将得到ClassCastException ,如下所示:

Exception in thread "main" java.lang.ClassCastException: beans.PersonVo cannot be cast to beans.PersonBo
    at execute.Execute.main(Execute.java:37)

Yes, fields with the same names do get mapped automatically, but in your case you are using a CustomConverter to do the mapping. 是的,具有相同名称的字段会自动映射,但是在您的情况下,您正在使用CustomConverter进行映射。 In other words, Dozer is trusting you to take care of it, so you cannot simply point one Class variable (personVo) to another unrelated Class instance (personBo). 换句话说,Dozer相信您会照顾好它,因此您不能简单地将一个Class变量(personVo)指向另一个不相关的Class实例(personBo)。

2. Correcting the above Exception 2.纠正上述异常

The easiest way to correct the above exception is to to use the setter and getter methods, like you would for any unrelated classes: 纠正上述异常的最简单方法是使用setter和getter方法,就像处理任何不相关的类一样:

public class CustomObjectToList implements CustomConverter{

public Object convert(Object existingDestinationFieldValue, Object sourceFieldValue, Class<?> destinationClass, Class<?> sourceClass) {
    if(sourceFieldValue==null)
        return null;

    if(sourceFieldValue instanceof List && ((List<?>) sourceFieldValue).size()>0){
       /* This if is an attempt to get the first element of the
        list and return it as a single field, but id doesn't work*/
        Object o = ((List<?>)sourceFieldValue).get(0);
        return o;


    }else{
        /*Updated: using a setter and getter*/
        PersonVo source = (PersonVo) sourceFieldValue;
        List<PersonBo> dest  = new ArrayList<PersonBo>();

        PersonBo bo = new PersonBo();
        bo.setName(source.getName());
        dest.add(bo);
        return dest;
    }
}
}

3. Answer to your question 3.回答你的问题

To do away with one-way mapping and use only a CustomConverter, you could use the following: 要取消单向映射并仅使用CustomConverter,可以使用以下方法:

dozer XML: 推土机XML:

<!-- <mapping type="one-way">
    <class-a>beans.ClientBo</class-a>
    <class-b>beans.ClientVo</class-b>
    <field>
        <a>person[0]</a>
        <b>person</b>
    </field>
</mapping> -->
<mapping>
    <class-a>beans.ClientVo</class-a>
    <class-b>beans.ClientBo</class-b>
    <field custom-converter="converter.CustomObjectToList">
        <a>person</a>
        <b>person</b>
    </field>
</mapping>

CustomConverter: CustomConverter:

public class CustomObjectToList implements CustomConverter{

public Object convert(Object existingDestinationFieldValue, Object sourceFieldValue, Class<?> destinationClass, Class<?> sourceClass) {
        if(sourceFieldValue==null)
            return null;

        if(sourceFieldValue instanceof PersonVo){
            PersonVo source = (PersonVo) sourceFieldValue;
            List<PersonBo> dest  = new ArrayList<PersonBo>();

            PersonBo bo = new PersonBo();
            bo.setName(source.getName());
            dest.add(bo);
            return dest;

        }else if (sourceFieldValue instanceof List<?>){
            List<PersonBo> source = (List<PersonBo>) sourceFieldValue;

            PersonVo dest = new PersonVo();
            dest.setName(source.get(0).getName());
            return dest;
        }
        else {
            throw new MappingException("Converter TestCustomConverter "
                + "used incorrectly. Arguments passed in were:"
                + existingDestinationFieldValue + " and " + sourceFieldValue);
          }
    }
}

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

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