使用JAXB 进行XML格式数据导入导出 Restful service

JAXB技术介绍(引用的)

Java Architecture for XML Binding (JAXB) 是一个业界的标准,是一项可以根据XML Schema产生Java类的技术。该过程中,JAXB也提供了将XML实例文档反向生成Java对象树的方法,并能将Java对象树的内容重新写到XML实例文档。从另一方面来讲,JAXB提供了快速而简便的方法将XML模式绑定到Java表示,从而使得Java开发者在Java应用程序中能方便地结合XML数据和处理函数。

这意味着你不需要处理甚至不需要知道XML编程技巧就能在Java应用程序中利用平台核心XML数据的灵活性。而且,可以充分利用XML的优势而不用依赖于复杂的XML处理模型如SAX或DOM。JAXB 隐藏了细节并且取消了SAX和DOM中没用的关系——生成的JAXB类仅描述原始模型中定义的关系。其结果是结合了高度可移植Java代码和高度可移植的XML数据。其中这些代码可用来创建灵活、轻便的应用程序和Web服务。

JAXB的体系结构和应用过程如图所示,一般来说包含以下几个步骤:

1)        根据你的应用程序所要操作的XML数据格式,撰写相应的XMLSchema,有关XML
Schema的知识,请参阅“参考资料

2)        使用JAXB 所带的编译工具(Binding Compiler),将这个XMLSchema文件作为输入,产生一系列相关的Java
Class和Interface

3)        在使用JAXB编译工具的时候,可以有选择性的提供一个配置文件(图的虚线部分),来控制JAXB编译工具的一些高级属性。

4)        这些Java Class和Interface是你的应用程序操纵XML数据的主要接口和方法。

5)        通过JAXB对XML文档进行的操作主要包括:将符合XML
Schema规定的XML文档解析生成一组相应的Java对象;对这些对象进行操作(修改、增加和删除对象的属性等等);然后将这些对象的内容保存到这个XML文档中。

JDK中JAXB相关的重要Annotation:

@XmlType,将Java类或枚举类型映射到XML模式类型

@XmlAccessorType(XmlAccessType.FIELD),控制字段或属性的序列化。FIELD表示JAXB将自动绑定Java类中的每个非静态的(static)、非瞬态的(由@XmlTransient标注)字段到XML。其他值还有XmlAccessType.PROPERTY和XmlAccessType.NONE。

@XmlAccessorOrder,控制JAXB绑定类中属性和字段的排序。

@XmlJavaTypeAdapter,使用定制的适配器(即扩展抽象类XmlAdapter并覆盖marshal()和unmarshal()方法),以序列化Java类为XML。

@XmlElementWrapper,对于数组或集合(即包含多个元素的成员变量),生成一个包装该数组或集合的XML元素(称为包装器)。

@XmlRootElement,将Java类或枚举类型映射到XML元素。

@XmlElement,将Java类的一个属性映射到与属性同名的一个XML元素。

@XmlAttribute,将Java类的一个属性映射到与属性同名的一个XML属性。

1 定义数据格式xml Schema :DemoSchema.xsd

<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.example.org/DemoSchema"
    xmlns:xs="http://www.example.org/DemoSchema" elementFormDefault="qualified">
  <element name="movie" type="xs:Movie"/>
        <complexType name="ObjectInfo">
        	    <sequence>
		        <element name="id" type="string" />
		        <element name="image-url" type="string" nillable="true"/>
		        <element name="priority" type="int" nillable="true"/>
		        <element name="localized" type="xs:Localized" nillable="true"/>
		        </sequence>
        </complexType>

          <!--localized-->
	   <complexType name="Localized">
	         <sequence>
	            <element name="lang" type="xs:Lang" minOccurs="0"  maxOccurs="unbounded" nillable="true"/>
	          </sequence>
	     </complexType>
	  <!--lang-->
	   <complexType name="Lang">
	     <sequence>
	        <element name="code" type="string" />
	        <element name="name" type="string" nillable="true"/>
	        <element name="attribute" type="string" nillable="true"/>
	        <element name="description" type="string" nillable="true"/>
	     </sequence>
	   </complexType>
        <complexType name="Movie">
        	<sequence>
        		<element name="object-Infos" type="xs:ObjectInfos" maxOccurs="1" minOccurs="0"></element>
        	</sequence>
        </complexType>

        <complexType name="ObjectInfos">
        	<sequence>
        		<element name="object-info" type="xs:ObjectInfo" maxOccurs="unbounded" minOccurs="0"></element>
        	</sequence>
        </complexType>
