当前位置: 首页 > 知识库问答 >
问题:

未为字段调用Dozer java API设置的自定义转换器

琴俊良
2023-03-14

我正在使用Dozer框架在JavaBean之间进行转换。我想使用Dozer的JavaApi而不是XML创建我的映射,以便能够操作和配置我的自定义转换器。

如果我使用下面代码中的备选方案1运行转换器,并删除xml文件中的alt 2映射,则转换工作正常,并调用自定义转换器。如果我使用备选方案2运行转换器-使用java API进行映射,则映射程序永远不会调用我的转换器。bean被转换,但相同类型的嵌套字段被忽略,在下面的代码中,父字段在转换后为null。

Organization org = ...init organization....
OrganizationDto orgDto = new MyConverter().convert(organization, OrganizationDto.class);
assertEquals(3,orgDto.getParent().getX()) //Fails due to NPE since parent field is not copied

我知道java API不支持类级自定义转换器,但字段级转换器看起来是受支持的,因为它是在java映射API示例中提供的。

(我也知道,推土机的作者建议将推土机作为一个单独的装置使用,但这不包括在下面的示例中。)

有什么提示吗?

public class OrganizationDto {
   int x;
   OrganizationDto parent ;
   // getters and setters....
}

public class Organization {
   int x;
   Organization parent ;
   // getters and setters....
}


public class MyConverter{


private DozerBeanMapper mapper = null;

public MyConverter() {
        mapper = new DozerBeanMapper();
        // Alternative 1 - works 
//          List<String> myMappingFiles = new ArrayList<String>();
//          myMappingFiles.add("myBeanMappings.xml");
//          mapper.setMappingFiles(myMappingFiles);

        // Alternative 2 - does not work
        Map<String,CustomConverter> customConvertersWithId = new HashMap<String, CustomConverter>();
        customConvertersWithId.put("OrganizationDetailsConverter", new OrganizationDetailsConverter());
        mapper.setCustomConvertersWithId(customConvertersWithId);

        // Also tried variants using
        //mapper.setCustomConverters(Collections.<CustomConverter> singletonList(new OrganizationDetailsConverter()));

        BeanMappingBuilder builder = new BeanMappingBuilder() {
            protected void configure() {
                mapping(OrganizationDto.class, Organization.class)
                .fields("parent",
                        "parent",
                        customConverterId("OrganizationDetailsConverter"));
                }
            };          
            mapper.addMapping(builder);
    }

    public <T, S> T convert(S fromBean, Class<T> toBeanClass) {
    return mapper.map(fromBean, toBeanClass);
    }

}



<?xml version="1.0" encoding="UTF-8"?>
<mappings xmlns="http://dozer.sourceforge.net" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://dozer.sourceforge.net
      http://dozer.sourceforge.net/schema/beanmapping.xsd">
    <mapping>
        <class-a>foo.OrganizationDto</class-a>
        <class-b>foo.Organization</class-b>
        <field custom-converter="foo.OrganizationDetailsConverter">
            <a>parent</a>
            <b>parent</b>
        </field>
    </mapping>
</mappings>

共有1个答案

衡子安
2023-03-14
public class DozerMap {

   public static class ContainerA {
      private A a;
      public A getA() { return a; }
      public void setA(A a) { this.a = a; }
   }

   public static class ContainerB {
      private B b;
      public B getB() { return b; }
      public void setB(B b) { this.b = b; }
   }

   private static class A { };

   private static class B { };

   static class ConverterImpl extends DozerConverter<A, B> {

      ConverterImpl() {
         super(A.class, B.class);
      }

      @Override
      public B convertTo(A source, B destination) {
         Logger.getAnonymousLogger().info("Invoked");
         return destination;
      }

      @Override
      public A convertFrom(B source, A destination) {
         Logger.getAnonymousLogger().info("Invoked");
         return destination;
      }
   }

   public static void main(String[] args) {

      DozerBeanMapper mapper = new DozerBeanMapper();
      mapper.setCustomConverters(Collections.<CustomConverter> singletonList(new ConverterImpl()));
      BeanMappingBuilder foo = new BeanMappingBuilder() {

         @Override
         protected void configure() {
            mapping(ContainerA.class, ContainerB.class).fields("a", "b", FieldsMappingOptions.customConverter(ConverterImpl.class));
         }
      };
      mapper.setMappings(Collections.singletonList(foo));
      ContainerA containerA = new ContainerA();
      containerA.a = new A();
      ContainerB containerB = mapper.map(containerA, ContainerB.class);
   }
}
 类似资料:
  • 当我调用binder.setBean(vo)时,试图实现一个从textfield到自定义数据类型的自定义转换器并将同一个字段与binder绑定,它抛出了给定的异常 java.lang.ClassCastException:类com.demo.vo。DemoVO不能强制转换为类java.lang.String(com.demo.vo.DemoVO位于加载程序“deployment.demo.ear”

  • 我在修改我安装的WordPress流行帖子插件时遇到了一些问题。 它可以选择从自定义字段获取缩略图,我已将其输入为“image_facebook”。但是缩略图没有显示。 在检查代码时,我发现imgsrc有post id而不是返回图像URL。 我已经把问题缩小到我安装的另一个插件http://wordpress.org/plugins/advanced-custom-fields/ 当它处于活动状态

  • 我正在使用Apache PDFBox来读取一个可填充的PDF表单,并根据一些数据填充字段。我使用下面的代码(根据其他SO答案的建议)来获得默认的外观字符串并更改它(正如您在下面看到的,如果字段名是“field1”,我将字体大小从10更改为12。 如何加粗字段?是否有关于/HELV 10 Tf 0 g的排列顺序的文件?我需要设置什么来粗体字段? 如果我理解正确,有14种基本字体,我可以在PDFBox

  • 我正在尝试将添加到 Devise,但是当我注册一个新用户时,当我推送提交时它会中断。 我已确保运行< code>rake db:migrate并重新启动了我的服务器,但我得到了以下错误: ActiveRecord::StatementInvalid in Devise::RegistrationsController#create NoMethodError: nil:NilClass 的未定义方

  • 我有一个名为Metric的简单Java类,它有两个字段:MetricType和value:

  • 介绍 model 参考文档已经介绍了如何使用 Django 的标准字段类;例如 CharField, DateField,等等。对于很多应用来说,这些类足够用了。 但是在某些情况下, 你所用的Django 不具备你需要的某些精巧功能,或是你想使用的字段与 Django 自带字段完全不同。 Django 内置的字段类型并不能覆盖所有可能遇到的数据库的列类型,仅仅是些普通的字段类型,例如VARCHAR