jaxb 映射 空字段_推土机:将JAXB对象映射到业务/域对象

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元素,该元素可以具有嵌套的MailingAddressResidentialAddress元素以及两个用于名字和姓氏的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.javaPersonType.javaObjectFactory.javapackage-info.java

jaxbGeneratedClassesPersonAddress

接下来的两个代码清单是JAXB生成的两个主要感兴趣的类( PersonType.javaAddressType.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.javaAddressPlus.java两个代码清单中PersonPlus.java ,它们是先前介绍的Person.javaAddress.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;}@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生成的对象映射到业务/域对象的两种方法肯定会起作用,对于我的简单示例,可以将其视为最佳的使用方法(尤其是考虑到NetBeans使业务/域对象的生成几乎变得微不足道)。 但是,对于需要映射的更重要的对象层次结构,可以认为基于Dozer配置的映射是更可取的。

从下载页面 (在此情况下为dozer-5.3.2.jar )下载了Dozer。 “ 入门”页面显示,当要映射的类的属性具有相同的名称时,映射确实非常容易(最小配置)。 在我的示例中,情况并非如此,我故意将一个属性设为“城市”,将另一个属性设为“市政性”,以使映射更加有趣。 由于这些名称不同,因此我需要自定义Dozer映射 ,这是通过XML映射配置完成的。 必要的映​​射文件以dozerBeanMapping.xml的“默认映射名称”命名,并在下面显示。 我只需要映射两个具有不同名称的字段( citymunicipality ),因为被映射的两个类的所有其他字段都具有相同的名称,并且无需显式配置即可自动映射在一起。

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生成的对象映射到业务/域对象所需的代码量。 当然,需要一些XML,但仅适用于名称不同的字段。 这意味着字段名称之间的差异越大,就需要进行更多的配置。 但是,只要大多数字段是一对一映射的,并且它们之间没有任何特殊的“转换”逻辑,Dozer就会用配置映射替换许多繁琐的代码。

如果需要转换字段(例如将一个对象中的米转换为另一对象中的公里),则当必须编写自定义转换器时,此映射支持可能会不太吸引人。 推土机映射也很难更正确地应用于深层嵌套的对象,但是我的示例在Person嵌套了Address作为一个简单示例。 尽管复杂的映射在Dozer中可能不再那么吸引人,但是JAXB生成的对象到业务/域对象的许多映射都足够简单,足以被Dozer服务。

我想在这篇文章中指出的最后一件事是,Dozer对某些第三方库具有运行时依赖性。 幸运的是,这些库无论如何都经常在Java项目中使用,并且随时可用。 如下面的两个图像所示,所需的运行时依赖项是SLF4J,Apache Commons Lang,Apache Commons Logging和Apache BeanUtils。

推土机运行时相关性页面
dozerAdvertisedRuntimeDependencies
本文的示例的NetBeans 7.4项目库 dozerNetBeansProjectRuntimeDependencies 设置Dozer及其依赖项并配置映射需要花费很少的精力,但是在许多常见的JAXB到企业对象数据复制应用程序中,可以通过大大减少映射代码来很好地回报这种努力。

参考: 推土机:来自JCG合作伙伴 Dustin Marx的“ 实际事件的启发”博客中的JAXB对象到业务/域对象的映射 。

翻译自: https://www.javacodegeeks.com/2013/12/dozer-mapping-jaxb-objects-to-businessdomain-objects.html

jaxb 映射 空字段

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/344861.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【渝粤题库】陕西师范大学202881 电子商务概论

《电子商务概论》作业 一、判断题 1、CPU中运算器的主要功能是完成对数据的算术运算、逻辑运算和逻辑判断等操作。&#xff08; &#xff09; 2、与传统的支付方式相比&#xff0c;电子支付具有方便、快捷、高效、经济、安全的优势。&#xff08; &#xff09; 3、在面向终端的…

常用计算机网络性能指标的是什么,什么是Bit?【计算机网络的性能指标】

