【JAVA】Dozer 介绍及快速入门教程

article/2025/9/9 15:07:17

文章目录

  • 概述
  • 使用
    • 安装
    • 入门
    • XML 映射
    • 注解映射
    • SpringBoot 集成
  • 结语

概述

Dozer 是什么?

Dozer 是 Java Bean 到 Java Bean 的映射器,他以递归的方式将数据从一个对象复制到另一个对象。

它支持简单的属性映射,复杂类型映射,双向映射,隐式显式的映射,以及递归映射,使用该映射器可以很方便的在项目中进行 pojo、do、vo 之间的转换。

它支持三种映射方式:注解、API、XML。

它是开源的,遵从 Apache 2.0 协议。
 

使用

安装


Maven

如果你的项目使用 maven,添加以下依赖到你的 pom.xml 即可:

<dependency><groupId>net.sf.dozer</groupId><artifactId>dozer</artifactId><version>${dozer.version}</version>
</dependency>

导入 jar 包

如果不使用 Maven,那么需要引入 Dozer 的 jar 包以及其依赖的第三方 jar 包。

  • Dozer
  • Dozer 依赖的第三方 jar 包

 

入门

创建两个 Java Bean 类:

public class User {private String name;private Integer age;private Date birthday;// 省略 setter 和 getter 方法
}
public class UserApiDestinationObject {private String name;private String age;public String birthday;// 重写 toString 方法,方便测试@Overridepublic String toString() {return "UserApiDestinationObject{" +"name='" + name + '\'' +", age='" + age + '\'' +", birthday='" + birthday + '\'' +'}';}// 省略 getter、setter 方法
}

测试:

@Test
public void apiTest() {Mapper mapper = new DozerBeanMapper();User user = new User();user.setName("sid10t.");user.setAge(3);user.setBirthday(new Date());UserApiDestinationObject destinationObject = mapper.map(user, UserApiDestinationObject.class);System.out.println(destinationObject);
}

输出:

UserApiDestinationObject{name='sid10t.', age='3', birthday='Tue Mar 08 10:56:02 CST 2022'}

此时,Dozer 自动完成 User 类到 ApiUserDestination 类的映射。这是 Dozer 的默认映射方式——隐式映射,Dozer 自动的将两个实体类的相同属性名的属性进行映射。如果两个属性的属性名相同,但是类型不同,Dozer 会按照默认的转换规则进行类型的转换,而且不同修饰符的属性也能正常进行映射。

注意:

两个 Java Bean 类都是需要 get 和 set 方法的,上述省略不代表不需要,不然是无法进行映射的;

如果运行时报了这个异常:java.lang.NoClassDefFoundError: org/slf4j/LoggerFactory,则需要导入 slf4j 的 jar 包:

<dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>1.7.22</version>
</dependency>

 

XML 映射

有时候两个 bean 的属性名并不完全相同,这时候通过 Dozer 的隐式映射并不能满足我们的实际需求,这时候就可以通过 Dozer 的另一种映射方式——显示映射进行映射。通过显示映射的方法需要我们自己创建一个 xml 的映射文件来指定两个类的映射关系。这些 xml 配置文件将在运行时由 Dozer 引擎使用。

下面演示 Dozer 的显示映射方式:

新建 UserXmlDestinationObject 类:

public class UserXmlDestinationObject {private String username;private String age;public String dateOfBirth;// 省略 setter 和 getter 方法// 省略 toString 方法
}

在 resource 目录下新建 userMapping.xml 文件,xml 中的配置信息如下:

<?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.nethttp://dozer.sourceforge.net/schema/beanmapping.xsd"><!--全局配置,配置日期的映射格式--><configuration><date-format>yyyy-MM-dd HH:mm:ss</date-format></configuration><mapping wildcard="true"><class-a>User</class-a><class-b>UserXmlDestinationObject</class-b><field><a>name</a><b>username</b></field><field><a>birthday</a><b>dateOfBirth</b></field></mapping></mappings>

一个 mappings 元素包含多个 mapping 元素,每个 mapping 元素都有类映射声明和字段的映射关系。wildcard 属性默认值为 true,这意味着 Dozer 将会尝试映射两个类的每个字段,当该属性设置为 false 时,Dozer 将仅映射显示定义的字段。也可以在 filed 下的 <a> 或者 <b> 节点下添加配置信息,如:<a date-fomat="MM/dd/yyyy HH:mm">,此时字段的配置信息优先级别高于全局配置。

