【问题标题】:@XmlPath has no impact during the JAXB Marshalling@XmlPath 在 JAXB 编组期间没有影响
【发布时间】:2021-08-02 15:14:49
【问题描述】:

我正在尝试使用 JaxB Marshalling 方法创建 XML。我想跳过某些孩子的父标签,或者可能为某个元素添加一个新的 XML 父标签。因此,我尝试使用来自import org.eclipse.persistence.oxm.annotations.XmlPath;@XmlPath

我正在关注创始人 (Blog on @XmlPath) 的博客以使其正常工作,但由于某种原因,@XmlPath 没有影响,并且输出 XML 与博客中显示的不匹配。我遵循了博客中提到的所有过程,并且在此处的各种答案中也提到了。

我所有的课程都在model.jaxb 包中。另外,我在该包中创建了一个jaxb.properties 文件。

以下是我的Customer类:

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.eclipse.persistence.oxm.annotations.XmlPath;

@Getter
@Setter
@NoArgsConstructor
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Customer {

  @XmlPath("contact-info/billing-address")
  private Address billingAddress;

  @XmlPath("contact-info/shipping-address")
  private Address shippingAddress;

}

以下是我的Address类:

@Getter
@Setter
@NoArgsConstructor
public class Address {

  private String street;

}

以下是Demo类:

public class Demo {

  public static void main(String[] args) throws Exception {
    JAXBContext jc = JAXBContext.newInstance(Customer.class);

    Customer customer = new Customer();

    Address billingAddress = new Address();
    billingAddress.setStreet("1 Billing Street");
    customer.setBillingAddress(billingAddress);

    Address shippingAddress = new Address();
    shippingAddress.setStreet("2 Shipping Road");
    customer.setShippingAddress(shippingAddress);

    Marshaller m = jc.createMarshaller();
    m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
    m.marshal(customer, System.out);
  }

}

我得到的有和没有@XmlPath 的XML 实际上是一样的。所以看起来@XmlPath 在编组期间没有影响。

<customer>
    <billingAddress>
        <street>1 Billing Street</street>
    </billingAddress>
    <shippingAddress>
        <street>2 Shipping Road</street>
    </shippingAddress>
</customer>

我在package model.jaxb 中创建了jaxb.properties 文件,内容如下:

javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory

根据博客,输出 XML 应该是这样的:

<customer>
   <contact-info>
      <billing-address>
         <street>1 Billing Street</street>
      </billing-address>
      <shipping-address>
         <street>2 Shipping Road</street>
      </shipping-address>
   </contact-info>
<customer>

我不确定我做错了什么,因为我无法按预期获取 XML。我尝试了很多东西,但都没有奏效,所以在这里发布相同的内容。

有人可以帮助我如何在编组过程中使@XmlPath 踢,以便我可以在编组过程中获得预期的标签吗?

**** 已编辑 *****

根据Intellij IDE File -&gt; Project Structure,我正在使用 Java 版本 15.0.01。我看到了一个答案,其中提到MoxyJava 11 Answer Java 11.0 above 上方不起作用。