比特(英语&#xff1a;Bit)&#xff0c;亦称二进制位&#xff0c;指二进制中的一位&#xff0c;是信息的最小单位。因此一个比特就是二进制数字中的一个 1 或 0Bit是Binary digit(二进制数字)的缩写&#xff0c;由数学家John Wilder Tukey提出(可能是1946年提出&#xff0c;但有…

使用AWS Lambda在Go中构建RESTful API

在本文中&#xff0c;我们将学习使用AWS Lambda在Go中设计&#xff0c;构建和部署RESTful API。 在开始之前&#xff0c;让我给您简要介绍一下AWS Lambda。 什么是AWS Lambda&#xff1f; AWS Lambda是一种无服务器计算服务&#xff0c;可运行我们的代码以响应事件并自动为我…

【渝粤题库】陕西师范大学210011幼儿园语言教育作业(高起专)

《幼儿园语言教育》作业 一、填空题 1、儿童语言的发展是指儿童对母语的理解和 能力随着时间的推移而发生变化的过程和现象。 2、儿童获得语言之前&#xff0c;用语音及伴随的表情或动作代替语言进行交往的现象被称为 。 3、 是指交际双方根据交际目的和语言情境有效地使用语言…

html的段落标志中 标注行中断,?HTML的段落标志中,标注行中断的是?

A:,B:,C: ,D:答案查看答案?HTML的段落标志中,标注行中断的是?解析【单选题】下列关于元素在网页中的叠放顺序描述&#xff0c;不正确的是&#xff1f;【单选题】HTML代码表示&#xff1f;【单选题】创建选项菜单应使用以下标记符&#xff1f;【单选题】在本窗口打开超链接的代…

【渝粤题库】陕西师范大学292301 国际金融学Ⅱ 作业(专升本)

《国际金融II》作业 一、判断 1、国际收支一般总是有差额的&#xff0c;当国际收入部分小于支出部分称为顺差&#xff0c;反之为逆差或赤字。 2、特别提款权在国际储备中所占的比重很大&#xff0c;约为40%。 3、在不同标价法下&#xff0c;买入价与卖出价的表示方法不同。在直…

【渝粤题库】陕西师范大学500010 量子力学 作业(专升本)

一、填空题 1、历史上第一个完全肯定光除了波动性之外还具有粒子性的科学家是 。按照光子假&#xff0c;频率为ν、波长为λ的电磁辐射其光子的能量E &#xff0c;动量P &#xff0e; 2、按照德布罗意假说&#xff0c;能量为E、动量为的自由粒子&#xff0c;其相应的物质波可表…

【渝粤题库】陕西师范大学800004 遥感概论

《遥感概论》作业 一&#xff0e; 填空题 &#xff11;&#xff0e;根据运载工具的类型&#xff0c;可分为 、 、 。    &#xff12;&#xff0e;固体自扫描目前常用的探测元件是 &#xff0c;它是一种用电荷量表示信号大小&#xff0c;用耦合方式传输信号的探测元件。 &…

undertow服务器分析_使用undertow构建和测试Websocket服务器

undertow服务器分析即将发布的JBoss Application Server版本将不再使用Tomcat作为集成的Web服务器&#xff0c;而是将其替换为undertow 。 undertow的体系结构基于可通过Builder API动态添加到服务器的处理程序。 这种方法类似于在Node.js中构造Web服务器的方式。 它使开发人员…

国家开放大学2021春1087数学分析专题研究题目

教育 教育 试卷代号&#xff1a;1087 2021年春季学期期末统一考试 数学分析专题研究 试题 2021年7月 一、单项选择题&#xff08;每小题4分&#xff0c;共20分&#xff09; 1.设映射f:A→B&#xff0c;g:B→C&#xff0c;且g。f:A→C是双射&#xff0c;则映射f一定是&#xf…

跳转指令微型计算机,哪种类型的汇编程序跳转指令最有用?

Ira Baxter..5(我已经为汇编程序编写了40多年;实际上在20世纪70年代早期设计并构建了一个生产多寄存器16位机器).真正有用的是CMP指令和指定该条件的JMP相对.我建议你让算术指令产生状态位零结果从结果出发结果的标志溢出(签名)我们称之为"条件位".你会发现它们都很有…

渝粤题库]西北工业大学组成与系统结构

