首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >@XmlPath在JAXB编组期间没有影响

@XmlPath在JAXB编组期间没有影响
EN

Stack Overflow用户
提问于 2021-05-12 09:09:09
回答 1查看 534关注 0票数 1

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

我正在跟踪创始人(@XmlPath上的博客)的博客,以使其正常工作,但出于某种原因,@XmlPath没有任何影响,输出的XML与博客中所示的不匹配。我跟踪了博客中提到的所有过程,在这里也提到了各种答案。

我的所有类都在model.jaxb包中。此外,我还在该包中创建了一个jaxb.properties文件。

以下是我的Customer课程:

代码语言:javascript
复制
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课程:

代码语言:javascript
复制
@Getter
@Setter
@NoArgsConstructor
public class Address {

  private String street;

}

以下是Demo课程:

代码语言:javascript
复制
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似乎没有任何影响。

代码语言:javascript
复制
<customer>
    <billingAddress>
        <street>1 Billing Street</street>
    </billingAddress>
    <shippingAddress>
        <street>2 Shipping Road</street>
    </shippingAddress>
</customer>

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

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

根据博客,输出XML应该如下所示:

代码语言:javascript
复制
<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 -> Project Structure,我使用的是Java15.0.01版本。我看到了一个答案,其中提到了Moxy并不能直接在Java 11 回答上面的Java 11.0之上工作。

所以我做了以下事情:

  1. 我添加了上面的答案中提到的依赖项和build,所以我的pom.xml看起来如下所示:
代码语言:javascript
复制
    <?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依赖性的东西,我已经添加了答案中提到的所有依赖项。我不知道出了什么问题。

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

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-05-13 07:02:47

最后,在@andrewjames的大量帮助下找到了解决方案。发布相同的解决方案,这样某人就可以快速找到解决方案,并且不会像我一样整天都在浪费时间:)

您还可以遵循@andrewjames 在他的回答中中提到的步骤。

  1. 确保在域类的同一包中只有一个jaxb.properties文件的副本(在编组过程中使用的是Customer.class)。文件的内容应该是: jakarta.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory

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

代码语言:javascript
复制
<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. 将以下<build>添加到pom.xml
代码语言:javascript
复制
      <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. Stackoverflow上的大多数帖子中提到的答案都是旧版本的。包括各种网站上的文章和博客。由于在Java 11之后发生了一些更改,所以最好使用这个答案中提到的最新版本和步骤,或者使用上面的链接提供的其他答案。
  3. 确保清理和重新构建maven项目,因为有时在保存dependencies文件时不直接添加pom.xml。至少在我使用Intellij IDE的时候。每次添加依赖项时,我都会进行清理和构建,这样我就可以确保Maven方面的一切都很好。

这就是我认为足以使这件事成功的所有要点。如果你仍然面临一些问题,请在另一篇文章或这里留下评论。如果可以的话,我会尽力回答的。祝您今天愉快。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67500565

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档