JAXB(Java Architecture for XML Binding)下载、使用

简介

JAXB(Java Architecture for XML Binding)就是XML数据绑定的java架构。JAXB可以根据XML Schema生成java类,也能根据java类生成XML Schema,能将XML数据unmarshall到Java内容树,也能将Java内容树持久化为XML数据。
JAXB提供了API和工具,可以自动在XML文档和java对象之间映射。

JAXB框架可以使开发者进行如下操作:

  • 将XML内容解包为java表示。
  • 访问和更新java表示。
  • 将java表示的XML内容打包回XML内容。

JAXB为开发者提供了一个高效、标准的方式来映射XML和java代码。java开发者的效率可以更高,因为他们可以写更少的代码,而且不必是XML专家。JAXB可以用到需要XML和Java互相转化的场景。JAXB使开发者结合XML和Web服务技术更加容易扩展他们的应用。
Java API for XML-Based Web Services(JAX-WS)底层的XML和Java绑定就是使用了JAXB。

各版本参考资源

JAXB 2.0版本参考资源

https://jcp.org/en/jsr/detail?id=222
在这里插入图片描述
JAXB 2.3版本详情页:
https://jcp.org/aboutJava/communityprocess/mrel/jsr222/index3.html
在这里插入图片描述

从该页面可以下载规范文档、和javadoc文档:
在这里插入图片描述
在这里插入图片描述
JAXB 2.3版本规范:
https://download.oracle.com/otn-pub/jcp/jaxb-2_3-mrel3-eval-spec/JAXB-2.3-spec.pdf
在这里插入图片描述

JAXB 3.0版本参考资源

https://jakarta.ee/specifications/xml-binding/3.0/
在这里插入图片描述

JAXB 4.0版本参考资源

https://jakarta.ee/specifications/xml-binding/4.0/
在这里插入图片描述

JAXB参考实现

旧版本(已经归档,只读)

https://github.com/javaee/jaxb-v2

这个项目库2019年2月份已经归档了,现在只读。新的项目这已经转移到https://github.com/eclipse-ee4j/jaxb-ri
在这里插入图片描述

新版本

代码库:https://github.com/eclipse-ee4j/jaxb-ri
主页:https://eclipse-ee4j.github.io/jaxb-ri/
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

下载zip独立发行包版本

打开主页:https://eclipse-ee4j.github.io/jaxb-ri/
点击右边的Download,可以下载最新的版本,例如jaxb-ri-4.0.3.zip:
在这里插入图片描述

将下载下来的压缩包解压,目录结构为:
在这里插入图片描述

bin子目录下的内容:
在这里插入图片描述

docs子目录下的内容:
在这里插入图片描述

mod子目录下的内容:
在这里插入图片描述

samples子目录下的内容:
在这里插入图片描述

对JDK版本的要求

参考实现4.0.3版本需要Java SE 11及以上。

利用运行时绑定框架

https://eclipse-ee4j.github.io/jaxb-ri/4.0.3/docs/release-documentation.html#section-3589085759105448

Schema到Java:开发应用的基本步骤

Schema转Java是将1个或多个schema文件编译为生成java类的过程。用这种方式开发一个应用的基本步骤如下:

  • 开发或者定位到schema
  • 如果需要的话,用绑定定制化注解schema,或者将它们放在一个外部的绑定文件
  • 用xjc绑定编译器编译schema,生成java内容类
    在这里插入图片描述
  • 用上面生成的java内容类和jakarta.xml.bind运行时框架来开发JAXB应用
  • 设置CLASSPATH变量,将下面的jar文件包含到路径中
    https://eclipse-ee4j.github.io/jaxb-ri/4.0.3/docs/ch02.html#jars
    在这里插入图片描述

上面的jar文件在下载包解压后的mod子目录下可以找到:
在这里插入图片描述

  • 用javac编译所有的java源文件
  • 运行程序

Java到Schema:开发应用的基本步骤

Java到Schema是利用jakarta.xml.bind.annotation包中的注解来增强已经存在的java类的过程,由此JAXB运行时绑定框架可以进行解包/打包的操作。用这种方式开发一个应用的基本步骤如下:

  • 设置CLASSPATH变量,将下面的jar文件包含到路径中
    https://eclipse-ee4j.github.io/jaxb-ri/4.0.3/docs/ch02.html#jars
    在这里插入图片描述
  • 用java开发数据模型
  • 利用jakarta.xml.bind.annotation包中的注解来控制绑定过程
  • 用数据模型开发应用;编写代码,用JAXB运行时框架的打包/解包操作持久化数据模型
  • 编译、运行应用

xjc(根据xml schema生成java代码)

