gpt4 book ai didi

java - 从 JDK 1.8.0.77 升级到 1.8.0.162 后 Jaxb2Marshaller 失败

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

这个把我难住了。我有一个 Java String Batch 应用程序,在 Java 1.8.0.77 上运行时没有任何错误。它读取 XML 文件并将其完美地写入数据库。

更新到 JDK 1.8.0.162 后,即使将日志记录设置为 DEBUG,阅读器也无法工作,也不会发送任何错误消息。改回 Java 1.8.0.77 可以解决该问题。不过我们的服务器运行的是 162,所以我必须在 162 上进行这项工作。

这是读者:

      @Bean
  ItemReader<Product> reviewItemReader() {
    StaxEventItemReader<Product> xmlFileReader = new StaxEventItemReader<>();
    xmlFileReader.setResource(new FileSystemResource(this.fileName));
    xmlFileReader.setFragmentRootElementName("Product");
    Jaxb2Marshaller feedMarshaller = new Jaxb2Marshaller();
    feedMarshaller.setClassesToBeBound(Product.class);
    xmlFileReader.setUnmarshaller(feedMarshaller);
    return xmlFileReader;
  }

当我针对 Java 1.0.8.77 运行它时,我获得了完整的产品记录,并且所有子类都用文件中的数据填充。当我针对 Java 1.0.8.162 运行它时,我只取回产品标签上的 3 个属性,而没有取回其中的任何字段。

XML 看起来像:

...
<Product id="asdsada" removed="false" disabled="true">
<Descriptoin> Blah blah blah</Descriptoin>
<UPCs>
<UPC> 123423432</UPC>
</UPCs>
<Rating>5</Rating>
<Name>name here</Name>
<Categories>
<Category> Cat 1 </Category>
<Category> Cat 2 </Category>
<Category> Cat 3 </Category>
</Categories>
...
</Product>
<Product id="zxcvzxcvxcv" removed="true" disabled="false">
<Descriptoin> Blah blah blah</Descriptoin>
<UPCs>
<UPC> 123222423432</UPC>
</UPCs>
<Rating>5</Rating>
<Name>name here</Name>
<Categories>
<Category> Cat 1 </Category>
<Category> Cat 2 </Category>
<Category> Cat 3 </Category>
</Categories>
....
</Product>

产品类别是这样的

@XmlRootElement(name = "Product", namespace = "FOO POWER")
public class Product {

  @XmlAttribute(name = "removed")
  public String removed;
  @XmlAttribute(name = "disabled")
  public String disabled;
  @XmlAttribute(name = "id")
  public String id;
public String Name;
public String Rating;

  public UPCs UPCs;

  public Brand Brand;
...

同样,它在 1.8.0.77 中运行完全没有任何问题。我在测试中通过它运行了数百万条记录。在 1.8.0.162 中运行时,这些相同的记录会失败

Someone asked to see what a child class looks like. They are pretty much like this: 

public class Brand {
  public String Name;

    public Attributes Attributes;

    public String ExternalId;

    public String disabled;
...

最佳答案

今年早些时候我遇到了类似的问题。我正在将一个项目从 Java 1.8.0_92 升级到 1.8.0_152,并且一些适用于 1.8.0_92 的 JAXB 解码不再适用于 1.8.0_152。我在下面的回答中更多地作为实验结果而不是作为对文档的引用,因为我一直在努力寻找相关文档来支持我的发现。如果其他人可以找到相关文档,我很有兴趣查看。

我的理解是,如果 Java 类中的字段或属性没有 @XmlElement 注释,JAXB 会将该字段或属性视为具有注释 @XmlElement(name = "fieldName")@XmlElement(name = "propertyName")(视情况而定)。因此,例如,Product 类中未注释的字段将按如下方式处理:

@XmlElement(name = "Name")
public String Name;

@XmlElement(name = "Rating")
public String Rating;

@XmlElement(name = "UPCs")
public UPCs UPCs;

@XmlElement(name = "Brand")
public Brand Brand;

此外,在 Java 8 更新 101 和 111 之间,JAXB 中处理命名空间的方式发生了变化。 Java 8 更新 101 允许元素单独匹配本地名称,而不管命名空间,但从更新 111 开始,元素命名空间也必须匹配。如果您不指定命名空间(特别是,如果您根本不指定 @XmlElement 注释),则假定使用默认命名空间。

Product 元素的子元素不在默认命名空间中,因此它们不再与上面的 @XmlElement 注释匹配。但是,例如,尝试将 xmlns="" 添加到 Rating 元素。您应该会发现该产品的评级已被读入。

因此,解决您的问题的一种可能的解决方案是向所有子元素添加 @XmlElement 注释(包括命名空间)。这就是我需要做的来解决我遇到的问题:我已经有了必要的 @XmlElement 注释,我只需要向这样的注释添加一个命名空间。但是,我怀疑您有更多的子元素,并且您指定的示例文档是从更大的真实文档中截取的。考虑到这一点,创建带有相关注释的 package-info.java 文件并将其放入包含 POJO 的包中可能会更快(希望它们都在同一个包中) ):

@XmlSchema( 
namespace = "FOO POWER",
elementFormDefault = XmlNsForm.QUALIFIED)
package your.package.name.here;

import javax.xml.bind.annotation.XmlNsForm;
import javax.xml.bind.annotation.XmlSchema;

我将其添加到我创建的一个小型 Java 项目中来测试您的代码,我发现解码似乎有效。 Product 类中的子属性使用 XML 文档中的值进行填充。我从 this page 中得到了使用 package-info.java 文件的想法。 .

关于java - 从 JDK 1.8.0.77 升级到 1.8.0.162 后 Jaxb2Marshaller 失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49885939/

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