测试:

@Test
public void xmlTest(){List myMappingFiles = new ArrayList();myMappingFiles.add("userMapping.xml");DozerBeanMapper mapper = new DozerBeanMapper();mapper.setMappingFiles(myMappingFiles);User user = new User();user.setName("sid10t.");user.setAge(3);user.setBirthday(new Date());UserXmlDestinationObject destinationObject = mapper.map(user, UserXmlDestinationObject.class);System.out.println(destinationObject);
}

输出:

//<mapping wildcard="true">
UserXmlDestinationObject{username='sid10t.', age='3', dateOfBirth='2022-03-08 12:54:14'}//<mapping wildcard="false">
UserXmlDestinationObject{username='sid10t.', age='null', dateOfBirth='2022-03-08 12:57:09'}

 

注解映射

从版本 5.3.2 开始,Dozer 也开始提供注解支持,使用注解的明显原因是避免在映射代码中复制字段和方法名称,注解可以放在映射类的属性上,从而减少代码量。但是有些情况应该减少使用注解,甚至无法使用注解,如:

  • 你正在映射类时,这些类不在你的控制下,但在库中提供;
  • 映射类非常复杂,而且需要许多配置;

新建 UserAnnotationsObject 类:

public class UserAnnotationsObject {@Mapping("name")public String username;private String age;@Mapping("birthday")private String dateOfBirth;// 省略 getter、setter 方法// 省略 toString 方法
}

注意:dozer 是双向映射的,无论使用 xml 或者 注解的方式进行映射,都只需要配置一个类的映射关系就行。

测试:

@Test
public void annotationsTest(){DozerBeanMapper mapper = new DozerBeanMapper();User user = new User();user.setName("sid10t.");user.setAge(3);user.setBirthday(new Date());UserAnnotationsObject destinationObject = mapper.map(user, UserAnnotationsObject.class);System.out.println(destinationObject);
}

输出:

UserAnnotationsObject{username='sid10t.', age='3', dateOfBirth='Tue Mar 08 13:03:37 CST 2022'}

通过注解的方式,User 类中的 “name” 属性将映射到 UserAnnotationsObject 类中的 username 属性,不用担心 private 修饰符,Dozer 将会自动处理。目前 Dozer 只提供 @Mapping 这一个注解,后续版本可能会添加新的注解,至于现在,你可以混合 api 方式、xml 方式、注解方式进行类的映射。

注意:对于实际应用程序,建议不要在每次映射对象时创建一个新的 Mapper 实例,而是重新使用上次创建的 Mapper 实例,可以把 Mapper 封装成单例模式使用。
 

SpringBoot 集成

自从 6.2.0 版本之后,Dozer 提供了 dozer-spring-boot-starter 用于 Spring Boot 的集成,如果使用 Maven 构建的项目,只需要在 pom.xml 文件中引入如下依赖:

<dependency><groupId>com.github.dozermapper</groupId><artifactId>dozer-spring-boot-starter</artifactId><version>{dozer-version}</version>
</dependency>

新建 DozerMapperConfig 配置类:

@Configuration
public class DozerMapperConfig {@Beanpublic DozerBeanMapperFactoryBean dozerMapper(@Value("classpath:mapping/*.xml") Resource[] resources) throws IOException {DozerBeanMapperFactoryBean dozerBeanMapperFactoryBean = new DozerBeanMapperFactoryBean();dozerBeanMapperFactoryBean.setMappingFiles(resources);return dozerBeanMapperFactoryBean;}}

把 DozerBeanMapperFactoryBean 注入到 IOC 容器中,就能优雅的使用 Dozer 啦,如:

@SpringBootTest
@RunWith(SpringRunner.class)
public class DozerTest {@Autowiredprivate Mapper mapper;@Testpublic void dozerForSbTest(){User user = new User();user.setName("hxy");user.setAge(123);user.setBirthday(new Date());UserXmlDestinationObject destinationObject = mapper.map(user, UserXmlDestinationObject.class);System.out.println(destinationObject);}
}

 