备注:xjc命令行脚本只存在于JAXB的zip独立发行包版本中。

拉起xjc的方式

以在Windows下使用为例,可以运行bin目录下的批处理文件xjc.bat、或者mod目录下的jaxb-xjc.jar文件来拉起xjc。

xjc.bat文件在解压包的bin子目录下:
在这里插入图片描述
jaxb-xjc.jar文件在解压包的mod子目录下:
在这里插入图片描述

运行xjc.bat文件,例如:
在这里插入图片描述

运行jaxb-xjc.jar文件,例如:
在这里插入图片描述

xjc语法

可以通过运行xjc.bat文件、或者jaxb-xjc.jar文件,后面加上-help参数,来查看具体的用法,有哪些选项。
也可以查询官网来了解具体用法:
https://eclipse-ee4j.github.io/jaxb-ri/4.0.3/docs/ch04.html#tools-xjc

xjc [OPTION]... <schema file/URL/dir/jar> [-b <binding>...]

在这里插入图片描述
在这里插入图片描述

举例

根据一个schema文件生成java文件

例如,在cmd窗口下执行如下命令:

xjc D:\temp\xmlschema\test.xsd -d D:\temp\outcode

其中:
D:\temp\xmlschema\test.xsd指定schema文件
-d D:\temp\outcode指定生成的java文件存放目录。注意,输出目录必须已经存在,xjc编译器不会创建。
在这里插入图片描述

schema文件的内容:

<?xml version="1.0" encoding="UTF-8"?>
<!--Copyright (c) 1997, 2021 Oracle and/or its affiliates. All rights reserved.This program and the accompanying materials are made available under theterms of the Eclipse Distribution License v. 1.0, which is available athttp://www.eclipse.org/org/documents/edl-v10.php.SPDX-License-Identifier: BSD-3-Clause--><xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"><xs:import namespace="http://www.w3.org/XML/1998/namespace"schemaLocation="http://www.w3.org/2001/xml.xsd"/><xs:complexType name="foo"><xs:sequence><xs:element name="age" type="xs:int"/></xs:sequence></xs:complexType><xs:element name="root" type="foo"/></xs:schema>

到输出目录下查看生成的内容:
在这里插入图片描述
其中generated是默认生成的包名。

在这里插入图片描述

生成的Foo.java文件的内容:

//
// 此文件是由 Eclipse Implementation of JAXB v4.0.3 生成的
// 请访问 https://eclipse-ee4j.github.io/jaxb-ri 
// 在重新编译源模式时, 对此文件的所有修改都将丢失。
//package generated;import jakarta.xml.bind.annotation.XmlAccessType;
import jakarta.xml.bind.annotation.XmlAccessorType;
import jakarta.xml.bind.annotation.XmlType;/*** <p>foo complex type的 Java 类。* * <p>以下模式片段指定包含在此类中的预期内容。* * <pre>{@code* <complexType name="foo">*   <complexContent>*     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">*       <sequence>*         <element name="age" type="{http://www.w3.org/2001/XMLSchema}int"/>*       </sequence>*     </restriction>*   </complexContent>* </complexType>* }</pre>* * */
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "foo", propOrder = {"age"
})
public class Foo {protected int age;/*** 获取age属性的值。* */public int getAge() {return age;}/*** 设置age属性的值。* */public void setAge(int value) {this.age = value;}}

生成的ObjectFactory.java文件的内容:

//
// 此文件是由 Eclipse Implementation of JAXB v4.0.3 生成的
// 请访问 https://eclipse-ee4j.github.io/jaxb-ri 
// 在重新编译源模式时, 对此文件的所有修改都将丢失。
//package generated;import javax.xml.namespace.QName;
import jakarta.xml.bind.JAXBElement;
import jakarta.xml.bind.annotation.XmlElementDecl;
import jakarta.xml.bind.annotation.XmlRegistry;/*** This object contains factory methods for each * Java content interface and Java element interface * generated in the generated package. * <p>An ObjectFactory allows you to programmatically * construct new instances of the Java representation * for XML content. The Java representation of XML * content can consist of schema derived interfaces * and classes representing the binding of schema * type definitions, element declarations and model * groups.  Factory methods for each of these are * provided in this class.* */
@XmlRegistry
public class ObjectFactory {private static final QName _Root_QNAME = new QName("", "root");/*** Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: generated* */public ObjectFactory() {}/*** Create an instance of {@link Foo }* * @return*     the new instance of {@link Foo }*/public Foo createFoo() {return new Foo();}/*** Create an instance of {@link JAXBElement }{@code <}{@link Foo }{@code >}* * @param value*     Java instance representing xml element's value.* @return*     the new instance of {@link JAXBElement }{@code <}{@link Foo }{@code >}*/@XmlElementDecl(namespace = "", name = "root")public JAXBElement<Foo> createRoot(Foo value) {return new JAXBElement<>(_Root_QNAME, Foo.class, null, value);}}

