适用于 Java 的简单 XML 序列化程序

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3056896/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 00:08:30  来源:igfitidea点击:

Easy XML Serializer for Java

javaxml-serialization

提问by sdoca

I'm looking for a way to serialize Java objects into XML for use by a RESTful web service. I don't have an XSD.

我正在寻找一种将 Java 对象序列化为 XML 以供 RESTful Web 服务使用的方法。我没有 XSD。

I have looked at the following:

我看过以下内容:

  1. JAXB - fairly heavy weight with annotations required on classes and also an ObjectFactory class and/or a jaxb.index file

  2. Simple - requires annotations but no other config classes/files. Unfortunately it can't serialize Sets.

  3. XStream - no annotations etc. required, but doesn't support generics

  1. JAXB - 相当重的类需要注释,还有一个 ObjectFactory 类和/或一个 jaxb.in​​dex 文件

  2. 简单 - 需要注释但不需要其他配置类/文件。不幸的是它不能序列化集合。

  3. XStream - 不需要注释等,但不支持泛型

Does anyone else have any suggestions?

还有其他人有什么建议吗?

回答by Romain Hippeau

import java.beans.XMLEncoder;
import java.beans.XMLDecoder;
import java.io.*;

public class XMLSerializer {
    public static void write(Object f, String filename) throws Exception{
        XMLEncoder encoder =
           new XMLEncoder(
              new BufferedOutputStream(
                new FileOutputStream(filename)));
        encoder.writeObject(f);
        encoder.close();
    }

    public static Object read(String filename) throws Exception {
        XMLDecoder decoder =
            new XMLDecoder(new BufferedInputStream(
                new FileInputStream(filename)));
        Object o = (Object)decoder.readObject();
        decoder.close();
        return o;
    }
}

回答by Will Hartung

JAXB is pretty painless, and comes with Java 6, and it has a low footprint.

JAXB 非常轻松,随 Java 6 一起提供,而且占用空间小。

You get this for the price of one annotation.

您以一个注释的价格获得此信息。

Order.java

订单.java

package xxx;


import java.util.Date;
import java.util.List;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Order {

    int custId;
    Date orderDate;
    String description;
    List<Item> items;

    public void setCustId(int custId) {
        this.custId = custId;
    }

    public void setOrderDate(Date orderDate) {
        this.orderDate = orderDate;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public void setItems(List<Item> items) {
        this.items = items;
    }

    public int getCustId() {
        return custId;
    }

    public Date getOrderDate() {
        return orderDate;
    }

    public String getDescription() {
        return description;
    }

    public List<Item> getItems() {
        return items;
    }

    public String toString() {
        return "Order: " + custId + " - " + orderDate + " - " + description + " - " + items;
    }
}

Item.java:

项目.java:

package xxx;

public class Item {

    String name;
    private int qty;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getQty() {
        return qty;
    }

    public void setQty(int qty) {
        this.qty = qty;
    }

    public String toString() {
        return "Item:" + name + " - " + qty;
    }
}

Test.java:

测试.java:

package xxx;

import java.io.StringReader;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;

public class Test {

    public static void main(String args[]) throws Exception {
    Order o = new Order();
        o.setCustId(123);
        o.setDescription("New order");
        o.setOrderDate(new Date());

        List<Item> items = new ArrayList<Item>();

        Item i = new Item();
        i.setName("Duck Soup");
        i.setQty(10);
        items.add(i);

        i = new Item();
        i.setName("Carrots");
        i.setQty(4);

        items.add(i);

        o.setItems(items);


        //Write it
        JAXBContext ctx = JAXBContext.newInstance(Order.class);

        Marshaller m = ctx.createMarshaller();
        m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

        StringWriter sw = new StringWriter();
        m.marshal(o, sw);
        sw.close();
        System.out.println(sw.toString());

        // Read it back
        JAXBContext readCtx = JAXBContext.newInstance(Order.class);
        Unmarshaller um = readCtx.createUnmarshaller();

        Order newOrder = (Order) um.unmarshal(new StringReader(sw.toString()));
        System.out.println(newOrder);
    }
}

Results:

结果:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<order>
    <custId>123</custId>
    <description>New order</description>
    <items>
        <name>Duck Soup</name>
        <qty>10</qty>
    </items>
    <items>
        <name>Carrots</name>
        <qty>4</qty>
    </items>
    <orderDate>2010-06-16T18:12:06.870-07:00</orderDate>
</order>

Order: 123 - Wed Jun 16 18:12:06 PDT 2010 - New order - [Item:Duck Soup - 10, Item:Carrots - 4]

回答by mdma

My vote would be for XStream. The lack of generics support is a small price to pay for the amount of flexibility it offers. You can also easily implement generics by serializing the generic class type at serialization time, or build this into your domain objects. E.g.

我的投票将投给 XStream。缺乏泛型支持是为其提供的灵活性付出的小代价。您还可以通过在序列化时序列化泛型类类型来轻松实现泛型,或者将其构建到域对象中。例如

   class Customer
   {
      List<Order> orders;

      public List<Order> getOrders()
      {
         return orders;
      }
   }

In the stream, the element type denotes the type of each object. When the type is an abstract type or interface, the element listed with the implementing class, unless that has been specified as the default for that interface type. (E.g. ArrayList as the default for instances of static type List.)

在流中,元素类型表示每个对象的类型。当类型是抽象类型或接口时,元素与实现类一起列出,除非已将其指定为该接口类型的默认值。(例如 ArrayList 作为静态类型 List 实例的默认值。)

Generics are "rose coloured glasses" in java - they don't really change what you are seeing, just how you see it. The objects would be sent over the wire exactly the same if they were sent with generics support or not.

泛型是 Java 中的“玫瑰色眼镜”——它们并没有真正改变你所看到的,只是你如何看待它。如果发送的对象是否带有泛型支持,则这些对象将通过网络完全相同地发送。

回答by Santhosh Kumar Tekuri

You can try JLibs XMLDocument. It uses SAX to create XML and thus light-weight and have complete control.

您可以尝试JLibs XMLDocument。它使用 SAX 来创建 XML,因此重量轻并具有完全的控制权。