使用JAXB实现xml转Java对象

这篇博客介绍了Java中的JAXB技术,主要用于XML数据和Java对象之间的转换。重点讲解了Marshaller和Unmarshaller两个核心类的功能,它们分别用于将Java对象序列化为XML和将XML反序列化为Java对象。文章详细阐述了解组(Unmarshal)过程,包括不同类型的解组方法,并强调了在没有明确映射或XML数据与JAXBContext不匹配时的处理策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

java xml bind

Marshaller 和 Unmashaller

Mashaller

Unmashaller

Unmarshaller 类管理将 XML 数据反序列化为新创建的 Java 对象的过程,可选择在解组时验证 XML 数据。 它为许多不同的输入类型提供了重载解组方法。

从文件解组:

	JAXBContext jc = JAXBContext.newInstance( "com.acme.foo" );
	Unmarshaller u = jc.createUnmarshaller();
	Object o = u.unmarshal( new File( "nosferatu.xml" ) );

从输入流解组:

	InputStream is = new FileInputStream( "nosferatu.xml" );
	JAXBContext jc = JAXBContext.newInstance( "com.acme.foo" );
	Unmarshaller u = jc.createUnmarshaller();
	Object o = u.unmarshal( is );

从URL解组:

 	JAXBContext jc = JAXBContext.newInstance( "com.acme.foo" );
 	Unmarshaller u = jc.createUnmarshaller();
 	URL url = new URL( "http://beaker.east/nosferatu.xml" );
 	Object o = u.unmarshal( url );

使用 javax.xml.transform.stream.StreamSource 从 StringBuffer 解组:

        JAXBContext jc = JAXBContext.newInstance( "com.acme.foo" );
        Unmarshaller u = jc.createUnmarshaller();
        StringBuffer xmlStr = new StringBuffer( "<?xml version="1.0"?>..." );
        Object o = u.unmarshal( new StreamSource( new StringReader( xmlStr.toString() ) ) );

从org.w3c.dom.Node解组:

        JAXBContext jc = JAXBContext.newInstance( "com.acme.foo" );
        Unmarshaller u = jc.createUnmarshaller();
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        dbf.setNamespaceAware(true);
        DocumentBuilder db = dbf.newDocumentBuilder();
        Document doc = db.parse(new File( "nosferatu.xml"));
        Object o = u.unmarshal( doc );

使用客户端指定的 SAX2.0 解析器从 javax.xml.transform.sax.SAXSource 解组:

        // configure a validating SAX2.0 parser (Xerces2)
        static final String JAXP_SCHEMA_LANGUAGE = "http://java.sun.com/xml/jaxp/properties/schemaLanguage";
        static final String JAXP_SCHEMA_LOCATION = "http://java.sun.com/xml/jaxp/properties/schemaSource";
        static final String W3C_XML_SCHEMA = "http://www.w3.org/2001/XMLSchema";
 
        System.setProperty( "javax.xml.parsers.SAXParserFactory", "org.apache.xerces.jaxp.SAXParserFactoryImpl" );
 
        SAXParserFactory spf = SAXParserFactory.newInstance();
        spf.setNamespaceAware(true);
        spf.setValidating(true);
        SAXParser saxParser = spf.newSAXParser();
 
        try {
            saxParser.setProperty(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA);
            saxParser.setProperty(JAXP_SCHEMA_LOCATION, "http://....");
        } catch (SAXNotRecognizedException x) {
            // exception handling omitted
        }
 
        XMLReader xmlReader = saxParser.getXMLReader();
        SAXSource source = new SAXSource( xmlReader, new InputSource( "http://..." ) );
 
        // Setup JAXB to unmarshal
        JAXBContext jc = JAXBContext.newInstance( "com.acme.foo" );
        Unmarshaller u = jc.createUnmarshaller();
        ValidationEventCollector vec = new ValidationEventCollector();
        u.setEventHandler( vec );
 
        // turn off the JAXB provider's default validation mechanism to
        // avoid duplicate validation
        u.setValidating( false )
        // unmarshal
        Object o = u.unmarshal( source );
 
        // check for events
        if( vec.hasEvents() ) {
           // iterate over events
        }

从StAX XMLStreamReader解组:

       JAXBContext jc = JAXBContext.newInstance( "com.acme.foo" );
       Unmarshaller u = jc.createUnmarshaller();

       javax.xml.stream.XMLStreamReader xmlStreamReader =
           javax.xml.stream.XMLInputFactory().newInstance().createXMLStreamReader( ... );

       Object o = u.unmarshal( xmlStreamReader );

