推土机:将JAXB对象映射到业务/域对象
Dozer是開放源代碼( Apache 2許可 )“ Java Bean到Java Bean映射器,可將數(shù)據(jù)從一個對象遞歸復制到另一個對象”。 正如從其主頁上的描述所描述的那樣,它用于映射兩個JavaBeans實例,以在實例之間進行自動數(shù)據(jù)復制。 盡管這些可以是多種JavaBeans實例中的任何一種,但我將重點介紹如何使用Dozer將JAXB生成的對象映射到“業(yè)務數(shù)據(jù)對象”(有時稱為“域對象”)。
在使用Java XML綁定體系結構 ( JAXB )的Java應用程序中,開發(fā)人員編寫特定的業(yè)務或域對象供應用程序本身使用,而僅使用JAXB生成的對象進行讀取(解組)和寫入操作,這是很常見的 。 (編組)XML。 盡管將JAXB生成的對象本身用作業(yè)務/域對象具有一定的吸引力 ( DRY ),但是這種方法存在一些缺點。 JAXB生成的類沒有toString() , equals(Object)或hashCode()實現(xiàn),這使得這些生成的類不適合用于多種類型的集合中,除身份比較之外不適合比較,并且不便于記錄其內容。 在對生成的類進行生成之后,對其進行手動編輯很麻煩,并且即使對源XSD進行了很小的更改,也不利于再次生成JAXB類。
盡管可以使用JAXB2 Basics來確保JAXB生成的類具有在集合中使用,進行比較以及記錄其內容所需的一些通用方法,但是使用JAXB生成的類作為domain /可能存在更大的問題業(yè)務對象是業(yè)務邏輯與XSD緊密結合的必然結果。 XSD中的模式更改(例如版本更新)通常會導致通過JAXB從該XSD生成的類的包結構不同。 然后,不同的包結構將強制所有導入那些JAXB生成的類的代碼來更改其導入語句。 XSD的內容更改可能會產生更大的影響,從而影響JAXB類的get / set方法,如果將JAXB類用于域/業(yè)務對象,則該方法會散布在整個應用程序中。
假定決定不使用JAXB生成的類作為業(yè)務/域類,有多種方法可以通過代碼或配置中描述的“映射層”將生成的JAXB類映射到定義業(yè)務/域對象的類。 為了演示兩個基于代碼的映射層實現(xiàn)并演示基于Dozer的映射層,我介紹了一些JAXB生成的類和定制構建的業(yè)務/域類的簡單示例。
本文的示例的第一部分是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執(zhí)行xjc (Oracle JDK隨附的JAXB編譯器)時,在com / blogspot / marxsoftware目錄中(從XSD的命名空間派生)生成以下四個類: AddressType.java , PersonType.java , ObjectFactory.java和package-info.java 。
接下來的兩個代碼清單是JAXB生成的兩個主要感興趣的類( PersonType.java和AddressType.java )。 在這里顯示它們的主要目的是提醒他們,它們缺少我們經(jīng)常需要我們的業(yè)務/域類擁有的方法。
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生成的對象和自定義編寫的業(yè)務/域對象之間復制數(shù)據(jù)的一種常見而直接的策略是使用一個對象的“ get”方法并將其返回值傳遞給另一個對象的“ set”方法。 例如,在將XML解組/讀取到應用程序的過程中,可以將JAXB生成的對象上調用的“ get”方法的結果傳遞給業(yè)務/域對象的“ set”方法。 相反,通過將域/業(yè)務對象上的“ get”方法的結果傳遞給JAXB生成的對象的相應“ set”方法,可以輕松完成編組/編寫XML。 下一個代碼清單用于PersonCoverter.java并說明了此方法的一種實現(xiàn)。
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生成的對象和域/業(yè)務對象之間雙向復制數(shù)據(jù)。 另一種方法是將這種復制功能構建到域/業(yè)務對象本身中。 這在PersonPlus.java和AddressPlus.java兩個代碼清單中PersonPlus.java ,它們是先前介紹的Person.java和Address.java版本,并添加了對從JAXB生成的對象復制數(shù)據(jù)的支持。 為了方便起見,我在toString實現(xiàn)之后將新方法添加到類的底部。
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;}@Overridepublic 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;}@Overridepublic 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;}@Overridepublic 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;}@Overridepublic int hashCode(){return Objects.hash(this.streetAddress1, this.streetAddress2, this.municipality,this.state, this.zipCode);}@Overridepublic 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;}@Overridepublic 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生成的對象映射到業(yè)務/域對象的兩種方法肯定會起作用,對于我的簡單示例,可以將其視為最佳的使用方法(尤其是考慮到NetBeans使業(yè)務/域對象的生成幾乎變得微不足道)。 但是,對于需要映射的更重要的對象層次結構,可以認為基于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.nethttp://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生成的對象映射到業(yè)務/域對象所需的代碼量。 當然,需要一些XML,但僅適用于名稱不同的字段。 這意味著字段名稱之間的差異越大,就需要進行更多的配置。 但是,只要大多數(shù)字段之間是一對一映射的,并且它們之間沒有任何特殊的“轉換”邏輯,Dozer就會用配置映射替換許多繁瑣的代碼。
如果需要轉換字段(例如將一個對象中的米轉換為另一對象中的公里),那么當必須編寫自定義轉換器時,此映射支持可能會不太吸引人。 推土機映射也很難更正確地應用于深層嵌套的對象,但我的示例確實將Address嵌套在Person作為一個簡單示例。 盡管復雜的映射在Dozer中可能不再那么吸引人,但是JAXB生成的對象到業(yè)務/域對象的許多映射都是足夠簡單的映射,可以由Dozer很好地服務。
我想在這篇文章中指出的最后一件事是,Dozer對某些第三方庫具有運行時依賴性。 幸運的是,無論如何,這些庫還是Java項目中常用的,并且隨時可用。 如下面的兩個圖像所示,所需的運行時依賴項是SLF4J,Apache Commons Lang,Apache Commons Logging和Apache BeanUtils。
推土機運行時相關性頁面
本帖子示例的NetBeans 7.4項目庫 設置Dozer及其依賴項并配置映射需要花費很少的精力,但是在許多常見的JAXB到企業(yè)對象數(shù)據(jù)復制應用程序中,可以通過大大減少映射代碼來很好地回報這種努力。
翻譯自: https://www.javacodegeeks.com/2013/12/dozer-mapping-jaxb-objects-to-businessdomain-objects.html
總結
以上是生活随笔為你收集整理的推土机:将JAXB对象映射到业务/域对象的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux登录密码忘了怎么办(linux
- 下一篇: 休眠事实:始终检查Criteria AP