结语

感谢你能看到这里,但是很遗憾的告诉你,Dozer 已经停更了,所以本文也只是简单的介绍了一下,因为项目用到了,就简单的记录一下;

在这里插入图片描述

Dozer 项目当前不再维护了,并且将来很大可能被弃用,然后新用户不建议使用了,老用户也推荐大家迁移到 MapStruct 和 ModelMapper 等类库上面去。

参考:

  • Dozer - 码农教程
  • Dozer 使用小结 - 静默虚空

http://chatgpt.dhexx.cn/article/4hcKtTIi.shtml

相关文章

1.Dubbo教程

转自&#xff1a;https://blog.csdn.net/hellozpc/article/details/78575773 2. 什么是dubbo 2.1. 简介 DUBBO是一个分布式服务框架&#xff0c;致力于提供高性能和透明化的RPC远程服务调用方案&#xff0c;是阿里巴巴SOA服务化治理方案的核心框架&#xff0c;每天为2,000个服务…

黑马程序员Dubbo快速入门,Java分布式框架dubbo教程

分布式系统中的相关概念 &#xff08;一&#xff09;互联网项目架构目标-特点 &#xff08;二&#xff09;互联网项目架构目标-目标 &#xff08;三&#xff09;集群和分布式 &#xff08;四&#xff09;架构演进 Dubbo概述 &#xff08;一&#xff09;dubbo概述 1、dub…

Dubbo快速入门教程

Dubbo入门教程 1 、Dubbo概述 DUbbo架构 2、Dubbo快速入门 Zookeeper 安装传统的模块化开发Duboo入门小案例 修改Service模块代码修改WEB模块代码增加公共的接口模块 3、Dubbo高级特性 dubbo-admin管理平台 dubbo-adminm安装 一、dubbo-admin安装二、dubbo-admin简单使用 序…

dubbo教程总结(springboot+dubbo)

概述 Apache Dubbo 是一款微服务开发框架&#xff0c;它提供了 RPC通信 与 微服务治理 两大关键能力。这意味着&#xff0c;使用 Dubbo 开发的微服务&#xff0c;将具备相互之间的远程发现与通信能力&#xff0c; 同时利用 Dubbo 提供的丰富服务治理能力&#xff0c;可以实现诸…

Dubbo入门详细教程

什么是Dubbo&#xff1f; Dubbo 是阿里开源的远程服务调用(RPC)的分布式框架&#xff0c;提供了 SOA 服务治理方案;它的架构主要有五个角色/核心组件&#xff0c;分为是 Container(容器)、Provider(服务的提供方)、Registry(注册中心)、Consumer(服务的消费方)、Monitor(监控中…

dubbo 教程

&#xfeff;&#xfeff; 先给出阿里巴巴dubbo的主页&#xff1a;http://code.alibabatech.com/wiki/display/dubbo/Home-zh 自己的demo下载地址&#xff1a;http://download.csdn.net/detail/u012049463/6763315 1. Dubbo是什么&#xff1f; Dubbo是一个分布式服务框架&…

dubbo使用教程(可直接应用于企业开发)

本dubbo使用教程基于zookeeper-3.4.9搭建&#xff0c;包含服务提供者DubboProvider、和消费者DubboConsumer&#xff0c;可直接在Tomcat上运行。DubboProvider对外开放2个接口&#xff0c;DubboConsumer调用DubboProvider&#xff0c;并对外暴露HTTP服务。DubboProvider还提供了…

Dubbo快速入门

前言&#xff1a;本文需要建立在博主的环境之上来进行&#xff0c;大家也可以用自己的环境测试一下看能不能行得通&#xff0c;如果可以的话请在下方评论&#xff0c;让更多的人知道 Jdk&#xff1a;11 Springboot版本&#xff1a;2.6.6 Dubbo版本&#xff1a;0.2.0&#xf…

dubbo最全的使用教程

dubbo是阿里一款高性能&#xff0c;轻量级的rpc框架&#xff0c;有两大核心功能&#xff1a;远程服务调用和服务治理。本文主要介绍dubbo的运用。 一&#xff0c;安装注册中心zookeeper 1&#xff0c;为什么需要注册中心&#xff0c;不要能不能远程服务调用 答&#xff1a;可以…