一单选题 1.动态流水线是指( )。(2分) A.只有一种功能的流水线 B.同时只能完成一种功能的多功能流水线 C.功能不能改变的流水线 D .可同时执行多种功能的流水线 2.通道程序执行结束后引起的中断是(). (2分) A.程序性中断 B.外中断 C. I/O中断 D.机器校验中断 3.不属于堆栈型替…

重新开始Java的原始字符串文字讨论

在2018年12月宣布 将从JDK 12中删除原始字符串文字 。 现在&#xff0c;在新的一年中&#xff0c;与Java中原始字符串文字的设计有关的讨论又开始了。 在琥珀色专家OpenJDK邮件列表上的“ 原始字符串文字-重新开始讨论 ”一文中 &#xff0c;Brian Goetz参考了有关从JDK 12中删…

【渝粤教育】广东开放大学 计算机思维 形成性考核 (29)

题库查询系统 选择题 题目&#xff1a;计算思维的特征有概念化,不是程序化、有根本的,不是刻板的技能、有是人的不是计算机的思维方式() 答案&#xff1a; A、是思想,不是人造物 题目&#xff1a;以下是算法的特性的() 答案&#xff1a; A、确定性、有穷性、不可行、输出、有穷…

计算机考博哪个学校好考,管理学博士哪个学校好考

我知道都不容易&#xff0c;都是宽进严出。 但是排除那些像上财、复旦这种热门、大。东华大学授予管理学博士学位的有企业管理博士点和管理科学与工程博士点。 如果你只是想混文凭的话&#xff0c;建议你选择企业管理专业进行报考。该专业相对管理科学与工程的论文要求要低一些…

【渝粤教育】广东开放大学 文化经济实务 形成性考核 (49)

选择题 题目&#xff1a;钢琴三重奏指的是钢琴和&#xff08;&#xff09;。 题目&#xff1a;音乐经纪业务的本质其实就是&#xff08; &#xff09;。 题目&#xff1a;明星制的核心功能是&#xff08;&#xff09;。 题目&#xff1a;模特经纪人还要帮助模特制定近期、中期、…

【渝粤教育】广东开放大学 现代服务业管理 形成性考核 (21)

选择题 题目&#xff1a;产权交易的主要形式有 题目&#xff1a;不属于责任保险的是 题目&#xff1a;以下哪些行业不属于现代服务业&#xff1f; 题目&#xff1a;是国民经济发展的晴雨表&#xff0c;是现代经济的核心。 题目&#xff1a;按照评估对象来分&#xff0c;以下不属…

武汉科技大学计算机研究生拟录取名单,武汉科技大学2021年硕士研究生拟录取名单公示...

104881414604818 黄威威 004 【信息科学与工程学院/人工智能学院】 081100 控制科学与工程 310 66.80 63.44 全日制 学术学位104881421605130 厉许昌 004 【信息科学与工程学院/人工智能学院】 081100 控制科学与工程 306 64.10 62.07 全日制 学术学位104881421200121 饶梓归 0…

spring boot程序_Spring Boot –现代Java应用程序的基础

spring boot程序Spring Boot是Spring.io中一个相对较新的项目。 其目的是简化创建新的基于Spring Framework的项目&#xff0c;并通过应用一些约定来统一其配置。 这种关于配置的方法约定已经成功地应用于大多数所谓的现代Web框架中&#xff0c;例如Ruby on Rails&#xff0c;D…

【渝粤教育】广东开放大学 云计算技术与应用 形成性考核

选择题 题目&#xff1a;下列哪个文件提出&#xff1a;到2020年&#xff0c;云计算成为我国信息化重要形态和建设网络强国的重要支撑&#xff08;&#xff09;。 题目&#xff1a;一般认为&#xff0c;我国云计算产业链主要分为四个层面&#xff0c;即&#xff1a;&#xff08;…