下面的代码过去是在JDK 1.7使用的JAXB实现下工作的,但现在在JDK 1.8下它被破坏了。在下面的代码中,您将发现关键的更改,它似乎在1.8中起作用。1.8下的“修复”并不是真正的修复,因为公开内部集合供外部世界直接修改是一种不好的做法。我想通过我的类来控制对内部列表的访问,我不想通过创建可观察的集合并聆听它们来使事情复杂化。这是不可接受的。
有没有办法让我的原始代码在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
private List<String> foos = new LinkedList<String>(1000);
@XmlElement(name="foo")
public List<String> getFoos() {
return foos;
}
如果之前让JAXB调用映射到从getter返回非null响应的集合的属性上的setter,那么该JAXB实现中存在错误。您的代码也不应该在以前的版本中工作。
要调用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解组返回的List执行任何逻辑,那么使用字段访问可能是一种可接受的解决方案。
@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);
}
}
测试使用Jetty服务器周围的包装器作为连接到的主机。对于主机和客户端来说,truststore和keystore是相同的。出于某种原因,从2.5到2.6的更改导致服务器提前关闭。 我唯一要改变的是maven中的OkHttp版本从2.5到2.6。测试类在这里(实现在TestInvokeHttpCommon中):https://github.com/apache/nifi/blob/8c2323dc
null 04:52:42.738警告:没有为分析源文件提供依赖项的字节码,最终可能会得到不太精确的结果。可以使用sonar.java.Libraries属性提供字节码
我刚刚升级了我的android studio,它破坏了我的颤振构建过程。我现在在尝试构建以前工作过的项目时遇到了这个错误。我的andriod studio设置在最后。非常感谢您的帮助。 失败:构建失败,有一个异常。 出错原因: 任务执行失败:应用程序:processDebugMainManifest 无法使字段私有化。字符串java。木卫一。文件路径可访问:模块java。base不会将java.i
我们公司让我们从Oracle WebLogic 12.1.3升级到12.2.1.4,因为12.1.3失去支持/即将失去支持。 我们有一个主要的应用程序,它使用Spring Framework v3.0.2。当我们将EAR部署到12.2.1.4并尝试使用任何web服务时,我们会得到这个错误堆栈跟踪。我已经删除了使用通用名称指定我们公司的名称,但您应该能够了解发生的事情的要点: 2021-06-02
我最近通过从源代码编译在CentOS机器上安装了Python 2.7.3。Python 2.7.3安装在/opt/python2.7上,当我安装它时,我只需更改/usr/bin/Python以指向新版本。这显然是错误的,因为当我这样做的时候,它打破了百胜。我会得到以下内容。 我更改了/usr/bin/python以指向python 2.6.6,但现在2.6.6是python的默认版本。你知道怎么解
我正在将我的django项目从1.8升级到2.2.0(使用virtualenv中的Python 3.6)。我做了以下更改。 将on_delete添加到所有外键字段 将url反向导入更改为来自django。URL反向导入 在所有应用程序的url文件中包含路径/re_path而不是url 将设置文件中的MIDDLEWARE_CLASSES导入更改为MIDDLEWARE={} 我试图运行服务器,但它仍然