JAXB众所周知的秘密

介绍

我重新发现了Java提供给大众的库。 当我第一次阅读该规范时,我很困惑,以为我需要所有这些特殊工具来实现。 我最近发现,只需要一些注释和一个POJO。

杰克斯

JAXB代表XML绑定的Java体系结构。 这种体系结构允许开发人员将来自类的数据转换为XML表示形式。 这称为编组。 该体系结构还允许开发人员逆转将XML表示转换为类的过程。 这称为解组。 有一些工具可以从XML Schema文件创建Java类。 该工具称为xjc。 还有另一种使用schemagen创建xsd文件的工具。

编组

编组和解组在Java中发生了很多地方。 我首先接触到的是RMI。 对象被发送用作远程方法调用的参数,因此名称为“远程方法调用(RMI)”。 它发生的另一个地方是将对象写入流。 实现此功能的流是ObjectOutputStream和ObjectInputStream。 发生的另一个地方是ORM类。 当然,另一种方式是编写实例的XML表示。 想要编组的类需要实现Serializable,并且其所有成员属性也都需要实现Serializable,但通过JAXB的类除外。 可序列化是标记接口。 它没有实现的方法,但是它表明可以对类进行序列化或编组。 被编组的对象的数据已采用某种持久化方式。 未编组对象的数据已从持久状态读取并与类连接。 这使得类路径非常重要。 有趣的是,类路径中的有效条目是http:// ip:port / path / to / jar 。 我想有些组织可以通过集中化jar文件来使用此功能,而最新版本仅需下载即可。

我用maven和spring来做这个例子。 原因不是使它更加复杂,而是使代码更清晰地阅读和更专注于使用我所展示的技术。 pom.xml文件中的依赖项如下:

<dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.11</version><scope>test</scope></dependency><dependency><groupId>com.sun.xml.bind</groupId><artifactId>jaxb-impl</artifactId><version>2.2.8-b01</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-core</artifactId><version>3.2.3.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>3.2.3.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-beans</artifactId><version>3.2.3.RELEASE</version></dependency></dependencies>

JAXB的妙处在于它使用POJO。 Contact.java是三个集合中的中心POJO类。

package org.mathison.jaxb.beans;import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Contact {private String lastName;private String firstName;private String middleName;private String jobTitle;@XmlElementWrapper(name = "addresses")@XmlElement(name = "address")private List<Address> addresses;@XmlElementWrapper(name = "phone-numbers")@XmlElement(name = "phone-number")private List<PhoneNumber> numbers;public String getLastName() {return lastName;}public void setLastName(String lastName) {this.lastName = lastName;}public String getFirstName() {return firstName;}public void setFirstName(String firstName) {this.firstName = firstName;}public String getMiddleName() {return middleName;}public void setMiddleName(String middleName) {this.middleName = middleName;}public String getJobTitle() {return jobTitle;}public void setJobTitle(String jobTitle) {this.jobTitle = jobTitle;}public List<Address> getAddresses() {return addresses;}public void setAddresses(List<Address> addresses) {this.addresses = addresses;}public List<PhoneNumber> getNumbers() {return numbers;}public void setNumbers(List<PhoneNumber> numbers) {this.numbers = numbers;}@Overridepublic String toString() {return "Contact{" + "lastName=" + lastName + ", firstName=" + firstName + ", middleName=" + middleName + ", jobTitle=" + jobTitle + ", addresses=" + addresses + ", numbers=" + numbers + '}';}@Overridepublic int hashCode() {int hash = 3;hash = 23 * hash + (this.lastName != null ? this.lastName.hashCode() : 0);hash = 23 * hash + (this.firstName != null ? this.firstName.hashCode() : 0);hash = 23 * hash + (this.middleName != null ? this.middleName.hashCode() : 0);hash = 23 * hash + (this.jobTitle != null ? this.jobTitle.hashCode() : 0);hash = 23 * hash + (this.addresses != null ? this.addresses.hashCode() : 0);hash = 23 * hash + (this.numbers != null ?this.numbers.hashCode() : 0);return hash;}@Overridepublic boolean equals(Object obj) {if (obj == null) {return false;}if (getClass() != obj.getClass()) {return false;}final Contact other = (Contact) obj;if ((this.lastName == null) ? (other.lastName != null) :!this.lastName.equals(other.lastName)) {return false;}if ((this.firstName == null) ? (other.firstName != null) : !this.firstName.equals(other.firstName)) {return false;}if ((this.middleName == null) ? (other.middleName != null) : !this.middleName.equals(other.middleName)) {return false;}if ((this.jobTitle == null) ? (other.jobTitle != null) : !this.jobTitle.equals(other.jobTitle)) {return false;}if(!listEquals(this.addresses, other.addresses)) {return false;}if(!listEquals(this.numbers, other.numbers)) {return false;}return true;}private boolean listEquals(List first, List second) {for(Object o: first) {if(!second.contains(o)) {return false;}}return true;}}

