通过MOXy实现使JAXB更加清洁

编组和解组XML时使用JAXB的主要优点是编程模型。 只需注释几个POJO并使用JAXB API,您就可以很容易地序列化为XML和从XML反序列化。 您无需担心有关XML如何编组/解组的细节。 一切都比DOM和SAX等替代方案简单得多。

现在,XML文件中的数据本质上趋于分层。 例如,考虑以下XML文件:

<?xml version="1.0" encoding="UTF-8"?>
<person><firstname>Barok</firstname><lastname>Obama</lastname><age>52</age><car><model>Green Ford Focus 1.4L</model></car>
</person>

在这种情况下,Barok Obama人拥有的汽车是Green Ford Focus。 在这里,我们看到了XML的层次结构特征。 车在人下。 在一个更复杂的示例中,一个人可以拥有一个汽车,该汽车具有一个汽车收音机,该汽车具有一个放大器,该汽车具有晶体管等。但是,让我们暂时坚持我们的简单情况。 假设我们要使用JAXB解组该XML文件。 我们需要所有人的详细信息(名字,姓氏等)以及属于该人的汽车的型号。 我们创建一个Person POJO和一个Car POJO并进行适当的注释。

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(propOrder={"name", "firstname", "lastname"})
public class Person {private String firstname;private String lastname;private int age;private Car car;public String getLastname() {return lastname;}public void setLastname(String lastname) {this.lastname = lastname;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getFirstname() {return firstname;}public void setFirstname(String name) {this.firstname = name;}public Car getCar() {return car;}public void setCar(Car car){this.car= car;}
}
public class Car {private String model;public String getModel() {return model;}public void setModel(String model){this.model = model;}
}

要解组,我们只需做

public static void unmarshall() throws Exception {JAXBContext jaxbContext = JAXBContext.newInstance(Person.class);Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();Person person = (Person)unmarshaller.unmarshal(new File("Person.xml"));System.out.println("Perosn is=" +person.toString());
}

这一切看起来非常简单-特别是当您考虑到Car实体甚至不需要任何注释时! 但是,Car仅具有一个属性,对于我们只希望从中获得一个属性的东西拥有POJO类似乎有点过头了! 记住,这是一个简单的示例,想象一下层次结构是否更深。 类似于包含实体的外部实体,其中包含另一个实体,该实体甚至包含另一个实体,而我们所需的只是外部实体和来自最深层嵌套实体的一个属性。 本质上是相同的问题,但更多的是矫kill过正。 我们必须确保层次结构中的所有内容都有POJO类,甚至对于我们一无所求的实体也是如此。 没有人喜欢代码膨胀。 所以,我们能做些什么?

我们首先要记住的是,JAXB是一个规范,该规范有许多实现(例如JaxMeAPI,MOXy,Metro)。 如果我们要使用JAXB参考实现(随JDK一起提供,则无能为力)。 我们必须有一个汽车和人POJO。 但是,如果我们使用EclipseLink的MOXy实现,则可以使用其一些扩展来帮助我们。 更具体地说,我们可以使用受XPath启发的MOXy @XmlPath扩展。

让我们来看看它的作用。 这是更新的Person POJO。

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(propOrder={"name", "firstname", "lastname"})
public class Person {private String firstname;private String lastname;private int age;public String getLastname() {return lastname;}public void setLastname(String lastname) {this.lastname = lastname;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getFirstname() {return firstname;}public void setFirstname(String name) {this.firstname = name;}@XmlPath("car/model/text()")private String model;public String getModel() {return model;}
}

那么,汽车POJO哪里去了? 好吧,它被删除了。 我们不再需要它了。 再见。
使用MOXy @XmlPath批注,我们不需要Car POJO。 该批注驻留在org.eclipse.persistence.oxm.annotations包中,将其放在类路径中非常简单。 如果您是maven用户,只需添加:

<dependency><groupid>org.eclipse.persistence</groupId><artifactid>eclipselink</artifactId><version>2.3.2</version>
</dependency>

为了告诉您的JDK在运行时将MOXy用于JAXB实现,您放置了一个名为
jaxb.properties与JAXB POJO位于同一目录中。 它包含一行:

javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory

为了确保您正在使用MOXy实现,只需检查JAXB上下文:

JAXBContext jaxbContext = JAXBContext.newInstance(Person.class);
System.out.println("jaxbContext is=" +jaxbContext.toString());

您应该看到类似以下内容:

jaxbContext is=org.eclipse.persistence.jaxb.JAXBContext@5e3974

之后,没有任何变化。 完全相同的数据编码都可以使用。
我之所以真正喜欢此扩展的原因之一是因为它意味着更少的代码。 这通常意味着更简洁的代码和更多可维护的代码。 这在更复杂的情况下变得更加明显,在这种情况下,实体的层次结构比该简单示例要深得多。 如果使用XJC之类的东西来生成POJO没关系,您仍然会感到代码膨胀。

请记住,JAXB被设置为比JAXP替代品(例如SAX和DOM)更简洁的编程模型,但是在具有深层次结构的场景中,使用JAXB对类进行概要分析并不能使它令人信服地更加简洁。 请记住,使用DOM和XPath甚至仅使用SAX来忽略不需要的类将非常容易。

MOXy通过提供对XML文件中的任何内容使用XPath表达式的功能,将清洁的战斗带回了JAXB。

注意:MOXy刚刚作为WebLogic 12c的JAXB实现包含在内。

参考文献:

  1. MOXy项目页面
  2. Blaise Doughan的博客
  3. 来自都柏林技术博客的 JCG合作伙伴 Alex Staveley 通过MOXy实现使JAXB清洁器

相关文章 :

  • 使用JAXB从XSD生成XML
  • 重用生成的JAXB类
  • 将对象映射到多个XML模式–天气示例
  • JAXB,SAX,DOM性能
  • 具有简单框架教程的Android XML绑定

翻译自: https://www.javacodegeeks.com/2012/01/make-your-jaxb-cleaner-with-moxy.html

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

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

相关文章

android 上下滚动文字_计算机毕设项目004之Android系统在线小说阅读器

计算机毕设项目004之Android系统在线小说阅读器一. 项目名称基于Android系统的在线小说阅读器二. 项目简介项目中的角色功能&#xff1a;支持翻页动画:仿真翻页、覆盖翻页、上下滚动翻页等翻页效果。支持页面定制:亮度调节、背景调节、字体大小调节支持全屏模式(含有虚拟按键的…

697. 数组的度

给定一个非空且只包含非负数的整数数组 nums&#xff0c;数组的 度 的定义是指数组里任一元素出现频数的最大值。 你的任务是在 nums 中找到与 nums 拥有相同大小的度的最短连续子数组&#xff0c;返回其长度。 来源&#xff1a;力扣&#xff08;LeetCode&#xff09; 链接&a…

python math模块

1.math简介 >>> import math >>>dir(math) #这句可查看所有函数名列表 [__doc__, __name__, __package__, acos, acosh, asin, asinh, atan, atan2, atanh, ceil, copysign, cos, cosh, degrees, e, erf, erfc, exp, expm1, fabs, factorial, flo…

Visual Studio找不到adb.exe错误解决

Visual Studio找不到adb.exe错误解决 错误信息&#xff1a;Cannot find adb.exe in specified SDK path。出现这种情况&#xff0c;是因为没有安装Android SDK Platform-tools。解决办法&#xff1a;在SDK Manager中&#xff0c;安装该组件即可。 转载于:https://www.cnblogs.c…

Vaadin应用程序中的EJB查找

自从我实现上一个服务定位器以来已经有很长时间了。 我认为不再需要考虑Java EE CDI &#xff08;上下文和依赖注入&#xff09;的成熟度。 我的第一个实现是在基于Struts的Web应用程序中使用EJB。 之后&#xff0c;我开始使用JSF&#xff0c;它只需要带有EJB或Resource的带注释…

基线检查工具_最新版CAD燕秀工具箱2.87(支持20042021)

好课推荐&#xff1a;零基础CAD&#xff1a;点我CAD家装&#xff1a;点我 周站长CAD&#xff1a;点我CAD机械&#xff1a;点我revit教程&#xff1a;点我CAD建筑&#xff1a;点我CAD三维&#xff1a;点我全屋定制&#xff1a;点我 ps教程&#xff1a;点我苹果版CAD:点我 3dmax教…

团队项目记录2

遇到的问题&#xff1a;在对Trigger机关进行测试时发现&#xff0c;画出的轨道也会将机关触发。 问题描述&#xff1a;Trigger机关的作用是在发生碰撞时运行脚本中指定的特定物体的特定函数&#xff0c;在这个例子当中特定的物体是一块地板&#xff0c;特定的函数的功能是删除这…

关于java.lang.ArithmeticException

java.lang.ArithmeticException “数学运算异常”&#xff0c;可能是自己的数学运算公式出现了错误、违反了数学运算规则。错误记录&#xff1a; 出错原因&#xff1a; a % b 中b不能为0

1103. Integer Factorization (30)

题目如下&#xff1a; The K-P factorization of a positive integer N is to write N as the sum of the P-th power of K positive integers. You are supposed to write a program to find the K-P factorization of N for any positive integers N, K and P. Input Specifi…

Java EE 6与Spring Framework:技术决策过程

在过去的几个月中&#xff0c;我们经历了这个决策过程&#xff1a;为Java平台上的企业开发选择哪种技术堆栈&#xff1f; 有多种选择。 但是&#xff0c;我们深入讨论的是&#xff1a;纯Java EE 6堆栈与带有Java EE的Spring。 以下博客文章总结了当您考虑这些技术堆栈选项之一时…

DOM 基础 HTML标签 元素 属性

什么是HTML标签 HTML标签标记了HTML文档和HTML元素 HTML标签由开始标签和结束标签组成.开始标签为尖括号包围的元素名,结束标签为尖括号包围的斜杠和元素名 例如:<h2> My First Heading</h2> HTML基本标签 标题(Heading)是通过h1 - h6等标签进行定义的.段落 是通过…

允许服务与桌面交互_vivo 正式推出 Origin OS,融合自然设计与全新交互

点击右上角关注我们&#xff0c;每天给您带来最新最潮的科技资讯&#xff0c;让您足不出户也知道科技圈大事&#xff01;今天下午&#xff0c;vivo 推出了全新 Origin OS 手机系统。它采用了源于自然界的设计理念&#xff0c;同时加入了全新并且允许用户进行深度自定义的交互方…

Error - Found cycle in the ListNode

Error - Found cycle in the ListNode 刷力扣时遇到这个错误&#xff0c;节点成环 自己摸索了一下发现确实形成循环&#xff0c;原题是206反转链表&#xff0c;我用的是栈&#xff0c;先将链表节点依次进栈&#xff0c;然后依次出栈链接&#xff0c;构成反转。但是我忽略了第一…

JUnit 4.9(测试版3)中的规则

不久前&#xff0c; David Saff宣布了JUnit 4.9的beta版 。 因此&#xff0c;我认为现在是研究该版本中的新增功能的好时机。 JUnit领域中最有用的创新之一是Rule。 我在这里写了有关规则的文章 。 我在这里写了有关JUnit规则的用例 。 规则很棒。 借助JUnit 4.9&#xff0c;它…

计算机网络-终端

我们常用的电脑来说&#xff0c;外围设备就是终端。 外围设备包括显示器、鼠标、键盘等等。 负责向主机输入数据的就叫输入终端&#xff0c;比如鼠标、键盘、麦克风、摄像头&#xff1b; 负责接收主机输出数据的设备就被称作输出终端&#xff0c;比如显示器、耳机。 注意一点…

为什么我喜欢Java的细节

他们说&#xff0c;Java太冗长了。 您可以找到Hello World程序的比较结果&#xff0c;这些程序在ruby中使用2行&#xff0c;在Java中使用10行&#xff0c;要读取文件&#xff0c;您需要使用Java 20行和php中1行。 尽管示例经常被夸大&#xff08;例如&#xff0c;计算导入次数&…

dll 源码_【技术分享】 | 一个JAVA内存马的源码分析

前言偶然接触到了这样一个JAVA内存马&#xff0c;其作者也是冰蝎的作者&#xff0c;项目地址&#xff1a;https://github.com/rebeyond/memShell正好最近在接触JAVA&#xff0c;借此机会学习下大佬的代码&#xff0c;对自己的编程思路也有了一定的提升。当然笔者只是一个脚本小…

ThunderSearch(闪电搜索器)_网络空间搜索引擎工具_信息收集

文章目录 ThunderSearch简介1 项目地址2 使用方式2.1 配置文件config.json说明2.2 构建和运行 3 使用式例 ThunderSearch简介 ThunderSearch&#xff08;闪电搜索器&#xff09;是一款使用多个(【支持Fofa、Shodan、Hunter、Zoomeye、360Quake网络空间搜索引擎】网络空间搜索引…

字符串匹配方法

介绍两种字符串匹配方法1.暴力匹配母串用s表示&#xff0c;长度为m子串用p表示&#xff0c;长度为n时间复杂度为:(m-n1)n算法&#xff1a;从s串的第一个字符开始匹配&#xff0c;若匹配&#xff0c;继续根据p向后匹配&#xff0c;若后续的不匹配&#xff0c;s右移重新匹配p 2.K…

区分几进制的标志

自己总是记不住进制的开头标记&#xff0c;就写下来忘了就看看 1.二进制&#xff1a;Binary&#xff0c;数字以0b 、0B开头 2.八进制&#xff1a;octal number system&#xff0c;数字自然以0打头 3.十六进制&#xff1a;hexadecimal&#xff0c;以0x、0X开头