schemagen(根据java文件生成schema)

备注:schemagen命令行脚本只存在于JAXB的zip独立发行包版本中。

介绍

schemagen可以处理java源文件、或者class文件。

拉起schemagen的方式

以windows为例,可以运行bin目录下的schemagen.bat文件来拉起schemagen。
如果java源文件或者类文件引用了其它的类,那么被引用的类必须通过系统环境变量CLASSPATH可以访问到,否则就必须在工具命令中通过-classpath/ -cp可选参数来指定。
例如:
在这里插入图片描述

schemagen语法

介绍

schemagen [-options ...] <java files>

可以通过官网查看命令参数详细介绍:
https://eclipse-ee4j.github.io/jaxb-ri/4.0.3/docs/ch04.html#tools-schemagen
在这里插入图片描述

或者执行schemagen -help命令查看帮助信息:
在这里插入图片描述

查看帮助信息

执行命令:

schemagen -help

在这里插入图片描述

查看版本信息

执行命令:

schemagen -version

在这里插入图片描述

查看完整版本信息

执行命令:

schemagen -fullversion

在这里插入图片描述

举例

根据java源文件生成schema文件

java源文件的内容如下。其中属性name用了JavaBeans样式(get和set),属性age用了JAXB的注释:

package com.thb;import jakarta.xml.bind.annotation.XmlElement;public class Demo {private String name;@XmlElementprivate int age;public String getName() {return this.name;}public void setName(String name) {this.name = name;}
}

执行命令及输出:

schemagen D:\temp\eclipse-workspace\java_work\java_test2\src\com\thb\Demo.java -d D:\temp\outschema

其中 -d D:\temp\outschema指定了生成的schema文件、class文件的存放路径。
在这里插入图片描述
到outschema目录下查看生成的内容:
在这里插入图片描述
可以看到,生成了schema文件schema1.xsd,另外,也将java源文件编译成了class文件。

打开生成的schema1.xsd文件,内容如下:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema"><xs:complexType name="demo"><xs:sequence><xs:element name="age" type="xs:int"/><xs:element name="name" type="xs:string" minOccurs="0"/></xs:sequence></xs:complexType>
</xs:schema>

通过maven下载JAXB的Eclipse实现

在maven工程的pom.xml文件中依赖部分增加如下片段:

  <dependencies><dependency><groupId>jakarta.xml.bind</groupId><artifactId>jakarta.xml.bind-api</artifactId><version>4.0.0</version></dependency><dependency><groupId>com.sun.xml.bind</groupId><artifactId>jaxb-impl</artifactId><version>4.0.3</version></dependency></dependencies>

xml简单数据类型到java类型的映射

xml中用简单类型定义的schema部件(component)通常绑定一个java属性。

xml原子类型到java类型的映射

https://jakarta.ee/specifications/xml-binding/4.0/jakarta-xml-binding-spec-4.0#atomic-datatype
所谓原子类型,就是XML规范认为值不可再分的数据类型。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

XmlElement注解

介绍

https://jakarta.ee/specifications/xml-binding/4.0/apidocs/jakarta.xml.bind/jakarta/xml/bind/annotation/xmlelement

jakarta.xml.bind.annotation.XmlElement注解的作用是将一个JavaBean 属性映射到一个XML 元素,元素的名字取自属性的名字。
在这里插入图片描述

举例:将一个 XmlElement注解的java类的属性映射为一个XML的元素,元素的名字默认就是java类的名字

java类的源码:

package com.thb;import jakarta.xml.bind.annotation.XmlElement;public class Request {@XmlElementprivate String reqType;
}

用schemagen命令生成schema:
在这里插入图片描述
schema文件的内容:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema"><xs:complexType name="request"><xs:sequence><xs:element name="reqType" type="xs:string" minOccurs="0"/></xs:sequence></xs:complexType>
</xs:schema>

从上面内容可以看出,java中的属性reqType映射到了 xml中的元素reqType,元素的名字默认就是java中属性的名字。

举例:java类的属性没有使用JAXB注解,也没有采用JavaBean样式(即没有get 和 set),不会转化为xml的元素

java类的内容,其中age没有使用JAXB注解,也没有采用JavaBean样式(即没有get 和 set):

package com.thb;import jakarta.xml.bind.annotation.XmlElement;public class Request {@XmlElementprivate String reqType;private int age;
}

