java 如何使用 JAXB 将 HashTable<String, String> 序列化为 XML?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7534500/
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
How to serialize HashTable<String, String> to XML using JAXB?
提问by mark
I am trying to use JAXB to serialize a HashTable<String, String>
to XML. I am very new to Java (came from C#), so I am kinda perplexed by this task.
我正在尝试使用 JAXB 将 a 序列化为HashTable<String, String>
XML。我对 Java 很陌生(来自 C#),所以我对这个任务有点困惑。
I have seen the following code:
我看到了以下代码:
public static <T> String ObjectToXml(T object, Class<T> classType) throws JAXBException
{
JAXBContext jaxbContext = JAXBContext.newInstance(classType);
StringWriter writerTo = new StringWriter();
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(object, writerTo); //create xml string from the input object
return writerTo.toString();
}
Which is invoked like so: ObjectToXml(o, ClassOfO.class)
, but HashTable<String, String>.class
is wrong (that I already know).
这是这样调用的:ObjectToXml(o, ClassOfO.class)
,但是HashTable<String, String>.class
是错误的(我已经知道了)。
Can Java gurus out there show me how to invoke this code? Proposing a simpler implementation (along with an invocation example, of course) is most welcome as well.
那里的 Java 大师可以告诉我如何调用此代码吗?提出一个更简单的实现(当然还有一个调用示例)也是最受欢迎的。
Thanks.
谢谢。
采纳答案by bdoughan
You will need to create a wrapper class to hold onto the Hashtable
:
您将需要创建一个包装类来保持Hashtable
:
package forum7534500;
import java.util.Hashtable;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class Wrapper {
private Hashtable<String, String> hashtable;
public Hashtable<String, String> getHashtable() {
return hashtable;
}
public void setHashtable(Hashtable<String, String> hashtable) {
this.hashtable = hashtable;
}
}
Then you can do the following:
然后您可以执行以下操作:
package forum7534500;
import java.io.StringWriter;
import java.util.Hashtable;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
public class Demo {
public static void main(String[] args) throws Exception {
JAXBContext jc = JAXBContext.newInstance(Wrapper.class);
Wrapper wrapper = new Wrapper();
Hashtable<String, String> hashtable = new Hashtable<String,String>();
hashtable.put("foo", "A");
hashtable.put("bar", "B");
wrapper.setHashtable(hashtable);
System.out.println(objectToXml(jc, wrapper));
}
public static String objectToXml(JAXBContext jaxbContext, Object object) throws JAXBException
{
StringWriter writerTo = new StringWriter();
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(object, writerTo); //create xml string from the input object
return writerTo.toString();
}
}
This will produce the following output:
这将产生以下输出:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<wrapper>
<hashtable>
<entry>
<key>bar</key>
<value>B</value>
</entry>
<entry>
<key>foo</key>
<value>A</value>
</entry>
</hashtable>
</wrapper>
Things to Note
注意事项
JAXBContext
is a thread-safe object and should be created once and reused.Hashtable
is synchronized, if you do not need this then usingHashMap
is the common replacement.- The convention is to start Java method names with a lower case letter.
JAXBContext
是一个线程安全的对象,应该创建一次并重用。Hashtable
是同步的,如果你不需要这个,那么 usingHashMap
是常见的替代品。- 约定是以小写字母开头的 Java 方法名称。
Customizing the Mapping
自定义映射
You can use an XmlAdapter
in JAXB to customize the mapping of any class. Below is an link to a post on my blog where I demonstrate how to do just that:
您可以使用XmlAdapter
JAXB 中的 自定义任何类的映射。下面是我博客上一篇文章的链接,我演示了如何做到这一点:
回答by fruchtose
Unfortunately, JAXB is not able to directly serialize a Map
or HashMap
instance directly. Instead, you'll have to do some sort of translation from a Map
into a list of entries that have a key and a value. Try looking into this Stack Overflow questionand see if it can help you. This problem shows up a lot in Google, and the sad answer is that JAXB doesn't know how to serialize a Map
.
不幸的是,JAXB 不能直接序列化一个Map
或HashMap
实例。相反,您必须将 aMap
转换为具有键和值的条目列表。尝试查看此堆栈溢出问题,看看它是否可以帮助您。这个问题在 Google 中经常出现,令人遗憾的答案是 JAXB 不知道如何序列化Map
.
回答by forty-two
Bah! If you had only googled on jaxband hashmapyou would have directly found this: http://download.oracle.com/javase/6/docs/api/javax/xml/bind/annotation/adapters/XmlAdapter.html
呸! 如果你只在jaxb和hashmap上搜索过你会直接找到这个:http: //download.oracle.com/javase/6/docs/api/javax/xml/bind/annotation/adapters/XmlAdapter.html
But, yes, I kind of agree that 'perplexion' is a good description of the feeling of the non-obviousness of the task.
但是,是的,我有点同意“困惑”是对任务不明显的感觉的一个很好的描述。
回答by Shivan Dragon
While you might be familiar with C# reified generics, Java's generics are for compile time only, they go away at runtime. That's why, at runtime, even if you have an instance with established generics (Such as String for HashTable) at runtime those generics go away, so all you can do is obtain the class of the thing (HashTable here) and not the actual generic types (String here). In short: compile time Hashtable<String,String>
becomes HashTable at runtime (or, to be totally pedantic HashTable<?,?>
)
虽然您可能熟悉 C# 实体化泛型,但 Java 的泛型仅用于编译时,它们在运行时消失。这就是为什么,在运行时,即使您有一个具有已建立泛型的实例(例如用于 HashTable 的 String),这些泛型也会在运行时消失,所以您所能做的就是获取事物的类(此处为 HashTable)而不是实际的泛型类型(此处为字符串)。简而言之:编译时Hashtable<String,String>
在运行时变成 HashTable (或者,完全迂腐HashTable<?,?>
)
回答by smp7d
I think your best bet is to create an xml schema that reflects what you want and then run xjc on it. This way you have some control over what the xml will look like w/o getting into the guts of JaxB. http://download.oracle.com/docs/cd/E17802_01/webservices/webservices/docs/1.6/jaxb/xjc.html
我认为最好的办法是创建一个 xml 模式来反映您想要的内容,然后在其上运行 xjc。通过这种方式,您可以控制 xml 的外观,而无需进入 JaxB 的内部。 http://download.oracle.com/docs/cd/E17802_01/webservices/webservices/docs/1.6/jaxb/xjc.html
You can then translate your HashTable to the generated object and pass it to this variation of your static method.
然后,您可以将 HashTable 转换为生成的对象,并将其传递给静态方法的此变体。
public static <T> String ObjectToXml(T object) throws JAXBException {
JAXBContext jaxbContext = JAXBContext.newInstance(object.getClass());
StringWriter writerTo = new StringWriter();
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(object, writerTo);
return writerTo.toString();
}