Java JAXB和继承在封送时起作用;但不是拆封
我想封送/取消封送继承自另一个类的类的对象 我从课程Java JAXB和继承在封送时起作用;但不是拆封,java,inheritance,jaxb,Java,Inheritance,Jaxb,我想封送/取消封送继承自另一个类的类的对象 我从课程开始: import java.util.List; 公共类事物{ 私有列表字符串; 公共列表getStrings(){ 返回字符串; } 公共无效设置字符串(列表字符串){ this.strings=字符串; } } 我扩展了这个类并用JAXB注释对其进行注释 import java.util.List; 导入javax.xml.bind.annotation.*; @XmlRootElement 公共类JaxbThing扩展了这个东西{
开始:
import java.util.List;
公共类事物{
私有列表字符串;
公共列表getStrings(){
返回字符串;
}
公共无效设置字符串(列表字符串){
this.strings=字符串;
}
}
我扩展了这个类并用JAXB注释对其进行注释
import java.util.List;
导入javax.xml.bind.annotation.*;
@XmlRootElement
公共类JaxbThing扩展了这个东西{
//@xmlementwrapper(name=“list”)
@XmlElementWrapper(name=“strings”)
@xmlement(name=“string”)
公共列表getStrings(){
返回super.getStrings();
}
公共无效设置字符串(列表字符串){
超级设置字符串(字符串);
}
}
然后运行以下编组/解编组程序:
导入java.io.File;
导入java.util.array;
导入javax.xml.bind.*;
公共班机{
公共静态void main(字符串[]args){
JaxbThing t=新的JaxbThing();
t、 集合字符串(数组.asList(“a”、“b”、“c”));
试一试{
文件f=新文件(“jaxb File.xml”);
JAXBContext context=JAXBContext.newInstance(JaxbThing.class);
Marshaller m=context.createMarshaller();
m、 元帅(t,f);
Unmarshaller um=context.createUnmarshaller();
JaxbThing t2=(JaxbThing)um.unmarshal(f);
System.out.println(t2.getStrings());//我希望看到[a,b,c]
}捕获(JAXBEException e){
e、 printStackTrace();
}
}
}
XML文件的内容是:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<jaxbThing>
<strings>
<string>a</string>
<string>b</string>
<string>c</string>
</strings>
</jaxbThing>
当我期待看到[a,b,c]
如果我以这种方式注释字符串
属性:
@xmlementwrapper(name=“list”)
//@xmlementwrapper(name=“strings”)
@xmlement(name=“string”)
公共列表getStrings(){
返回super.getStrings();
}
然后控制台显示预期的[a、b、c]
我猜JAXB解组器使用classThing
而不是JaxbThing
来解组XML文件内容。事实上,如果我用@xmltransive
注释类东西
,我会得到预期的结果
但是,我不理解JAXB的这种行为
谁能给我解释一下吗?提前感谢。问题在于您正在重写父类中的属性。JAXB认为JAXBThing
has“
一个名为strings
(继承自String
)的属性映射到元素strings
名为strings
(在JAXBThing
上定义)的属性映射到元素strings
下的元素string
如果在JAXBThing
上的setStrings
方法中放置一个断点,您将看到它首先使用正确的数据调用,然后使用覆盖初始集的错误数据调用第二次(因为它认为它们是共享一个setter的不同属性)
通过使用@xmltransive
对类进行注释,始终可以删除对象
import java.util.List;
import javax.xml.bind.annotation.XmlTransient;
@XmlTransient
public class Thing {
private List<String> strings;
public List<String> getStrings() {
return strings;
}
public void setStrings(List<String> strings) {
System.out.println("Thing" + strings);
this.strings = strings;
}
}
import java.util.List;
导入javax.xml.bind.annotation.XmlTransient;
@XmlTransient
公共类事物{
私有列表字符串;
公共列表getStrings(){
返回字符串;
}
公共无效设置字符串(列表字符串){
System.out.println(“Thing”+字符串);
this.strings=字符串;
}
}
了解更多信息
非常感谢您的回答。我已经按照您的建议做了。您是对的,
setStrings
方法被调用了两次。但是,至少在我的实验中,它从来没有用正确的值调用过
下面我提供了修改后的示例代码。我添加了几行来跟踪执行。我还激活了marshaller格式的输出,以便更好地查看解组过程中发生的情况
基类东西
import java.util.List;
公共类事物{
私有列表字符串;
公共列表getStrings(){
返回字符串;
}
公共无效设置字符串(列表字符串){
/*new*/System.out.printf(“Thing.setStrings called.Prev.this.strings:%s(大小%s)。收到的strings参数:%s”,this.strings,(this.strings!=null?this.strings.size():“null”),strings);
this.strings=字符串;
/*new*/System.out.printf(“.new this.strings:%s(大小%s)。%n%n”,this.strings,(this.strings!=null?this.strings.size():“null”);
}
}
扩展类JaxbThing
import java.util.List;
导入javax.xml.bind.annotation.*;
@XmlRootElement
公共类JaxbThing扩展了这个东西{
//@xmlementwrapper(name=“list”)
@XmlElementWrapper(name=“strings”)
@xmlement(name=“string”)
公共列表getStrings(){
返回super.getStrings();
}
公共无效设置字符串(列表字符串){
/*new*/System.out.printf(“调用了JaxbThing.setStrings.Received strings参数:%s(大小%s)%n”),string,(string!=null?string.size():“null”);
超级设置字符串(字符串);
}
}
测试程序:
结果如下(我已将行编号):
在解组期间,将构建一个新的JaxbThing
,首先使用0长度的字符串列表(第7行)调用其JaxbThing.setStrings
。因此,将调用Thing.setStrings
(第8行)。对象字符串字段的先前值(this.strings
)为null。然后,再次调用JaxbThing.setString
(第10行),但现在使用了一个字符串列表,其中包含一个带“\n”字符的字符串加上4个空格(我猜这对应于XML文件的缩进)。两条注释:
JaxbThing.setStrings
从未使用正确的值调用过(除非我没有看到它)
对JaxbThing.setString的第二次调用
import java.util.List;
import javax.xml.bind.annotation.XmlTransient;
@XmlTransient
public class Thing {
private List<String> strings;
public List<String> getStrings() {
return strings;
}
public void setStrings(List<String> strings) {
System.out.println("Thing" + strings);
this.strings = strings;
}
}
import java.io.File;
import java.util.Arrays;
import javax.xml.bind.*;
public class Main {
public static void main(String[] args) {
System.out.println("---- Initiallizing");
JaxbThing t = new JaxbThing();
t.setStrings(Arrays.asList("a", "b", "c"));
try {
File f = new File("jaxb-file.xml");
JAXBContext context = JAXBContext.newInstance(JaxbThing.class);
System.out.println("---- Marshalling");
Marshaller m = context.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); /*new*/
m.marshal(t, f);
System.out.println("---- UnMarshalling");
Unmarshaller um = context.createUnmarshaller();
JaxbThing t2 = (JaxbThing) um.unmarshal(f);
System.out.println("---- Showing results");
System.out.println(t2.getStrings()); // I expect to see [a, b, c]
} catch (JAXBException e) {
e.printStackTrace();
}
}
}
1 ---- Initiallizing
2 JaxbThing.setStrings called. Received strings param: [a, b, c] (size 3)
3 Thing.setStrings called. Prev. this.strings: null (size null). Received strings param: [a, b, c]. New this.strings: [a, b, c] (size 3).
4
5 ---- Marshalling
6 ---- UnMarshalling
7 JaxbThing.setStrings called. Received strings param: [] (size 0)
8 Thing.setStrings called. Prev. this.strings: null (size null). Received strings param: []. New this.strings: [] (size 0).
9
10 JaxbThing.setStrings called. Received strings param: [
] (size 1)
11 Thing.setStrings called. Prev. this.strings: [
] (size 1). Received strings param: [
]. New this.strings: [
] (size 1).
12
13 ---- Showing results
14 [
]