</schema>

可以使用图形界面来编辑 Schema

Schema 编辑完成以后,导出 Schema 的model 类

导出的 model 类的list

需要在 Movie 的类中配置XML 根节点@XmlRootElement

数据导入DemoFileUploadController

package com.jason.example.controller;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Iterator;
import java.util.List;

import javax.servlet.http.HttpServletResponse;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import com.jason.example.model.Movie;
import com.jason.example.model.ObjectFactory;
import com.jason.example.model.ObjectInfo;

@Controller
public class DemoFileUploadController {
    private static final Log logger = LogFactory.getLog(DemoFileUploadController.class);
    @RequestMapping(value = "/demoupload", method = RequestMethod.POST)
    public String upload(ModelMap model, MultipartHttpServletRequest request, HttpServletResponse response) throws IOException {
        String fileName = "";
        StringBuffer content = new StringBuffer();
        Iterator<String> itr1 = request.getFileNames();
        MultipartFile multipartFile = request.getFile(itr1.next());
        fileName = multipartFile.getOriginalFilename();
        InputStream in = multipartFile.getInputStream();
        BufferedInputStream bis = new BufferedInputStream(in);
        BufferedReader d = new BufferedReader(new InputStreamReader(bis));
        String xsdPath = this.getClass().getClassLoader().getResource("DemoSchema.xsd").getPath();
        System.out.println("check xsd path=" + xsdPath);
        String line = null;
        while ((line = d.readLine()) != null) {
            System.out.println(line);
            content.append(line + "\n");
        }
        bis.close();
        d.close();
        try {
            JAXBContext jaxbContext = JAXBContext.newInstance(ObjectFactory.class);
            Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
            JAXBElement<Movie> o = (JAXBElement<Movie>) jaxbUnmarshaller.unmarshal(multipartFile.getInputStream());
            Movie movie = o.getValue();
            List<ObjectInfo> infoList = movie.getObjectInfos().getObjectInfo();
            DemoCache.setInfoList(infoList);         

        } catch (JAXBException ep) {
            ep.printStackTrace();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return "successFile";
    }
}

DemoCache 缓存导入的数据

package com.jason.example.controller;

import java.util.List;

import com.jason.example.model.ObjectInfo;

public class DemoCache {
	private static List<ObjectInfo> infoList;

	public static List<ObjectInfo> getInfoList() {
		return infoList;
	}

	public static void setInfoList(List<ObjectInfo> infoList) {
		DemoCache.infoList = infoList;
	}
}

数据导出DemoSeekController

package com.jason.example.controller;

import java.io.File;
import java.io.IOException;
import java.io.OutputStream;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.jason.example.model.Movie;
import com.jason.example.model.ObjectFactory;
import com.jason.example.model.ObjectInfos;

@Controller
public class DemoSeekController {
    /**
     * Size of a byte buffer to read/write file
     */
    private static final int BUFFER_SIZE = 4096;

    /**
     * Path of the file to be downloaded, relative to application's
     * directory
     */
    private String filePath = "/demos.xml";

