JAXB @XmlRootElement具有相同的名称
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JAXB @XmlRootElement具有相同的名称相关的知识,希望对你有一定的参考价值。
我有一个非常长的XML:
<Author>
<id></id>
<name></name>
<title></title>
<address></address>
....
</Author>
我之前使用JAXB解析XML。
JAXBContext.newInstance(Author.class);
还有我的Author.java
@XmlRootElement(name = "Author")
public class Author {
private String id;
private String name;
private String title;
private String address;
...
}
它运行良好,但我不想每次都将整个XML解析为一个大的Java bean。
所以,我想在下面使用:
创建Commentator.java
@XmlRootElement(name = "Author")
public class Commentator {
private String id;
private String name;
// setters, getters
}
创建Analyst.java
@XmlRootElement(name = "Author")
public class Analyst {
private String title;
private String address;
// setters, getters
}
我写下面的代码进行测试。
JAXBContext context = JAXBContext.newInstance(Analyst.class, Commentator.class);
Unmarshaller unmarshaller = context.createUnmarshaller();
String xml = "<Author> <id>1</id> <name>A</name> <title>B</title> <address>C</address></Author>";
Commentator obj = (Commentator) unmarshaller.unmarshal(new ByteArrayInputStream(xml.getBytes()));
System.out.println(obj);
它将打印正确的结果。
如果我想得到分析师。
Analyst a = (Analyst) unmarshaller.unmarshal(new ByteArrayInputStream(xml.getBytes()));
我会得到例外:java.lang.ClassCastException: com.xxx.Commentator cannot be cast to com.xxx.Analyst
我不确定解析器的这种方式是否正确。但我真的需要这样一个功能。
找到一个快速的方法来做到这一点:
- 注册便便。
JAXBContext context = JAXBContext.newInstance(Analyst.class, Commentator.class);
- 处理输入。我将str-xml转换为StreamSource。
String xml = "<Author> <id>1</id> <name>A</name> <title>B</title> <address>C</address></Author>";
StreamSource source = new StreamSource(new ByteArrayInputStream(xml.getBytes()));
- 创建Unmarshaller。
Unmarshaller unmarshaller = context.createUnmarshaller();
- (重要)当你解组数据时,给出第二个参数(你想要解组的那个类)
JAXBElement<Analyst> unmarshal = unmarshaller.unmarshal(source, Analyst.class);
然后,得到你想要的:
Analyst analyst = unmarshal.getValue();
- 如果需要另一个pojo。(注意
unmarshaller
和source
不能在方法中重复使用)
JAXBElement<Commentator> unmarshal2 = unmarshaller2.unmarshal(source2, Commentator.class);
然后:
Commentator com = unmarshal2.getValue();
没有错误报告和结果是正确的。
在我看来,使用相同的@XmlRootElement
映射几个Java类是一种有点笨拙的设计。但是,你仍然能够实现你想要的。
你需要不同的JAXBContext
s为Analyst
和Commentator
。
因为JAXBContext
是一个大对象而JAXBContext.newInstance(...)
需要相当长的时间才能执行,所以在JAXBContext
variables中保存这些static
实例并重用它们而不是创建新的实例是有意义的:
private static JAXBContext analystContext;
private static JAXBContext commentatorContext;
if (analystContext == null)
analystContext = JAXBContext.newInstance(Analyst.class);
if (commentatorContext == null)
commentatorContext = JAXBContext.newInstance(Commentator.class);
因此,您还需要从它们创建不同的Unmarshaller
s:
Unmarshaller analystUnmarshaller = analystContext.createUnmarshaller();
Unmarshaller commentatorUnmarshaller = commentatorContext.createUnmarshaller();
然后,您可以将相同的XML内容解组到不同的根类:
String xml = "<Author> <id>1</id> <name>A</name> <title>B</title> <address>C</address></Author>";
Analyst analyst = (Analyst) analystUnmarshaller.unmarshal(new ByteArrayInputStream(xml.getBytes()));
Commentator commentator = (Commentator) commentatorUnmarshaller.unmarshal(new ByteArrayInputStream(xml.getBytes()));
以上是关于JAXB @XmlRootElement具有相同的名称的主要内容,如果未能解决你的问题,请参考以下文章
JAXB注解 @XmlRootElement 及XML文件解析详解