要看的主要部分是注释。 @XmlRootElement定义这是一个类的开始。 @XmlAccessorType(XmlAccessType.FIELD)告诉体系结构,这些字段将用于定义xml中的元素。 注释也可以放在吸气剂上。 如果未使用注释,则JAXB会混淆使用哪个注释。 对于存在列表的实例,@Xm​​lElementWrapper用来告诉JAXB外部标签将是什么。 例如,有一个地址列表。 包装器采用名为“ name”的参数,并用“ addresss”填充。 呈现XML时,将在地址集合周围包裹标签“ addresses”。 如果要更改属性的标记,则使用@XmlElement批注。 回到我们的地址列表,注释将地址列表重新定义为“ address”。 这将导致每个地址对象都具有“地址”标签,而不是已经占用的“地址”标签。 数字使用相同的模式。 其余的属性将具有与它们的名称匹配的标签。 例如,lastName将变成标签“ lastName”。 其他两个POJO(电话号码.java和地址.java)具有公共枚举类。 这是PhoneNumber.java:

package org.mathison.jaxb.beans;import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;@XmlRootElement
public class PhoneNumber {@XmlType(name="phone-type")public enum Type {HOME,WORK,HOME_FAX,WORK_FAX;}private Type type;private String number;public Type getType() {return type;}public void setType(Type type) {this.type = type;}public String getNumber() {return number;}public void setNumber(String number) {this.number = number;}@Overridepublic String toString() {return "PhoneNumber{" + "type=" + type + ", number=" + number + '}';}@Overridepublic int hashCode() {int hash = 7;hash = 37 * hash + (this.type != null ? this.type.hashCode() : 0);hash = 37 * hash + (this.number != null ? this.number.hashCode() : 0);return hash;}@Overridepublic boolean equals(Object obj) {if (obj == null) {return false;}if (getClass() != obj.getClass()) {return false;}final PhoneNumber other = (PhoneNumber) obj;if (this.type != other.type) {return false;}if ((this.number == null) ? (other.number != null) : !this.number.equals(other.number)) {return false;}return true;}}

注释的注释为@XmlType。 这告诉JAXB一类有限数量的值。 它带有一个名称参数。 最后一个POJO还使用@XmlType定义其公共枚举类。 可以在Address.java中找到它。

全部放在一起

有了所有这些注释和类定义,是时候将所有这些放到一个主类中了。 这是App.java,主要类:

package org.mathison.jaxb.app;import java.io.StringReader;
import java.io.StringWriter;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import org.mathison.jaxb.beans.Contact;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.GenericXmlApplicationContext;public class App 
{public static void main( String[] args ){ApplicationContext cxt = new GenericXmlApplicationContext("jaxb.xml");Contact contact = cxt.getBean("contact", Contact.class);StringWriter writer = new StringWriter();try {JAXBContext context = JAXBContext.newInstance(Contact.class);//create xml from an instance from ContactMarshaller m = context.createMarshaller();m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);m.marshal(contact, writer);String xml = writer.getBuffer().toString();System.out.println(xml);//Take xml to ContactStringReader reader = new StringReader(xml);Unmarshaller u = context.createUnmarshaller();Contact fromXml = (Contact)u.unmarshal(reader);System.out.println("Are the instances equivalent: " + contact.equals(fromXml));} catch(Exception e){e.printStackTrace();}}
}

首先,从ApplicationContext检索联系人实例。 其次,以Contact类作为根类创建JAXBContext实例。 上下文将分析类结构,并创建可以封送或拆封Contact,Address和PhoneNumber类的上下文。 在下一部分中,从JAXBContext创建一个编组器。 Marshaller.JAXB_FORMATTED_OUTPUT属性设置为true。 这将创建一个格式化的XML输出。 如果未设置该属性,则XML将作为一行文本出现。 调用编组器进行编组联系并将其写入StringWriter。 然后将XML打印到System.out。 输出应如下所示:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<contact><lastName>Mathison</lastName><firstName>Daryl</firstName><middleName>Bob</middleName><jobTitle>Developer</jobTitle><addresses><address><addressLine>123 Willow View</addressLine><city>Cibolo</city><state>TX</state><type>HOME</type><zipCode>78228</zipCode></address><address><addressLine>411 Grieg</addressLine><city>San Antonio</city><state>TX</state><type>WORK</type><zipCode>78228</zipCode></address></addresses><phone-numbers><phone-number><number>210-123-4567</number><type>WORK</type></phone-number><phone-number><number>210-345-1111</number><type>HOME</type></phone-number></phone-numbers></contact>

在下一部分中,将xml与其数据一起解组到Contact实例中。 Unmarshaller由JAXBContext创建。 接下来,解组器将传递一个StringReader,其内容为刚刚创建的XML。 解组器返回一个对象,该对象被强制转换为联系人。 将针对新的Contact实例测试Contact的原始实例,以查看它们是否等效。 输出应显示:

Are the instances equivalent: true.

摘要

在此示例中,Contact的实例被转换为XML,并且在JAXB的帮助下,所得的XML被转换回Contact实例。 JAXB是一种将对象的状态映射到XML并将XML映射回对象的体系结构。

参考文献

  • http://www.techrepublic.com/blog/programming-and-development/jaxb-20-offers-improved-xml-binding-in-java/498
  • http://www.vogella.com/articles/JAXB/article.html
  • http://en.wikipedia.org/wiki/JAXB

翻译自: https://www.javacodegeeks.com/2014/10/the-jaxb-well-known-secret.html

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

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

相关文章

题解:CF1914E-Game with Marbles

题解&#xff1a;CF1914E-Game with Marbles 事先说明一下&#xff0c;本题解不讲解简单数据范围的算法&#xff0c;因为复杂数据范围的就很简单。 这道题的大体意思是这样的&#xff1a;小A有颜色为i(i1~n)的小球a[i]个&#xff0c;小B有颜色为i(i1~n)的小球b[i]个。现在他们…

【canvas系列】canvas实现“ 简单的Amaziograph效果”--画对称图【强迫症福利】

标题很难引人入胜&#xff0c;先放个效果图好了 如果图片吸引不了你&#xff0c;那我觉得也就没啥看的了。 demo链接&#xff1a; https://win7killer.github.io/demo_set/html_demo/canvas/can_demo/draw_roll_2.html ************************************************* 上…

原生类型的autoboxing和auto-unboxing

原生类型的autoboxing和auto-unboxing 我们知道&#xff0c;在Java中&#xff0c;int,long等原生类型不是一个继承自Object的类&#xff0c;所以相应的&#xff0c;有很多操作我们都不能利用原生类型操作&#xff0c;比如想要把一个整数放入到一个集合中&#xff0c;我们必须首…

jquery ui datepicker 只能选今天以后的日期

$("input[namebegintime],input[nameendtime],input[nameArrivedate]").datepicker({dateFormat:"yy-mm-dd",minDate: new Date()}); 转载于:https://www.cnblogs.com/y0umer/archive/2012/03/02/3839264.html

全部关于测试–第2部分

这是有关测试系列的第二篇文章。 在第一部分中&#xff0c;我解释了在进行测试开发时需要具备的心态。 或者&#xff0c;换句话说&#xff0c;开发可测试的代码。 在这一部分中&#xff0c;我将介绍一些测试方法的技术。 我将描述的技术可以看作是如何将思维定势转化为行动。 …

简化软件操作,提升用户体验

虽然自己一直都是做网站开发的&#xff0c;没做过什么软件开发&#xff0c;但使用过的软件也不算少。渐渐的发现有些软件真的功能强大&#xff0c;操作性太复杂&#xff0c;于是该软件真的变成了所谓的专业软件&#xff0c;只有经过专业培训的人才能使用。问题是如果不是有很特…

原生js实现简单JSONP

JSONP是一种非常常见的实现跨域请求的方法。其基本思想是利用浏览器中可以跨域请求外链的JS文件&#xff0c;利用这一特性实现数据传输。 用原生JS实现JSONP非常简单&#xff0c;无非几点&#xff1a; 1&#xff09;定义一个函数&#xff0c;用于处理接收到的跨域数据。 2&a…

Java 8流:Micro Katas

编程kata是一种练习&#xff0c;可以帮助程序员通过练习和重复练习来磨练自己的技能。 本文是“ 通过Katas进行Java教程 ”系列的一部分。 本文假定读者已经具有Java的经验&#xff0c;熟悉单元测试的基础知识&#xff0c;并且知道如何从他最喜欢的IDE&#xff08;我是Intelli…

Effective Java第七条:避免使用终结方法

第七条&#xff1a;避免使用终结方法 1&#xff0c; 终结方法&#xff08;finalizer&#xff09;会让程序不稳定&#xff0c;性能降低&#xff0c;出现可移植性的问题。 2&#xff0c; Finalizer在c中师析构器&#xff08;destructors&#xff09;的一部分&#xff0c;用作回…

python3基础:字符串、文本文件

字符串&#xff1a; 练习1&#xff1a; str "大胖三百磅不是二百磅陪着一百磅的小胖" print(str.replace("磅", "斤")) # 替换所有 print(str.replace("磅", "斤", 2)) # 替换两次len len(str) # 这句话的字数长度 pri…

[Python][小知识][NO.3] Python 使用系统默认浏览器打开指定URL的网址

1、前言 一般用到的地方&#xff1a; GUI交互界面下&#xff0c;单击某个按钮实现打开指定网址。 某帮助菜单项目&#xff0c;需要跳转网页显示时。 O.O 某XX程序&#xff0c;需要植入网页弹窗广告时... 2、方法 调用 webbrowser 包中的 open 函数即可。 (没安装该包的 CMD命令…

全部关于测试–第1部分

这是三个系列文章中的第一篇。 测试思路 技术技巧 工具和提示 心态 测试代码是需要学习的东西。 需要花费时间来吸收如何做好。 这是一种应该始终练习和改进的技巧。 过去&#xff0c;开发人员没有进行测试&#xff0c;而是检查了他们的代码。 这是一个很好的技巧&#xf…

利用数据库创建webservice

http://www.cnblogs.com/yungboy/archive/2011/11/07/2239642.html转载于:https://www.cnblogs.com/mingyongcheng/archive/2012/03/08/2385242.html

ASP.NET AJAX Debugging and Tracing

Moved to http://blog.tangcs.com/2008/09/30/asp-net-ajax-debugging-and-tracing/转载于:https://www.cnblogs.com/WarrenTang/archive/2008/09/30/1302328.html

JS中编码操作

常见的网页设计编码&#xff1a;Unicode的UCS-2 UCS-4 UTF-8 UTF-16 UTF-32以及ASCII和ANSI。 要知道JS最初定稿时使用的编码是UCS-2&#xff08;因为那时候还没UTF-16&#xff0c;本质&#xff1a;UTF-16就是对UCS-2的扩展&#xff0c;前面的65536个字符就是UCS-2本身&#x…

Apache Commons IO教程:初学者指南

Apache Commons IO是由Apache Foundation创建和维护的Java库。 它提供了许多类&#xff0c;使开发人员可以轻松地完成常见任务&#xff0c;并且减少样板代码 &#xff0c;而每个项目都需要一遍又一遍地编写此类库的重要性是巨大的&#xff0c;因为它们已经成熟由经验丰富的开发…

MyEclipse 10优化技巧

MyEclipse 10优化速度方案仍然主要有这么几个方面&#xff1a;去除无需加载的模块、取消冗余的配置、去除不必要的检查、关闭更新。第一步: 去除不需要加载的模块一个系统20%的功能往往能够满足80%的需求&#xff0c;MyEclipse也不例外&#xff0c;我们在大多数时候只需要20%的…

为什么应该避免JSF

长期以来&#xff0c;对我来说&#xff0c;JSF只是另一个我不太在乎的Web框架。 这改变了。 在被迫使用了几个月之后&#xff0c;我认为在几乎所有情况下&#xff0c;这都是重大的项目风险。 在这里&#xff0c;我提出此判决的理由。 UI和处理逻辑的纠缠不清。 官方教程声称以…

HTML知识点总结之img、scirpt、link标签

<img>元素 使用<img>可以在网页插入一个图片&#xff0c;但实际上<img>标签并不会在网页中直接插入图像&#xff0c;而是从网页上链接图像。 <img>的主要属性 &#xff08;1&#xff09;src属性&#xff1a;图片的路径。 &#xff08;2&#xff09;alt…

更多 Kinect for Windows 项目揭示

虽然Kinect for Windows的发布不过才过去一个月而已&#xff0c;但是到目前为止这个Xbox 360游戏设备辅助产品似乎已经赶上了一些商业企业项目了。其中包括一个让机器人自动购物车成为现实的项目。在Microsoft Power and Utilities博客 的一篇博文中&#xff0c;微软列举了一些…