    @RequestMapping(value = "/getInfoDemo", method = RequestMethod.GET)
    public String getInfoObject(HttpServletRequest request, HttpServletResponse response) {

        ObjectFactory factory = new ObjectFactory();
        Movie demo = factory.createMovie();
        ObjectInfos objectInfos = factory.createObjectInfos();
        System.out.println("-------------DemoCache.getInfoList()------------=" + DemoCache.getInfoList().size());
        objectInfos.getObjectInfo().addAll(DemoCache.getInfoList());
        demo.setObjectInfos(objectInfos); 

        System.out.println("movie: " + demo.getObjectInfos().getObjectInfo().size());
        try {
            // get absolute path of the application
            ServletContext context = request.getSession().getServletContext();
            String appPath = context.getRealPath("");
            System.out.println("appPath = " + appPath);
            // construct the complete absolute path of the file
            String fullPath = appPath + filePath;
            File downloadFile = new File(fullPath);          

            // set content attributes for the response
            String mimeType = "text/xml";
            response.setContentType(mimeType);

            // set headers for the response
            String headerKey = "Content-Disposition";
            String headerValue = String.format("attachment; filename=\"%s\"", downloadFile.getName());
            response.setHeader(headerKey, headerValue);
            OutputStream outStream = response.getOutputStream();
            JAXBContext jaxbContext = JAXBContext.newInstance(Movie.class);
            Marshaller jaxbMarshaller = jaxbContext.createMarshaller();

            // output pretty printed
            jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
            jaxbMarshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
            jaxbMarshaller.marshal(demo, outStream);
            outStream.close();
        } catch (JAXBException e) {
            e.printStackTrace();
        } catch (IOException ex) {
            ex.printStackTrace();
        }

        return "ok";
    }
}

Demo 导入导出 Url

http://127.0.0.1:8080/data-ingestion-demo-war/fileUpload.html

http://127.0.0.1:8080/data-ingestion-demo-war/getInfoDemo.htm

导入的 demo.xml数据的格式:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<movie xmlns="http://www.example.org/DemoSchema">
    <object-Infos>
        <object-info>
            <id>bf435848-a165-4361-a2ad-13c23fa0b3ff</id>
            <image-url>20141211064023715.png</image-url>
            <priority>666</priority>
            <localized>
                <lang>
                    <code>en</code>
                    <name>3333</name>
                    <attribute>555</attribute>
                    <description>555</description>
                </lang>
            </localized>