VS2017安装教程(详细版)

1.首先下载好安装包 百度网盘下载链接 链接&#xff1a;https://pan.baidu.com/s/1HW8hrLMazRsBkPvkDHkD1Q?pwdz4jg 提取码&#xff1a;z4jg 2.下载到桌面以管理员身份运行 点击继续 3.进入后更改安装位置&#xff0c;选择安装路径&#xff0c;千万不要安装到C盘 4.改完后…

vs2017秘钥

vs2017 企业版秘钥&#xff1a;NJVYC-BMHX2-G77MM-4XJMR-6Q8QF 专业版秘钥&#xff1a;KBJFW-NXHK6-W4WJM-CRMQB-G3CDH 欢迎使用Markdown编辑器 你好&#xff01; 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章…

自定义 Tabhost 样式

经过了一天的折腾, 在网上也找了不少源码&#xff0c; 但是效果都不是很好&#xff0c;非常长&#xff0c; 最后自己终于写出了一个代码不是很多的Tabhost。 先上图(背景是随便弄的, 所以不怎么样) 首先&#xff0c; 我们要先写一个主xml main.xml 每一个LinearLayout代表…

tabHost 使用方法

近日 学习TabHost的使用 再网上搜不少文章 觉得这篇写的挺好 &#xff01; 出处 &#xff1a;http://www.blogjava.net/freeman1984/archive/2010/10/29/302803.html 查看tabhost的源代码&#xff0c;主要实例变量有&#xff1a; private TabWidget mTabWidget; priv…

android Tabhost控件的使用

Tabhost用来实现如图的效果&#xff1a; 上图的首页、自选、警报是由Tabhost控件来实现的&#xff0c;Tabhost控件中的每个tab其实都是一个Activity&#xff0c;也就是说我创建一个Tabhost&#xff0c;在tabhost中添加tab页就可以实现。 实现方式&#xff1a;1、创建布局文件 …

TabHost详解0

一、TabHost是一个选项卡容器&#xff0c;通过标签页将多个Activity整合到一起。 TabHost的三要素为&#xff1a;TabWidget、FrameLayout、List<TabSpec>。 其主要的使用方式有两种&#xff1a; 1.继承TabActivity&#xff0c;结合对应的xml配置文件导入tab选项内容体 …

TabHost

TabHost的实现有两种方式&#xff0c;第一种继承TabActivity&#xff0c;从TabActivity中用getTabHost()方法获取TabHost。各个Tab中的内容在布局文件中定义就行了。 mainActivity.xml private TabHost myTabHost;Overridepublic void onCreate(Bundle savedInstanceState) {su…

Android初级控件TabHost

TabHost我们都知道是用来实现导航栏布局来切换页面的&#xff0c;这个也是元老级的控件了&#xff0c;现在逐渐被TabLayout,BottomNavigationBar,使用RadioButton自定义。。。等等给取代了。TabHost有个好处就是它添加的是Activity而不像上面那些全部使用Fragment来显示内容。 …

Android中TabHost嵌套TabHost

在嵌套TabHost时&#xff0c;先后遇到了以下情况&#xff1a; 问题1&#xff1a;内部TabHos无显示&#xff0c;只显示了其中的一个Activity&#xff1b; 解决&#xff1a;按下文比对主子TabHos的布局文件和java文件并修改&#xff1b; 问题2&#xff1a;如上所做后&#xff…

Android的Tab与TabHost讲解

在Android应用中&#xff0c;经常会用到TabHost选项卡,可以方便地在不同页面间切换。之前看过网上的一些教程&#xff0c;但大多都是一个形式&#xff0c;看得迷迷糊糊&#xff0c;不能让人很好的理解和学习。所以&#xff0c;在此详细地列出了Tab与TabHost的使用方法&#xff…

Android - TabHost 选项卡功能用法详解

一、实例 二.、TabHost介绍 TabHost组件可以在界面中存放多个选项卡, 很多软件都使用了改组件进行设计; 1. TabHost常用组件 TabWidget : 该组件就是TabHost标签页中上部 或者 下部的按钮, 可以点击按钮切换选项卡; TabSpec : 代表了选项卡界面, 添加一个TabSpec即可添加到TabH…