gpt4 book ai didi

xml-parsing - JAXB 配置因集合从 JDK 1.7 升级到 JDK 1.8 u05 而中断

转载 作者:行者123 更新时间:2023-12-04 02:41:25 25 4
gpt4 key购买 nike

下面的代码曾经在 JDK 1.7 使用的 JAXB 实现下工作,但现在在 JDK 1.8 下它被破坏了。在下面的代码中,您会发现似乎使其在 1.8 中起作用的关键更改。 1.8 下的“修复”并不是真正的修复,因为公开内部集合供外界直接修改是不好的做法。我想通过我的类(class)控制对内部列表的访问,我不想通过制作可观察的集合并收听它们来使事情复杂化。这是 Not Acceptable 。

有什么方法可以让我的原始代码在 JD 1.8 的 JAXB 下工作吗?

 @XmlElementWrapper(name = "Wrap")
@XmlElement(name = "Item", required = true)
public synchronized void setList(List<CustomObject> values) {
list.clear();
list.addAll(values);
}

public synchronized List<CustomObject> getList() {
// return new ArrayList(list); // this was the original code that worked under 1.7
return list; //this is the only thing that works under 1.8
}

经过更多分析,问题似乎出在 JAXB 不再为集合调用 setter 方法(以前在 JDK 1.7 下)。现在在JDK 1.8下,直接调用getter修改集合。这带来了几个问题:

1-强制用户向外界公开内部集合以供自由修改(不良做法)2-不允许用户在列表更改时执行任何自定义代码(例如调用 setter 时您可以执行的操作)。可以制作一个可观察的集合并对其进行监听,但这是一种比仅调用 setter 方法复杂得多的解决方法。

最佳答案

背景

在 JAXB 中映射集合属性时,它首先检查 getter 以查看集合属性是否已预初始化。在下面的示例中,我希望将我的属性公开为 List<String> ,但支持实现是 LinkedList准备容纳 1000 件元素。

private List<String> foos = new LinkedList<String>(1000);

@XmlElement(name="foo")
public List<String> getFoos() {
return foos;
}

为什么你的代码曾经有效

如果您之前让 JAXB 在映射到从 getter 返回非空响应的集合的属性上调用 setter,则该 JAXB 实现中存在错误。您的代码也不应该在以前的版本中工作。

如何调用 Setter

要调用 setter,您只需让 getter 在对象的新实例上返回 null。您的代码可能类似于:

import java.util.*;
import javax.xml.bind.annotation.*;

@XmlRootElement(name = "Foo")
public class Foo {

private List<CustomObject> list = null;

@XmlElementWrapper(name = "Wrap")
@XmlElement(name = "Item", required = true)
public synchronized void setList(List<CustomObject> values) {
if (null == list) {
list = new ArrayList<CustomObject>();
} else {
list.clear();
}
list.addAll(values);
}

public synchronized List<CustomObject> getList() {
if (null == list) {
return null;
}
return new ArrayList(list);
}

}

更新

如果您不需要对从 JAXB 的解码返回的列表执行任何逻辑,那么使用字段访问可能是一个可接受的解决方案。

@XmlRootElement(name = "Foo")
@XmlAccessorType(XmlAccessType.FIELD)
public class Foo {

@XmlElementWrapper(name = "Wrap")
@XmlElement(name = "Item", required = true)
private List<CustomObject> list = null;

public synchronized void setList(List<CustomObject> values) {
if(null == list) {
list = new ArrayList<CustomObject>();
} else {
list.clear();
}
list.addAll(values);
}

public synchronized List<CustomObject> getList() {
return new ArrayList(list);
}

}

关于xml-parsing - JAXB 配置因集合从 JDK 1.7 升级到 JDK 1.8 u05 而中断,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23664516/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com