        </object-info>
        <object-info>
            <id>bf435848-a165-4361-a2ad-13c23fa0b3</id>
            <image-url>20141211064023715.png</image-url>
            <priority>140</priority>
            <localized>
                <lang>
                    <code>en</code>
                    <name>Sintel_en</name>
                    <attribute>Hero_en</attribute>
                    <description>Hero_en</description>
                </lang>
                <lang>
                    <code>zh</code>
                    <name>Sintel_zh</name>
                    <attribute>Hero_zh</attribute>
                    <description>Hero_zh</description>
                </lang>
            </localized>
        </object-info>
       </object-Infos>
</movie>

Source Code:

https://github.com/jingshauizh/JavaSpringSurmmary/tree/master/data-ingestion-demo-war

时间: 2024-08-23 22:56:40

使用JAXB 进行XML格式数据导入导出 Restful service的相关文章

R语言XML格式数据导入与处理

数据解析 XML是一种可扩展标记语言,它被设计用来传输和存储数据.XML是各种应用程序之间进行数据传输的最常用的工具.它与Access,Oracle和SQL Server等数据库不同,数据库提供了更强有力的数据存储和分析能力,例如:数据索引.排序.查找.相关一致性等,它仅仅是存储数据.事实上它与其他数据表现形式最大的不同是:它极其简单,这是一个看上去有点琐细的优点,但正是这点使它与众不同. 针对XML格式数据,R语言XML包可以对其进行数据导入与处理,详见下面的案例说明. 案例1 直接输入一段标

HData——ETL 数据导入/导出工具

HData是一个异构的ETL数据导入/导出工具,致力于使用一个工具解决不同数据源(JDBC.Hive.HDFS.HBase.MongoDB.FTP.Http.CSV.Excel.Kafka等)之间数据交换的问题.HData在设计上同时参考了开源的Sqoop.DataX,却与之有不同的实现.HData采用“框架+插件”的结构,具有较好的扩展性,框架相当于数据缓冲区,插件则为访问不同的数据源提供实现. [HData特性] 1.异构数据源之间高速数据传输: 2.跨平台独立运行: 3.数据传输过程全内存

考试系统维护--不同版本SQL数据导入导出

考试系统维护过程中,为了保证考试的顺利进行需要在多个服务器上搭建考试系统(备份),这时候需要把数据库来回迁移,之前我们常用的数据库备份还原的方法确实简单方便,但是遇到不同的服务器安装的SQL版本不同就歇菜了,虽然当时为了以后操作方便,我们把这次要用的服务器的数据库版本都统一了,但是在考试系统维护中米老师让我感触最深的一点-----"凡事多想一点!"多思考必须要应用到实际,所以我回来又仔细研究了几种不同版本SQL数据导入导出的方法,与大家交流提高. 一:使用SQLServer Impor

excel数据导入导出数据库

第一种方法: 先把Excel另存为.csv格式文件,如test.csv,再编写一个insert.ctl 用sqlldr进行导入! insert.ctl内容如下: load data          --1.控制文件标识 infile ‘my.csv‘          --2.要输入的数据文件名为my.csv append into table "tbl_test"   --3.向表table_name中追加记录 fields terminated by ‘,‘          

iOS dom解析xml格式数据

问题描述:接口返回的是xml格式数据,而且节点名居然都是相同的,采用了dom解析最终解决 一.文件导入 1.下载GDataXMLNode.h 和 GDataXMLNode.m文件,导入工程(csdn文件下载链接:http://download.csdn.net/detail/wusangtongxue/9502292) 2.配置环境: (1)改成ARC环境(-fno-objc-arc): (2)找到“Paths\Header Search Paths”项,并添加“/usr/include/lib

Oracle数据导入导出imp/exp

在oracle安装目录下有EXP.EXE与IMP.EXE这2个文件,他们分别被用来执行数据库的导入导出.所以Oracle数据导入导出imp/exp就相当与oracle数据还原与备份. Oracle数据导出exp Exp参数详解: USERID 运行导出命令的帐号的用户名/口令 BUFFEER 用来取数据行的缓冲区的大小 FILE 导出转储文件的名字 COMPRESS 导出是否应该压缩有碎片的段成一个范围,这将会影响STORAGE子句 GRANTS 导出时否要导出数据库对象上的授权 INDEXES

ORACLE EXPDP IMPDP数据导入导出命令详解及同EXP IMP命令详细对比

ORACLE EXPDP IMPDP数据导入导出命令详解及同EXP IMP 命令详细对比 一.EXPDP IMPDP EXP IMP 可以实现 1.可以实现逻辑备份和逻辑恢复 2.可以在数据库用户之间移动对象 3.可以在数据库之间移动对象 4.可以实现表空间转移 二.EXPDP的命令详解 C:\Users\Administrator>20:42:32.90>expdp help=y Export: Release 11.2.0.1.0 - Production on 星期六 10月 10 09

MongoDB学习(三)数据导入导出及备份恢复

这几天想着公司要用MongoDB,自然就要用到数据导入导出,就自己学习了一下. 在Mongo学习(二)中就讲到了在bin目录下有一些工具,本篇就是使用这些工具进行数据的导入导出及备份恢复. 注意:以下命令均在cmd命令行中输入,导出及备份未指明目录情况下,均保存在当前操作目录下. 数据导出mongoexport 1.常用导出方法:导出数据为json 假设库里有一张area 表,里面有9 条记录,我们要将它导出 >c:\mongo\bin\mongoexport -d iflashbuy_log

IT忍者神龟之Oracle 的数据导入导出及 Sql Loader (sqlldr) 的用法

在 Oracle 数据库中,我们通常在不同数据库的表间记录进行复制或迁移时会用以下几种方法: 1. A 表的记录导出为一条条分号隔开的 insert 语句,然后执行插入到 B 表中 2. 建立数据库间的 dblink,然后用 create table B as select * from [email protected] where ...,或 insert into B select * from [email protected] where ... 3. exp A 表,再 imp 到