用schemagen命令生成schema:
在这里插入图片描述
schema文件的内容:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema"><xs:complexType name="request"><xs:sequence><xs:element name="reqType" type="xs:string" minOccurs="0"/></xs:sequence></xs:complexType>
</xs:schema>

可以看到,java的属性age没有被转换为XML的属性。

举例:java类的属性没有使用JAXB注解,但采用JavaBean样式(即有get 和 set),会转化为xml的元素

java类的源码,其中age没有使用JAXB注解,但有getter和setter:

package com.thb;import jakarta.xml.bind.annotation.XmlElement;public class Request {@XmlElementprivate String reqtype;private int age;public void setAge(int age) {this.age = age;}public int getAge() {return this.age;}
}

用schemagen命令生成schema:
在这里插入图片描述
schema文件的内容:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema"><xs:complexType name="request"><xs:sequence><xs:element name="reqtype" type="xs:string" minOccurs="0"/><xs:element name="age" type="xs:int"/></xs:sequence></xs:complexType>
</xs:schema>

可以看到,java类的JavaBean属性age转换到了XML的元素age。

举例:java类的属性使用JAXB注解,并且采用JavaBean样式(即有get 和 set),转换的时候会报错

java代码:

package com.thb;import jakarta.xml.bind.annotation.XmlElement;public class Request {@XmlElementprivate String reqtype;public void setReqtype(String reqtype) {this.reqtype = reqtype;}public String getReqtype() {return this.reqtype;}
}

用schemagen命令生成schema的时候报错:
在这里插入图片描述

举例:用XmlElement注解的name属性指定XML中元素的名字

java代码如下,其中reqType采用驼峰写法,用XmlElement注解的name属性指定XML中元素的名字是reqtype(不是驼峰写法):

package com.thb;import jakarta.xml.bind.annotation.XmlElement;public class Request {@XmlElement(name = "reqtype")private String reqType;
}

用schemagen命令生成schema:
在这里插入图片描述
schema文件的内容:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema"><xs:complexType name="request"><xs:sequence><xs:element name="reqtype" type="xs:string" minOccurs="0"/></xs:sequence></xs:complexType>
</xs:schema>

举例:用XmlElement注解的name属性指定XML中元素的名字采用java属性的名字

java代码如下,其中XmlElement注解的name属性的值等于"##default",表示XML中元素的名字就采用java属性的名字:

package com.thb;import jakarta.xml.bind.annotation.XmlElement;public class Request {@XmlElement(name = "##default")private String reqType;
}

用schemagen命令生成schema:
在这里插入图片描述
schema文件的内容:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema"><xs:complexType name="request"><xs:sequence><xs:element name="reqType" type="xs:string" minOccurs="0"/></xs:sequence></xs:complexType>
</xs:schema>

举例:XmlElement注解的required属性值等于true

java代码如下,其中XmlElement注解的required 属性的值等于true。在此情况下,如果java属性是单值数据,那么该XML元素的minOccurs=“1”,maxOccurs=“1”;如果java属性是多值数据,那么XML元素的minOccurs=“1”,maxOccurs=“unbounded”:

package com.thb;import jakarta.xml.bind.annotation.XmlElement;public class Request {@XmlElement(name = "reqtype", required = true)private String reqType;@XmlElement(required = true)private String[] events;
}

用schemagen命令生成schema:
在这里插入图片描述

schema文件的内容:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema"><xs:complexType name="request"><xs:sequence><xs:element name="reqtype" type="xs:string"/><xs:element name="events" type="xs:string" maxOccurs="unbounded"/></xs:sequence></xs:complexType>
</xs:schema>

举例:XmlElement注解的required属性值为false

java代码如下,其中XmlElement注解的required 属性的值等于false。在此情况下,如果java属性是单值数据,那么该XML元素的minOccurs=“0”,maxOccurs=“1”;如果java属性是多值数据,那么XML元素的minOccurs=“0”,maxOccurs=“unbounded”:

package com.thb;import jakarta.xml.bind.annotation.XmlElement;public class Request {@XmlElement(name = "reqtype", required = false)private String reqType;@XmlElement(required = false)private String[] events;
}

用schemagen命令生成schema:
在这里插入图片描述
schema文件的内容:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema"><xs:complexType name="request"><xs:sequence><xs:element name="reqtype" type="xs:string" minOccurs="0"/><xs:element name="events" type="xs:string" minOccurs="0" maxOccurs="unbounded"/></xs:sequence></xs:complexType>
</xs:schema>

XmlRootElement注解

介绍

jakarta.xml.bind.annotation.XmlRootElement注解的作用是将一个java类、或者枚举类型映射为XML元素(element)。
XmlRootElement注解可以用在顶层类、或者枚举。

