jaxb 映射 空字段
Dozer是开放源代码( Apache 2许可 )“ Java Bean到Java Bean映射器,可将数据从一个对象递归复制到另一个对象”。 正如从其主页上的描述所描述的那样,它用于映射两个JavaBeans实例,以在实例之间进行自动数据复制。 尽管这些可以是多种JavaBeans实例中的任何一种,但我将重点介绍如何使用Dozer将JAXB生成的对象映射到“业务数据对象”(有时称为“域对象”)。
在使用Java XML绑定体系结构 ( JAXB )的Java应用程序中,开发人员编写特定的业务或域对象供应用程序本身使用,而仅使用JAXB生成的对象进行读取(解组)和写入操作,这是很常见的 。 (编组)XML。 尽管将JAXB生成的对象本身用作业务/域对象具有一定的吸引力 ( DRY ),但是这种方法存在一些缺点。 JAXB生成的类没有toString() , equals(Object)或hashCode()实现,这使得这些生成的类不适合用于许多类型的集合中,除身份比较之外不适合比较,并且不便于记录其内容。 在对生成的类进行生成后,对其进行手动编辑很麻烦,并且即使对源XSD进行了很小的更改,也不利于再次生成JAXB类。
尽管可以使用JAXB2 Basics来确保JAXB生成的类具有在集合中使用,在比较中使用以及记录其内容所需的一些常用方法,但是使用JAXB生成的类作为domain /业务对象是业务逻辑与XSD紧密结合的必然结果。 XSD中的模式更改(例如版本更新)通常会导致通过JAXB从该XSD生成的类的包结构不同。 然后,不同的包结构将强制所有导入那些JAXB生成的类的代码来更改其导入语句。 对XSD的内容更改可能会产生更大的影响,从而影响JAXB类的get / set方法,如果将JAXB类用于域/业务对象,则该方法会散布在整个应用程序中。
假设决定不使用JAXB生成的类作为业务/域类,有多种方法可以通过代码或配置中描述的“映射层”将生成的JAXB类映射到定义业务/域对象的类。 为了演示两个基于代码的映射层的实现并演示基于Dozer的映射层,我介绍了JAXB生成的类和定制构建的业务/域类的一些简单示例。
本文的示例的第一部分是XSD,将从中指示JAXB'x xjc到通用类,以将其编组到该XSD所描述的XML或从该XSD所描述的XML解组。 接下来显示的XSD定义了一个Person
元素,该元素可以具有嵌套的MailingAddress
和ResidentialAddress
元素以及两个用于名字和姓氏的String属性。 还要注意,主要名称空间是http://marxsoftware.blogspot.com/,JAXB将使用它来确定从该XSD生成的类的Java包层次结构。
人格
<?xml version="1.0"?>
<xs:schema version="1.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:marx="http://marxsoftware.blogspot.com/"
targetNamespace="http://marxsoftware.blogspot.com/"
elementFormDefault="qualified">
<xs:element name="Person" type="marx:PersonType" />
<xs:complexType name="PersonType">
<xs:sequence>
<xs:element name="MailingAddress" type="marx:AddressType" />
<xs:element name="ResidentialAddress" type="marx:AddressType" minOccurs="0" />
</xs:sequence>
<xs:attribute name="firstName" type="xs:string" />
<xs:attribute name="lastName" type="xs:string" />
</xs:complexType>
<xs:complexType name="AddressType">
<xs:attribute name="streetAddress1" type="xs:string" use="required" />
<xs:attribute name="streetAddress2" type="xs:string" use="optional" />
<xs:attribute name="city" type="xs:string" use="required" />
<xs:attribute name="state" type="xs:string" use="required" />
<xs:attribute name="zipcode" type="xs:string" use="required" />
</xs:complexType>
</xs:schema>
当针对上述XSD执行xjc (Oracle JDK随附的JAXB编译器)时,在com / blogspot / marxsoftware目录(从XSD的名称空间派生)中生成以下四个类: AddressType.java
, PersonType.java
, ObjectFactory.java
和package-info.java
。
接下来的两个代码清单是JAXB生成的两个主要感兴趣的类( PersonType.java
和AddressType.java
)。 在此处显示它们的主要目的是提醒他们,它们缺少我们经常需要我们的业务/域类拥有的方法。
JAXB生成的PersonType.java
//
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2
// See http://java.sun.com/xml/jaxb
// Any modifications to this file will be lost upon recompilation of the source schema.
// Generated on: 2013.12.03 at 11:44:32 PM MST
//
package com.blogspot.marxsoftware;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;
/**
* <p>Java class for PersonType complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* <complexType name="PersonType">
* <complexContent>
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* <sequence>
* <element name="MailingAddress" type="{http://marxsoftware.blogspot.com/}AddressType"/>
* <element name="ResidentialAddress" type="{http://marxsoftware.blogspot.com/}AddressType" minOccurs="0"/>
* </sequence>
* <attribute name="firstName" type="{http://www.w3.org/2001/XMLSchema}string" />
* <attribute name="lastName" type="{http://www.w3.org/2001/XMLSchema}string" />
* </restriction>
* </complexContent>
* </complexType>
* </pre>
*
*
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "PersonType", propOrder = {
"mailingAddress",
"residentialAddress"
})
public class PersonType {
@XmlElement(name = "MailingAddress", required = true)
protected AddressType mailingAddress;
@XmlElement(name = "ResidentialAddress")
protected AddressType residentialAddress;
@XmlAttribute(name = "firstName")
protected String firstName;
@XmlAttribute(name = "lastName")
protected String lastName;
/**
* Gets the value of the mailingAddress property.
*
* @return
* possible object is
* {@link AddressType }
*
*/
public AddressType getMailingAddress() {
return mailingAddress;
}
/**
* Sets the value of the mailingAddress property.
*
* @param value
* allowed object is
* {@link AddressType }
*
*/
public void setMailingAddress(AddressType value) {
this.mailingAddress = value;
}
/**
* Gets the value of the residentialAddress property.
*
* @return
* possible object is
* {@link AddressType }
*
*/
public AddressType getResidentialAddress() {
return residentialAddress;
}
/**
* Sets the value of the residentialAddress property.
*
* @param value
* allowed object is
* {@link AddressType }
*
*/
public void setResidentialAddress(AddressType value) {
this.residentialAddress = value;
}
/**
* Gets the value of the firstName property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getFirstName() {
return firstName;
}
/**
* Sets the value of the firstName property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setFirstName(String value) {
this.firstName = value;
}
/**
* Gets the value of the lastName property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getLastName() {
return lastName;
}
/**
* Sets the value of the lastName property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setLastName(String value) {
this.lastName = value;
}
}
JAXB生成的AddressType.java
//
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2
// See http://java.sun.com/xml/jaxb
// Any modifications to this file will be lost upon recompilation of the source schema.
// Generated on: 2013.12.03 at 11:44:32 PM MST
//
package com.blogspot.marxsoftware;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlType;
/**
* <p>Java class for AddressType complex type.
*
* <p>The following schema fragment specifies the expected content contained within this class.
*
* <pre>
* <complexType name="AddressType">
* <complexContent>
* <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
* <attribute name="streetAddress1" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
* <attribute name="streetAddress2" type="{http://www.w3.org/2001/XMLSchema}string" />
* <attribute name="city" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
* <attribute name="state" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
* <attribute name="zipcode" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
* </restriction>
* </complexContent>
* </complexType>
* </pre>
*
*
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "AddressType")
public class AddressType {
@XmlAttribute(name = "streetAddress1", required = true)
protected String streetAddress1;
@XmlAttribute(name = "streetAddress2")
protected String streetAddress2;
@XmlAttribute(name = "city", required = true)
protected String city;
@XmlAttribute(name = "state", required = true)
protected String state;
@XmlAttribute(name = "zipcode", required = true)
protected String zipcode;
/**
* Gets the value of the streetAddress1 property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getStreetAddress1() {
return streetAddress1;
}
/**
* Sets the value of the streetAddress1 property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setStreetAddress1(String value) {
this.streetAddress1 = value;
}
/**
* Gets the value of the streetAddress2 property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getStreetAddress2() {
return streetAddress2;
}
/**
* Sets the value of the streetAddress2 property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setStreetAddress2(String value) {
this.streetAddress2 = value;
}
/**
* Gets the value of the city property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getCity() {
return city;
}
/**
* Sets the value of the city property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setCity(String value) {
this.city = value;
}
/**
* Gets the value of the state property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getState() {
return state;
}
/**
* Sets the value of the state property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setState(String value) {
this.state = value;
}
/**
* Gets the value of the zipcode property.
*
* @return
* possible object is
* {@link String }
*
*/
public String getZipcode() {
return zipcode;
}
/**
* Sets the value of the zipcode property.
*
* @param value
* allowed object is
* {@link String }
*
*/
public void setZipcode(String value) {
this.zipcode = value;
}
}
在JAXB生成的对象和自定义编写的业务/域对象之间复制数据的一种常见而直接的策略是使用一个对象的“ get”方法,并将其返回值传递给另一个对象的“ set”方法。 例如,在将XML解组/读取到应用程序的过程中,可以将JAXB生成的对象上调用的“ get”方法的结果传递给业务/域对象的“ set”方法。 相反,通过将域/业务对象上的“ get”方法的结果传递给JAXB生成的对象的相应“ set”方法,可以轻松完成编组/编写XML。 下一个代码清单用于PersonCoverter.java
并说明了此方法的一种实现。
PersonConverter.java
package dustin.examples.dozerdemo;
import com.blogspot.marxsoftware.AddressType;
import com.blogspot.marxsoftware.ObjectFactory;
import com.blogspot.marxsoftware.PersonType;
import dustin.examples.Address;
import dustin.examples.Person;
/**
* Static functions for converting between JAXB-generated objects and domain
* objects.
*
* @author Dustin
*/
public class PersonConverter
{
/**
* Extract business object {@link dustin.examples.Person} from the JAXB
* generated object {@link com.blogspot.marxsoftware.PersonType}.
*
* @param personType JAXB-generated {@link com.blogspot.marxsoftware.PersonType}
* from which to extract {@link dustin.examples.Person} object.
* @return Instance of {@link dustin.examples.Person} based on the provided
* {@link com.blogspot.marxsoftware.PersonType}.
*/
public static Person extractPersonFromPersonType(final PersonType personType)
{
final String lastName = personType.getLastName();
final String firstName = personType.getFirstName();
final Address residentialAddress =
extractAddressFromAddressType(personType.getResidentialAddress());
final Address mailingAddress =
extractAddressFromAddressType(personType.getMailingAddress());
return new Person(lastName, firstName, residentialAddress, mailingAddress);
}
/**
* Extract business object {@link dustin.examples.Address} from the JAXB
* generated object {@link com.blogspot.marxsoftware.AddressType}.
*
* @param addressType JAXB-generated {@link com.blogspot.marxsoftware.AddressType}
* from which to extract {@link dustin.examples.Address} object.
* @return Instance of {@link dustin.examples.Address} based on the provided
* {@link com.blogspot.marxsoftware.AddressType}.
*/
public static Address extractAddressFromAddressType(final AddressType addressType)
{
return new Address(
addressType.getStreetAddress1(), addressType.getStreetAddress2(),
addressType.getCity(), addressType.getState(), addressType.getZipcode());
}
/**
* Extract an instance of {@link com.blogspot.marxsoftware.PersonType} from
* an instance of {@link dustin.examples.Person}.
*
* @param person Instance of {@link dustin.examples.Person} from which
* instance of JAXB-generated {@link com.blogspot.marxsoftware.PersonType}
* is desired.
* @return Instance of {@link com.blogspot.marxsoftware.PersonType} based on
* provided instance of {@link dustin.examples.Person}.
*/
public static PersonType extractPersonTypeFromPerson(final Person person)
{
final ObjectFactory objectFactory = new ObjectFactory();
final AddressType residentialAddressType =
extractAddressTypeFromAddress(person.getResidentialAddress());
final AddressType mailingAddressType =
extractAddressTypeFromAddress(person.getMailingAddress());
final PersonType personType = objectFactory.createPersonType();
personType.setLastName(person.getLastName());
personType.setFirstName(person.getFirstName());
personType.setResidentialAddress(residentialAddressType);
personType.setMailingAddress(mailingAddressType);
return personType;
}
/**
* Extract an instance of {@link com.blogspot.marxsoftware.AddressType} from
* an instance of {@link dustin.examples.Address}.
*
* @param address Instance of {@link dustin.examples.Address} from which
* instance of JAXB-generated {@link com.blogspot.marxsoftware.AddressType}
* is desired.
* @return Instance of {@link com.blogspot.marxsoftware.AddressType} based on
* provided instance of {@link dustin.examples.Address}.
*/
public static AddressType extractAddressTypeFromAddress(final Address address)
{
final ObjectFactory objectFactory = new ObjectFactory();
final AddressType addressType = objectFactory.createAddressType();
addressType.setStreetAddress1(address.getStreetAddress1());
addressType.setStreetAddress2(address.getStreetAddress2());
addressType.setCity(address.getMunicipality());
addressType.setState(address.getState());
addressType.setZipcode(address.getZipCode());
return addressType;
}
}
最后的代码清单演示了一种通用的第三方类方法,用于在JAXB生成的对象和域/业务对象之间双向复制数据。 另一种方法是将这种复制功能构建到域/业务对象本身中。 这在PersonPlus.java
和AddressPlus.java
两个代码清单中PersonPlus.java
,它们是先前介绍的Person.java
和Address.java
版本,并添加了对从JAXB生成的对象复制数据的支持。 为了方便起见,我在toString
实现之后将新方法添加到类的底部。
PersonPlus.java
package dustin.examples;
import com.blogspot.marxsoftware.ObjectFactory;
import com.blogspot.marxsoftware.PersonType;
import java.util.Objects;
/**
* Person class enhanced to support copying to/from JAXB-generated PersonType.
*
* @author Dustin
*/
public class PersonPlus
{
private String lastName;
private String firstName;
private AddressPlus mailingAddress;
private AddressPlus residentialAddress;
public PersonPlus(
final String newLastName,
final String newFirstName,
final AddressPlus newResidentialAddress,
final AddressPlus newMailingAddress)
{
this.lastName = newLastName;
this.firstName = newFirstName;
this.residentialAddress = newResidentialAddress;
this.mailingAddress = newMailingAddress;
}
public String getLastName()
{
return this.lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getFirstName()
{
return this.firstName;
}
public void setFirstName(String firstName)
{
this.firstName = firstName;
}
public AddressPlus getMailingAddress()
{
return this.mailingAddress;
}
public void setMailingAddress(AddressPlus mailingAddress)
{
this.mailingAddress = mailingAddress;
}
public AddressPlus getResidentialAddress()
{
return this.residentialAddress;
}
public void setResidentialAddress(AddressPlus residentialAddress)
{
this.residentialAddress = residentialAddress;
}
@Override
public int hashCode()
{
int hash = 3;
hash = 19 * hash + Objects.hashCode(this.lastName);
hash = 19 * hash + Objects.hashCode(this.firstName);
hash = 19 * hash + Objects.hashCode(this.mailingAddress);
hash = 19 * hash + Objects.hashCode(this.residentialAddress);
return hash;
}
@Override
public boolean equals(Object obj)
{
if (obj == null)
{
return false;
}
if (getClass() != obj.getClass())
{
return false;
}
final PersonPlus other = (PersonPlus) obj;
if (!Objects.equals(this.lastName, other.lastName))
{
return false;
}
if (!Objects.equals(this.firstName, other.firstName))
{
return false;
}
if (!Objects.equals(this.mailingAddress, other.mailingAddress))
{
return false;
}
if (!Objects.equals(this.residentialAddress, other.residentialAddress))
{
return false;
}
return true;
}
@Override
public String toString() {
return "PersonPlus{" + "lastName=" + lastName + ", firstName=" + firstName
+ ", mailingAddress=" + mailingAddress + ", residentialAddress="
+ residentialAddress + '}';
}
/**
* Provide a JAXB-generated instance of {@link com.blogspot.marxsoftware.PersonType}
* that corresponds to me.
*
* @return Instance of {@link com.blogspot.marxsoftware.PersonType} that
* corresponds to me.
*/
public PersonType toPersonType()
{
final ObjectFactory objectFactory = new ObjectFactory();
final PersonType personType = objectFactory.createPersonType();
personType.setFirstName(this.firstName);
personType.setLastName(this.lastName);
personType.setResidentialAddress(this.residentialAddress.toAddressType());
personType.setMailingAddress(this.mailingAddress.toAddressType());
return personType;
}
/**
* Provide instance of {@link dustin.examples.PersonPlus} corresponding
* to the provided instance of JAXB-generated object
* {@link com.blogspot.marxsoftware.PersonType}.
*
* @param personType Instance of JAXB-generated object
* {@link com.blogspot.marxsoftware.PersonType}.
* @return Instance of me corresponding to provided JAXB-generated object
* {@link com.blogspot.marxsoftware.PersonType}.
*/
public static PersonPlus fromPersonType(final PersonType personType)
{
final AddressPlus residentialAddress =
AddressPlus.fromAddressType(personType.getResidentialAddress());
final AddressPlus mailingAddress =
AddressPlus.fromAddressType(personType.getMailingAddress());
return new PersonPlus(personType.getLastName(), personType.getFirstName(),
residentialAddress, mailingAddress);
}
}
AddressPlus.java
package dustin.examples;
import com.blogspot.marxsoftware.AddressType;
import com.blogspot.marxsoftware.ObjectFactory;
import java.util.Objects;
/**
* Address class with support for copying to/from JAXB-generated class
* {@link com.blogspot.marxsoftware.AddressType}.
*
* @author Dustin
*/
public class AddressPlus
{
private String streetAddress1;
private String streetAddress2;
private String municipality;
private String state;
private String zipCode;
public AddressPlus(
final String newStreetAddress1,
final String newStreetAddress2,
final String newMunicipality,
final String newState,
final String newZipCode)
{
this.streetAddress1 = newStreetAddress1;
this.streetAddress2 = newStreetAddress2;
this.municipality = newMunicipality;
this.state = newState;
this.zipCode = newZipCode;
}
public String getStreetAddress1()
{
return this.streetAddress1;
}
public void setStreetAddress1(String streetAddress1)
{
this.streetAddress1 = streetAddress1;
}
public String getStreetAddress2()
{
return this.streetAddress2;
}
public void setStreetAddress2(String streetAddress2)
{
this.streetAddress2 = streetAddress2;
}
public String getMunicipality()
{
return this.municipality;
}
public void setMunicipality(String municipality)
{
this.municipality = municipality;
}
public String getState() {
return this.state;
}
public void setState(String state)
{
this.state = state;
}
public String getZipCode()
{
return this.zipCode;
}
public void setZipCode(String zipCode)
{
this.zipCode = zipCode;
}
@Override
public int hashCode()
{
return Objects.hash(
this.streetAddress1, this.streetAddress2, this.municipality,
this.state, this.zipCode);
}
@Override
public boolean equals(Object obj)
{
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final AddressPlus other = (AddressPlus) obj;
if (!Objects.equals(this.streetAddress1, other.streetAddress1))
{
return false;
}
if (!Objects.equals(this.streetAddress2, other.streetAddress2))
{
return false;
}
if (!Objects.equals(this.municipality, other.municipality))
{
return false;
}
if (!Objects.equals(this.state, other.state))
{
return false;
}
if (!Objects.equals(this.zipCode, other.zipCode))
{
return false;
}
return true;
}
@Override
public String toString()
{
return "Address{" + "streetAddress1=" + streetAddress1 + ", streetAddress2="
+ streetAddress2 + ", municipality=" + municipality + ", state=" + state
+ ", zipCode=" + zipCode + '}';
}
/**
* Provide a JAXB-generated instance of {@link com.blogspot.marxsoftware.AddressType}
* that corresponds to an instance of me.
*
* @return Instance of JAXB-generated {@link com.blogspot.marxsoftware.AddressType}
* that corresponds to me.
*/
public AddressType toAddressType()
{
final ObjectFactory objectFactory = new ObjectFactory();
final AddressType addressType = objectFactory.createAddressType();
addressType.setStreetAddress1(this.streetAddress1);
addressType.setStreetAddress2(this.streetAddress2);
addressType.setCity(this.municipality);
addressType.setState(this.state);
addressType.setZipcode(this.zipCode);
return addressType;
}
/**
* Provide instance of {@link dustin.examples.AddressPlus} corresponding
* to the provided instance of JAXB-generated object
* {@link com.blogspot.marxsoftware.AddressType}.
*
* @param addressType Instance of JAXB-generated object
* {@link com.blogspot.marxsoftware.AddressType}.
* @return Instance of me corresponding to provided JAXB-generated object
* {@link com.blogspot.marxsoftware.AddressType}.
*/
public static AddressPlus fromAddressType(final AddressType addressType)
{
return new AddressPlus(
addressType.getStreetAddress1(),
addressType.getStreetAddress2(),
addressType.getCity(),
addressType.getState(),
addressType.getZipcode());
}
}
上面演示的将JAXB生成的对象映射到业务/域对象的两种方法肯定会起作用,对于我的简单示例,可以将其视为最佳的使用方法(尤其是考虑到NetBeans使业务/域对象的生成几乎变得微不足道)。 但是,对于需要映射的更重要的对象层次结构,可以认为基于Dozer配置的映射是更可取的。
从下载页面 (在此情况下为dozer-5.3.2.jar
)下载了Dozer。 “ 入门”页面显示,当要映射的类的属性具有相同的名称时,映射确实非常容易(最小配置)。 在我的示例中,情况并非如此,我故意将一个属性设为“城市”,将另一个属性设为“市政性”,以使映射更加有趣。 由于这些名称不同,因此我需要自定义Dozer映射 ,这是通过XML映射配置完成的。 必要的映射文件以dozerBeanMapping.xml
的“默认映射名称”命名,并在下面显示。 我只需要映射两个具有不同名称的字段( city
和municipality
),因为被映射的两个类的所有其他字段都具有相同的名称,并且无需显式配置即可自动映射在一起。
dozerBeanMapping.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.net
http://dozer.sourceforge.net/schema/beanmapping.xsd">
<configuration>
<stop-on-errors>true</stop-on-errors>
<date-format>MM/dd/yyyy HH:mm:ss</date-format>
<wildcard>true</wildcard>
</configuration>
<mapping>
<class-a>dustin.examples.Address</class-a>
<class-b>com.blogspot.marxsoftware.AddressType</class-b>
<field>
<a>municipality</a>
<b>city</b>
</field>
</mapping>
</mappings>
请注意, XML并非可用于自定义Dozer映射的唯一方法 。 还支持注释和程序化API 。
“ Dozer 第三方对象工厂”页面简要介绍了如何将Dozer与JAXB以及JAXBBeanFactory一起使用。 还建议将推土器与Dozer一起使用,并提供Spring集成示例。 对于应用Dozer的简单示例,我没有使用这些方法,而是使用了非常简单的实例化方法。 这显示在下一个代码清单中。
DozerPersonConverter.java
package dustin.examples.dozerdemo;
import com.blogspot.marxsoftware.PersonType;
import dustin.examples.Person;
import java.util.ArrayList;
import java.util.List;
import org.dozer.DozerBeanMapper;
/**
* Dozer-based converter.
*
* @author Dustin
*/
public class DozerPersonConverter
{
static final DozerBeanMapper mapper = new DozerBeanMapper();
static
{
final List<String> mappingFilesNames = new ArrayList<>();
mappingFilesNames.add("dozerBeanMapping.xml");
mapper.setMappingFiles(mappingFilesNames);
}
/**
* Provide an instance of {@link com.blogspot.marxsoftware.PersonType}
* that corresponds with provided {@link dustin.examples.Person} as
* mapped by Dozer Mapper.
*
* @param person Instance of {@link dustin.examples.Person} from which
* {@link com.blogspot.marxsoftware.PersonType} will be extracted.
* @return Instance of {@link com.blogspot.marxsoftware.PersonType} that
* is based on provided {@link dustin.examples.Person} instance.
*/
public PersonType copyPersonTypeFromPerson(final Person person)
{
final PersonType personType =
mapper.map(person, PersonType.class);
return personType;
}
/**
* Provide an instance of {@link dustin.examples.Person} that corresponds
* with the provided {@link com.blogspot.marxsoftware.PersonType} as
* mapped by Dozer Mapper.
*
* @param personType Instance of {@link com.blogspot.marxsoftware.PersonType}
* from which {@link dustin.examples.Person} will be extracted.
* @return Instance of {@link dustin.examples.Person} that is based on the
* provided {@link com.blogspot.marxsoftware.PersonType}.
*/
public Person copyPersonFromPersonType(final PersonType personType)
{
final Person person =
mapper.map(personType, Person.class);
return person;
}
}
前面的示例显示了将JAXB生成的对象映射到业务/域对象所需的代码量。 当然,需要一些XML,但仅适用于名称不同的字段。 这意味着字段名称之间的差异越大,就需要进行更多的配置。 但是,只要大多数字段是一对一映射的,并且它们之间没有任何特殊的“转换”逻辑,Dozer就会用配置映射替换许多繁琐的代码。
如果需要转换字段(例如将一个对象中的米转换为另一对象中的公里),则当必须编写自定义转换器时,此映射支持可能会不太吸引人。 推土机映射也很难更正确地应用于深层嵌套的对象,但是我的示例在Person
嵌套了Address
作为一个简单示例。 尽管复杂的映射在Dozer中可能不再那么吸引人,但是JAXB生成的对象到业务/域对象的许多映射都足够简单,足以被Dozer服务。
我想在这篇文章中指出的最后一件事是,Dozer对某些第三方库具有运行时依赖性。 幸运的是,这些库无论如何都经常在Java项目中使用,并且随时可用。 如下面的两个图像所示,所需的运行时依赖项是SLF4J,Apache Commons Lang,Apache Commons Logging和Apache BeanUtils。
推土机运行时相关性页面
本文的示例的NetBeans 7.4项目库 设置Dozer及其依赖项并配置映射需要花费很少的精力,但是在许多常见的JAXB到企业对象数据复制应用程序中,可以通过大大减少映射代码来很好地回报这种努力。
翻译自: https://www.javacodegeeks.com/2013/12/dozer-mapping-jaxb-objects-to-businessdomain-objects.html
jaxb 映射 空字段