所以我做了以下事情:

  1. 我添加了上述答案中提到的依赖项和build,所以我的pom.xml 看起来像这样:
    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    
      <modelVersion>4.0.0</modelVersion>
          <groupId>model.jaxb</groupId>
        <version>1.0-SNAPSHOT</version>
    
      <artifactId>model-jaxb</artifactId>
    
      <build>
        <plugins>
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
              <source>8</source>
              <target>8</target>
            </configuration>
          </plugin>
        </plugins>
        <resources>
          <resource>
            <directory>src/main/java</directory>
            <excludes>
              <exclude>**/*.java</exclude>
            </excludes>
          </resource>
        </resources>
      </build>
    
      <dependencies>
    
        <dependency>
          <groupId>org.projectlombok</groupId>
          <artifactId>lombok</artifactId>
          <version>1.18.16</version>
          <scope>provided</scope>
        </dependency>
    
        <dependency>
          <groupId>com.sun.activation</groupId>
          <artifactId>javax.activation</artifactId>
          <version>1.2.0</version>
        </dependency>
    
        <dependency>
          <groupId>javax.xml.bind</groupId>
          <artifactId>jaxb-api</artifactId>
          <version>2.3.1</version>
        </dependency>
    
        <dependency>
          <groupId>com.sun.xml.bind</groupId>
          <artifactId>jaxb-core</artifactId>
          <version>2.3.0.1</version>
        </dependency>
    
        <dependency>
          <groupId>com.sun.xml.bind</groupId>
          <artifactId>jaxb-impl</artifactId>
          <version>2.3.1</version>
        </dependency>
    
        <dependency>
          <groupId>org.eclipse.persistence</groupId>
          <artifactId>eclipselink</artifactId>
          <version>2.7.6</version>
        </dependency>

    <dependency>
      <groupId>jakarta.xml.bind</groupId>
      <artifactId>jakarta.xml.bind-api</artifactId>
      <version>2.3.2</version>
    </dependency>

    <dependency>
      <groupId>org.glassfish.jaxb</groupId>
      <artifactId>jaxb-runtime</artifactId>
      <version>2.3.2</version>
    </dependency>
        
      </dependencies>
    
    </project>

当我运行程序时,我得到了错误: Exception in thread "main" java.lang.NoClassDefFoundError: jakarta/xml/bind/JAXBException

Caused by: java.lang.ClassNotFoundException: jakarta.xml.bind.JAXBException

我尝试了StackOverflow for this error and most of the answers mentioned adding the dependency`上提到的很多东西我已经添加了答案中提到的所有依赖项。我不确定出了什么问题。

有人可以帮我解决这个问题吗?

【问题讨论】:

  • 您的pom.xml 文件是否有一个构建步骤来确保jaxb.properties 文件被捆绑到Maven 构建的JAR(或WAR)中?
  • 我在this other question 的回答中添加了有关所需 Maven 构建步骤的注释,以防万一。除此之外,我无法重现您的问题。当我将它与这个额外的构建步骤一起使用时,您的代码会生成预期的 XML(但并非没有!)。
  • 非常感谢您查看并提供答案。我有点能够弄清楚这个问题。我在文件夹resources-&gt;model-&gt;jaxb 中添加了我的jaxb.properties 文件,与domain classes which will be used by jaxb 的结构相同,之后我添加了您的答案中提到的依赖项以及另外两个依赖项,例如org.glassfish.jaxbjakarta.xml.bind。现在它向我抛出错误Exception in thread "main" java.lang.NoClassDefFoundError: jakarta/xml/bind/JAXBContext
  • 好的 - 但是如果您恢复到我的其他答案中的依赖项,并且如果您添加 关于 Maven 构建的步骤, 那么它是否适合您(因为您的代码为我工作)。然后,如果需要,您可以开始调整依赖关系 - 但您将从有效的配置中进行调整。
  • 很高兴你解决了它!好的!欢迎您在这里answer your own question 描述您如何解决问题 - 您自己的观点会有所帮助。如果您愿意(并且这样做当然是 100% 可选),您也可以投票给另一个答案 here

标签: java xml jaxb eclipselink moxy


【解决方案1】:

在@andrewjames 的大力协助下,终于找到了解决方案。发布相同的解决方案,以便有人可以快速找到解决方案,而不会像我一样花费一整天:)

您也可以按照@andrewjames in his answer 提到的步骤进行操作。

  1. 确保在与域类相同的包中只有一份jaxb.properties 文件副本(在这种情况下,将在编组过程中使用Customer.class)。文件内容应为:

    jakarta.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory

2.从 pom.xml 文件中删除所有依赖项,只需添加以下 2 个依赖项:

<dependency>
    <groupId>jakarta.xml.bind</groupId>
    <artifactId>jakarta.xml.bind-api</artifactId>
    <version>3.0.1</version>
</dependency>

<dependency>
    <groupId>org.eclipse.persistence</groupId>
    <artifactId>eclipselink</artifactId>
    <version>3.0.0</version>
</dependency>
  1. 确保您的所有类(在本例中为 Customer.classDemo.ckass)都使用来自 import jakarta.xml.bind.JAXBContext; 的导入。

以前取自 import javax.xml.bind.JAXBContext; 的内容应替换为 import jakarta.xml.bind.JAXBContext;

我正在更改 Demo.class 并忘记更改 Customer.class 所以看到了一些 defclass 问题。因此,请确保您的所有班级都使用来自 Jakarta 而不是来自 Javax 的导入。

  1. 将以下&lt;build&gt; 添加到您的pom.xml
      <build>
        <resources>
          <resource>
            <directory>src/main/java</directory>
            <excludes>
              <exclude>**/*.java</exclude>
            </excludes>
          </resource>
        </resources>
      </build>
  1. 在进行这些更改后运行Demo.class,这应该会为您提供预期的XML。 @XmlPath 也应该按预期工作。

以下是我犯的一些错误。你可以检查你是否没有制作它们:

  1. 我有太多的依赖关系,有些也被重复了。例如来自com.sun.activationjavax.activationjavax.validationorg.glassfish.jaxb 等的依赖项。其他答案中提到了这些,所以我正在尝试一切。最好全部删除并重新开始,只添加一次需要的。对于这种情况,step-2 中仅提及 2 个就足够了。

  2. Stackoverflow 上的大部分帖子中提到的答案都是针对旧版本的。包括各种网站上的文章和博客。由于Java 11 之后发生了一些变化,因此最好使用最新版本以及此答案中提到的步骤或上面链接提供的其他答案。

  3. 确保清理并重建 maven 项目,因为有时在保存 pom.xml 文件时不会直接添加 dependencies。至少在我使用Intellij IDE 时是这样。每次添加依赖项时,我都在进行清理和构建,以确保从Maven 方面一切正常。

这就是我认为足以完成这项工作的所有要点。如果您仍然面临一些问题,请在其他帖子或此处发表评论。如果可以的话,我会尽量回答。祝你有美好的一天。

【讨论】:

    猜你喜欢
    • 2021-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-19
    • 1970-01-01
    • 2012-04-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多