XmlRootElement注解的类必须有一个公共、或者保护、或者包类型的不带参数的构造器。

举例:XmlRootElement注解的类没有不带参数的构造器,生成schema时出错

java代码:

package com.thb;import jakarta.xml.bind.annotation.XmlElement;
import jakarta.xml.bind.annotation.XmlRootElement;@XmlRootElement
public class Point {@XmlElementprivate int x;@XmlElementprivate int y;//public Point() {}public Point(int x, int y) {this.x = x;this.y = y;}
}

执行生成schema的命令,出错:
在这里插入图片描述

举例:XmlRootElement注解的类有不带参数的构造器,正常生成schema

java代码:

package com.thb;import jakarta.xml.bind.annotation.XmlElement;
import jakarta.xml.bind.annotation.XmlRootElement;@XmlRootElement
public class Point {@XmlElementprivate int x;@XmlElementprivate int y;public Point() {}public Point(int x, int y) {this.x = x;this.y = y;}
}

执行生成schema的命令:
在这里插入图片描述
生成的schema文件的内容:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema"><xs:element name="point" type="point"/><xs:complexType name="point"><xs:sequence><xs:element name="x" type="xs:int"/><xs:element name="y" type="xs:int"/></xs:sequence></xs:complexType>
</xs:schema>

JAXBContext、Marshaller、Unmarshaller

JAXBContext介绍

jakarta.xml.bind.JAXBContext类提供了到Jakarta XML 绑定API的入口点,它提供了管理XML/Java绑定信息的抽象,这些绑定信息对于实现Jakarta XML绑定框架操作是需要的。涉及到的操作有:打包(marshal )、解包(unmarshal)、验证(validate)。

newInstance方法的参数可以是需要被JAXBContext识别的类

在这里插入图片描述
例如:

JAXBContext context = JAXBContext.newInstance(Point.class);

newInstance方法的参数也可以是需要被JAXBContext识别的类的上下文路径

上下文路径就是包名的列表,包内包含schema导出的类、和(或者)java到schema映射的类(即(Jakarta XML Binding-annotated),多个包名之间用冒号(:)分割。在这里插入图片描述
例如:

JAXBContext.newInstance( "com.acme.foo:com.acme.bar" )

如果newInstance方法传入的是上下文路径,其中包含的每个包必须满足下面条件中的一个、或者两个,否则就会抛出JAXBException :

  • 包含ObjectFactory.class
  • 包含jaxb.index文件

其中jaxb.index文件是一个资源文件,罗列出了被JAXB注解的XML 绑定映射的类。

jaxb.index文件的格式:

  • 文件中包含了被新行分割的lei类名列表
  • 空格、tab、空行被忽略
  • 注释符号用’#’ (0x23)
  • 在每一行,紧跟注释符的字符被忽略
  • 文件必须采用 UTF-8编码

jaxb.index文件中类名的限制:

  • 不能以.class结尾
  • 类名必须相对包含*jaxb.index文件的包来解析。只有直接包含在该包中的类名才允许放在该文件中。
  • 完全限定的类名不允许。相对当前包的限定类名只有声明一个嵌套类或者一个内部类的时候才允许。

例如工程目录结构如下:
在这里插入图片描述
文件的内容:
在这里插入图片描述

Marshaller介绍

  • jakarta.xml.bind.Marshaller控制将java内容树序列化到XML数据的过程。
  • 客户端可以marshall java内容树到java.io.OutputStream、或者java.io.Writer。

Unmarshaller

jakarta.xml.bind.Unmarshaller用来控制将XML数据反序列到新创建的java内容树的过程。可选地,可以在反序列化过程中,校验XML数据的正确性。

举例:newInstance函数的参数是需要JAXBContext识别的java类、将java内容树marshall到了System.out

调用JAXBContext.newInstance(Point.class)函数,传递了需要JAXBContext识别的java类Point.class,将java内容树marshall到System.out,设置Marshaller的JAXB_FORMATTED_OUTPUT属性为true(表示对生成的xml数据用换行、缩进格式化):

package com.thb;import jakarta.xml.bind.JAXBContext;
import jakarta.xml.bind.JAXBException;
import jakarta.xml.bind.Marshaller;public class Demo {public static void main(String[] args) throws JAXBException {        JAXBContext context = JAXBContext.newInstance(Point.class);Marshaller marshaller = context.createMarshaller();marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);marshaller.marshal(new Point(1, 2), System.out);}}
package com.thb;import jakarta.xml.bind.annotation.XmlElement;
import jakarta.xml.bind.annotation.XmlRootElement;@XmlRootElement
public class Point {@XmlElementprivate int x;@XmlElementprivate int y;public Point() {}public Point(int x, int y) {this.x = x;this.y = y;}
}