从StAX XMLEventReader解组:

        JAXBContext jc = JAXBContext.newInstance( "com.acme.foo" );
        Unmarshaller u = jc.createUnmarshaller();
 
        javax.xml.stream.XMLEventReader xmlEventReader =
            javax.xml.stream.XMLInputFactory().newInstance().createXMLEventReader( ... );
 
        Object o = u.unmarshal( xmlEventReader );

解组 XML 数据
解组可以反序列化表示整个 XML 文档或 XML 文档子树的 XML 数据。
通常,使用全局声明的Unmarshal 根元素描述的解组方法就足够了。
这些解组方法利用 JAXBContext 将全局 XML 元素声明和类型定义映射到 JAXB 映射类来启动 XML 数据根元素的解组。
当 JAXBContext 的映射不足以解组 XML 数据的根元素时,应用程序可以通过使用声明类型的解组方法来帮助解组过程。
这些方法对于解组 XML 数据很有用,其中根元素对应于模式中的本地元素声明。

解组方法永远不会返回 null。
如果解组过程无法将 XML 内容的根解组到 JAXB 映射对象,则会报告致命错误,通过抛出 JAXBException 终止处理。

解组全局声明的根元素
没有declaredType的解组方法使用JAXBContext 解组 XML 数据的根元素。
JAXBContext实例是用于创建此解组器的实例。
JAXBContext实例维护全局声明的 XML 元素和类型定义名称到JAXB 映射类。
unmarshal 方法检查 JAXBContext 是否有映射从根元素的 XML 名称和/或 xsi:type 到 JAXB 映射类。
如果有,它会调整XML 数据使用适当的 JAXB 映射类。
请注意,当根元素名称未知且根元素有一个xsi:type,XML 数据被解组使用该 JAXB 映射类作为JAXBElement 的值。
当JAXBContext 对象没有根元素名称的映射时也不是它的 xsi:type,如果它存在,然后解组操作将通过抛出UnmarshalException 立即中止解组异常。可以通过使用解组来解决此异常情况下一小节中描述的声明类型方法。

按声明类型解组
带有declaredType的解组方法使应用程序能够反序列化 XML 数据的根元素,即使在根元素的 XML 名称的 JAXBContext 中没有映射时也是如此。
解组器使用指定为declaredType的应用程序提供的映射来解组根元素。
请注意,即使根元素的元素名称由 JAXBContext 映射,但在使用这些解组方法时,declaredType会覆盖用于反序列化根元素的映射。
此外,当 XML 数据的根元素具有 xsi:type 属性并且该属性的值引用由 JAXBContext 映射到 JAXB 映射类的类型定义时,根元素的 xsi:type 属性优先于解组方法中声明的类型参数 .
这些方法总是返回一个 JAXBElement 实例。
下表显示了如何设置返回的 JAXBElement 实例的属性。

按声明的类型解组返回的 JAXBElement
JAXBElement PropertyValue
namexml 元素名称
valuedeclaredType实例
declaredType解组方法declaredType参数
scopenull (actual scope is unknown)

下面是一个通过声明类型方法解组例子
根据 org.w3c.dom.Node 中的声明类型解组:
模式片段例如

<xs:schema>
	<xs:complexType name="FooType">...<\xs:complexType>
	<!-- 全局元素声明“PurchaseOrder”-->
	<xs:element name="PurchaseOrder">
		<xs:complexType>
			<xs:sequence>
				<!-- 局部元素声明“foo”-->
				<xs:element name="foo" type="FooType"/>
                     ...
				</xs:sequence>
		</xs:complexType>
	</xs:element>
</xs:schema>
    JAXBContext jc = JAXBContext.newInstance("com.acme.foo");
    Unmarshaller u = jc.createUnmarshaller();

    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    dbf.setNamespaceAware(true);
    DocumentBuilder db = dbf.newDocumentBuilder();
    文档 doc = db.parse(new File("nosferatu.xml"));
    元素 fooSubtree = ...; // 遍历 DOM 直到到达 xml 元素 foo,受 a 约束
                               // 模式中的本地元素声明。

    // FooType 是本地元素声明 foo 类型的 JAXB 映射。
    JAXBElement<FooType> foo = u.unmarshal( fooSubtree, FooType.class);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值