用maven的mvn命令运行程序:
在这里插入图片描述
将生成的xml数据打印到了System.out。

举例:不设置 Marshaller的JAXB_FORMATTED_OUTPUT属性

不设置Marshaller的JAXB_FORMATTED_OUTPUT属性(表示对生成的xml数据不用换行、缩进格式化):

package com.thb;import jakarta.xml.bind.JAXBContext;
import jakarta.xml.bind.JAXBException;
import jakarta.xml.bind.Marshaller;public class Demo {public static void main(String[] args) throws JAXBException {        JAXBContext context = JAXBContext.newInstance(Point.class);Marshaller marshaller = context.createMarshaller();       marshaller.marshal(new Point(1, 2), System.out);}}
package com.thb;import jakarta.xml.bind.annotation.XmlElement;
import jakarta.xml.bind.annotation.XmlRootElement;@XmlRootElement
public class Point {@XmlElementprivate int x;@XmlElementprivate int y;public Point() {}public Point(int x, int y) {this.x = x;this.y = y;}
}

用maven的mvn命令运行程序:
在这里插入图片描述
可以看出,生成的xml结果没有格式化。

举例:newInstance​传入上下文路径,但包路径下没有ObjectFactory.class文件,也没有jaxb.index文件,运行抛出异常

java代码:

package com.thb;import jakarta.xml.bind.JAXBContext;
import jakarta.xml.bind.JAXBException;
import jakarta.xml.bind.Marshaller;public class Demo {public static void main(String[] args) throws JAXBException {      JAXBContext context = JAXBContext.newInstance("com.thb");Marshaller marshaller = context.createMarshaller();marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);marshaller.marshal(new Point(1, 2), System.out);}}
package com.thb;import jakarta.xml.bind.annotation.XmlElement;
import jakarta.xml.bind.annotation.XmlRootElement;@XmlRootElement
public class Point {@XmlElementprivate int x;@XmlElementprivate int y;public Point() {}public Point(int x, int y) {this.x = x;this.y = y;}
}

运行抛出JAXBException异常:
在这里插入图片描述

举例:newInstance​传入上下文路径,包路径下有jaxb.index文件,运行正常

例如工程目录结构如下:
在这里插入图片描述
jaxb.index文件的内容:
在这里插入图片描述

java代码:

package com.thb;import jakarta.xml.bind.JAXBContext;
import jakarta.xml.bind.JAXBException;
import jakarta.xml.bind.Marshaller;public class Demo {public static void main(String[] args) throws JAXBException {      JAXBContext context = JAXBContext.newInstance("com.thb");Marshaller marshaller = context.createMarshaller();marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);marshaller.marshal(new Point(1, 2), System.out);}}
package com.thb;import jakarta.xml.bind.annotation.XmlElement;
import jakarta.xml.bind.annotation.XmlRootElement;@XmlRootElement
public class Point {@XmlElementprivate int x;@XmlElementprivate int y;public Point() {}public Point(int x, int y) {this.x = x;this.y = y;}
}

运行正常:
在这里插入图片描述

marshall到文件

java代码:

package com.thb;import java.io.FileNotFoundException;
import java.io.FileOutputStream;import jakarta.xml.bind.JAXBContext;
import jakarta.xml.bind.JAXBException;
import jakarta.xml.bind.Marshaller;public class Demo {public static void main(String[] args) throws JAXBException, FileNotFoundException {      JAXBContext context = JAXBContext.newInstance(Point.class);Marshaller marshaller = context.createMarshaller();marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);      marshaller.marshal(new Point(1, 2), new FileOutputStream("D:/temp/outputdata/point.xml"));}}
package com.thb;import jakarta.xml.bind.annotation.XmlElement;
import jakarta.xml.bind.annotation.XmlRootElement;@XmlRootElement
public class Point {@XmlElementprivate int x;@XmlElementprivate int y;public Point() {}public Point(int x, int y) {this.x = x;this.y = y;}
}

运行:
在这里插入图片描述
输出文件的内容:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<point><x>1</x><y>2</y>
</point>

设置marshall的编码格式

java代码:

package com.thb;import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;import jakarta.xml.bind.JAXBContext;
import jakarta.xml.bind.JAXBException;
import jakarta.xml.bind.Marshaller;
import jakarta.xml.bind.Unmarshaller;public class Demo {public static void main(String[] args) throws JAXBException, FileNotFoundException {final File file = new File("D:/temp/outputdata/point.xml");JAXBContext context = JAXBContext.newInstance(Point.class);Marshaller marshaller = context.createMarshaller();marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");      marshaller.marshal(new Point(1, 2), new FileOutputStream(file));}}
package com.thb;import jakarta.xml.bind.annotation.XmlElement;
import jakarta.xml.bind.annotation.XmlRootElement;@XmlRootElement
public class Point {@XmlElementprivate int x;@XmlElementprivate int y;public Point() {}public Point(int x, int y) {this.x = x;this.y = y;}
}

运行:
在这里插入图片描述
输出文件的内容:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<point><x>1</x><y>2</y>
</point>

将xml数据反序列化到java内容树

java代码:

package com.thb;import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;import jakarta.xml.bind.JAXBContext;
import jakarta.xml.bind.JAXBException;
import jakarta.xml.bind.Marshaller;
import jakarta.xml.bind.Unmarshaller;public class Demo {public static void main(String[] args) throws JAXBException, FileNotFoundException {final File file = new File("D:/temp/outputdata/point.xml");JAXBContext context = JAXBContext.newInstance(Point.class);Marshaller marshaller = context.createMarshaller();marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);       marshaller.marshal(new Point(1, 2), new FileOutputStream(file));Unmarshaller unMarshaller = context.createUnmarshaller();Object point = unMarshaller.unmarshal(file);marshaller.marshal(point, System.out);}}
package com.thb;import jakarta.xml.bind.annotation.XmlElement;
import jakarta.xml.bind.annotation.XmlRootElement;@XmlRootElement
public class Point {@XmlElementprivate int x;@XmlElementprivate int y;public Point() {}public Point(int x, int y) {this.x = x;this.y = y;}
}

运行输出:
在这里插入图片描述

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

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

相关文章

【煤矿虚拟仿真体验】VR采煤机技能培训有效提高训练效果

在我们的社会中&#xff0c;能源是至关重要的。它是推动我们日常生活和工作的主要动力。然而&#xff0c;我们在获取这种能源的过程中&#xff0c;也带来了许多环境问题。煤矿开采是其中的一个重要部分&#xff0c;因此我们需要寻找更环保、更安全的方式来进行煤矿开采。VR&…

手把手教你用 Milvus 和 Towhee 搭建一个 AI 聊天机器人

作为向量数据库的佼佼者&#xff0c;Milvus 适用于各种需要借助高效和可扩展向量搜索功能的 AI 应用。 举个例子&#xff0c;如果想要搭建一个聊天机器人&#xff0c;Milvus 一定是其进行数据管理的首选。那么&#xff0c;如何让这个应用程序开发变得易于管理及更好理解&#x…

LeetCode算法二叉树—222. 完全二叉树的节点个数

目录 222. 完全二叉树的节点个数 - 力扣&#xff08;LeetCode&#xff09; 代码&#xff1a; 运行结果&#xff1a; 给你一棵 完全二叉树 的根节点 root &#xff0c;求出该树的节点个数。 完全二叉树 的定义如下&#xff1a;在完全二叉树中&#xff0c;除了最底层节点可能…

2023-09-28 monetdb-db,schema,user,role-分析

摘要: 对moentdb的database,schema,user,role和权限做分析, 以与mysql中的概念做对比分析. 备份: https://stoneatom.yuque.com/staff-ft8n1u/qfqtnb/gfqc62fozh0qsyqm 上下文相关: 2023-09-28 mysql-代号m-schema调研-文档记录-CSDN博客 2023-09-28 monetdb-databae的概念和…

湖南软件测评公司简析:软件功能测试和非功能测试的联系和区别

一、软件功能测试   软件功能测试旨在验证软件是否按照需求规格说明书的要求正常工作。具体而言&#xff0c;功能测试会对软件的所有功能进行测试&#xff0c;以确保其满足用户的需求和预期。在进行功能测试时&#xff0c;根据需求规格说明书编写测试用例&#xff0c;并在测试…

时序预测 | MATLAB实现POA-CNN-BiLSTM鹈鹕算法优化卷积双向长短期记忆神经网络时间序列预测

时序预测 | MATLAB实现POA-CNN-BiLSTM鹈鹕算法优化卷积双向长短期记忆神经网络时间序列预测 目录 时序预测 | MATLAB实现POA-CNN-BiLSTM鹈鹕算法优化卷积双向长短期记忆神经网络时间序列预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 MATLAB实现POA-CNN-BiLSTM鹈鹕算…

ad18学习笔记十一:显示和隐藏网络、铺铜

如何显示和隐藏网络&#xff1f; Altium Designer--如何快速查看PCB网络布线_ad原理图查看某一网络的走线_辉_0527的博客-CSDN博客 AD19(Altium Designer)如何显示和隐藏网络 如何显示和隐藏铺铜&#xff1f; Altium Designer 20在PCB中显示或隐藏每层铺铜-百度经验 AD打开与…

优化Python开发环境的几个神技巧

用Python编代码体验极佳&#xff0c;并且随着新版本的发布越来越好&#xff01; 对于很多人而言&#xff0c;Python提供的大量免费函数库、高可读性的程序和新引入的类型注释让很多爱不释手。 然而&#xff0c;数据科学家特别容易使自己的Jupyter notebook变得庞大而杂乱&…

计算机里的神灵(SCIP)

计算机程序的构造和解释 我找到计算机里的神灵了&#xff0c;开心一刻 下面是从MIT官网下载的 SCIP求值器&#xff08;解释器&#xff09;的代码&#xff0c;这个官网是个宝藏库 还有其他视频课程和 SCIP的问题答案和可运行代码 链接&#xff1a;https://ocw.mit.edu/courses/6…

力扣-349.两个数组的交集

Idea 使用两个哈希集合&#xff0c;其中一个用来存储第一个数组&#xff0c;第二个来存储两个数组的交集&#xff0c;因为集合自带去重功能&#xff0c;因此最后用数组来接收就好了 AC Code class Solution { public:vector<int> intersection(vector<int>& n…

Android gradle dependency tree change(依赖树变化)监控实现

文章目录 前言基本原理执行流程diff 报告不同分支 merge 过来的 diff 报告同个分支产生的 merge 报告同个分支提交的 diff 报告 具体实现原理我们需要监控怎样的 Dendenpency 变化怎样获取 dependency Treeproject.configurations 方式./gradlew dependenciesAsciiDependencyRe…

什么是推挽电路?

推挽电路原理&#xff1a; 可以简单理解为推和拉&#xff1b; 此电路总共用到两个元器件&#xff0c;对应图中的Q1----NPN三极管&#xff0c;Q2----PNP三极管&#xff0c;两个电阻R1和R2起到限流的作用&#xff1b;两个三极管的中间对应信号的输出。 下面就举例说明是如何工作的…

uniapp 微信小程序之隐私协议开发

uniapp 微信小程序之隐私协议开发 官网通知&#xff1a;https://developers.weixin.qq.com/miniprogram/dev/framework/user-privacy/PrivacyAuthorize.html 1、配置 __usePrivacyCheck__: true&#xff1b;位置 manifest.json : "mp-weixin":{"__usePrivacyCh…

急救车工业路由器应用提升急救效率:车联网、数据采集与远程诊疗

急救车作为医院里医疗急救过程中的重要组成部分&#xff0c;在智慧医疗物联网领域中急救车应用4G工业路由器实现网络部署与数据采集&#xff0c;通过工业4G路由器能够实时采集到病患的生理数据、救护现场音频与视频、GPS定位以及车辆运行状态等重要信息。这些数据将被传输到医疗…

计算机毕业设计 基于HTML语言的环保网站的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

SVN状态图标不显示

问题可能点1&#xff1a;图标覆盖 1、右键找到设置 2、找到图标覆盖 3、重启TortoiseSVN 问题可能点2&#xff1a;注册表图标顺序太靠下&#xff0c;被占用 1、windowsr, 输入regedit进入注册表 2、找到一下目录 计算机\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Cu…

基于微信小程序的奶茶点餐小程序设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言系统主要功能&#xff1a;具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09;有保障的售后福利 代码参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计…

flink集群与资源@k8s源码分析-总述

1 简介 集群和资源模块提供动态资源能力,是分布式系统关键基础设施,分布式datax,分布式索引,事件引擎都需要集群和资源的弹性资源能力,提高伸缩性和作业处理能力。本文分析flink的集群和资源的k8s模块,深入了解其设计原理,为开发自有的集群和资源组件做技术准备, 同时涉…

云计算与大数据——部署Hadoop集群并运行MapReduce集群(超级详细!)

云计算与大数据——部署Hadoop集群并运行MapReduce集群(超级详细&#xff01;) Linux搭建Hadoop集群(CentOS7hadoop3.2.0JDK1.8Mapreduce完全分布式集群) 本文章所用到的版本号&#xff1a; CentOS7 Hadoop3.2.0 JDK1.8 基本概念及重要性 很多小伙伴部署集群用hadoop用mapr…

运动控制:音圈电机

在运动平台中&#xff0c;对于微小运动&#xff0c;例如1-5毫米&#xff0c;甚至更小的行程&#xff0c;常用音圈电机来驱动。 因为它们具有体积小&#xff0c;运动质量小&#xff0c;高加速度等显著特征。 无论是在工业领域&#xff0c;还是在医用内窥镜&#xff0c;呼吸机&…