@XmlPath 在 JAXB 编组期间没有影响 [英] @XmlPath has no impact during the JAXB Marshalling

查看:40
本文介绍了@XmlPath 在 JAXB 编组期间没有影响的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am trying to create XML using the JaxB Marshalling approach. I want to skip the parent tag for certain children or may add a new XML parent tag for a certain element. Hence I am trying to use the @XmlPath from import org.eclipse.persistence.oxm.annotations.XmlPath;.

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

I am following the blog from the founder (Blog on @XmlPath) to make it work but for some reason, the @XmlPath has no impact and the output XML does not match as shown in the blog. I followed all the process mentioned within the blog and also mentioned on various answers here.

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

All my classes are within the model.jaxb package. Also, I have created a jaxb.properties file within that package.

以下是我的 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 在编组过程中没有影响.

The XML I getting with and without @XmlPath are the same actually. So seems like the @XmlPath has no impact during the marshalling.

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

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

I have created jaxb.properties file within my package model.jaxb with the content:

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

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

As per the blog the output XML should be something like this:

<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.我尝试了很多东西,但都没有奏效,所以在这里发布相同的内容.

I am not sure what am I doing wrong due to which I am unable to get the XML as I expect. I tried a lot of things but none worked so posting the same here.

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

Can someone please help me with how can I make the @XmlPath kicking during the marshalling so that I can get the expected tag during the marshalling?

**** 编辑 *****

**** EDITED *****

我根据 Intellij IDE 文件使用 Java 15.0.01 版 ->项目结构.我看到一个答案,它提到 Moxy 不能直接在 Java 11 上方工作 AnswerJava 11.0 以上.

I am using Java version 15.0.01 as per the Intellij IDE File -> Project Structure. I saw one answer where it mentioned Moxy does not work directly above Java 11 Answer Java 11.0 above.

所以我做了以下事情:

  1. 我添加了上面答案中提到的依赖项和 build,所以我的 pom.xml 看起来像这样:
  1. I added the dependency and build as mentioned in the above answer so my pom.xml looks something like this:

    <?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>

当我运行程序时,出现错误:线程main"中的异常java.lang.NoClassDefFoundError: jakarta/xml/bind/JAXBException

When I run the program then I get the error: Exception in thread "main" java.lang.NoClassDefFoundError: jakarta/xml/bind/JAXBException

引起:java.lang.ClassNotFoundException:jakarta.xml.bind.JAXBException

我针对此错误尝试了 StackOverflow 上提到的很多内容,并且大多数答案都提到了添加 dependency` 我已经添加了答案中提到的所有依赖项.我不确定出了什么问题.

I tried a lot of things mentioned on StackOverflow for this error and most of the answers mentioned adding the dependency` I have added all the dependency mentioned in the answer. I am not sure what's going wrong.

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

Can someone please assist me with how can I fix this issue?

推荐答案

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

Finally was able to find the solution with a lot of assist from @andrewjames. Posting the solution for the same so somebody can find the solution quickly and do not end up spending whole day like me :)

您也可以按照@andrewjames 中提到的步骤进行操作他的回答.

You can also follow the steps mentioned by @andrewjames in his answer.

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

  1. Make sure you have only ONE copy of jaxb.properties file within the same package as of the domain class (the one which will be used during the marshalling in this case the Customer.class). The content of the file should be:

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

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

2.从您的 pom.xml 文件中删除所有依赖项,然后添加以下 2 个依赖项:

2.Remove all the dependency from your pom.xml file and just add the following 2 dependencies:

<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 的导入;.
  1. Make sure all your classes (in this case Customer.class and Demo.ckass) are using the imports from import jakarta.xml.bind.JAXBContext;.

以前它取自 import javax.xml.bind.JAXBContext; 应替换自 import jakarta.xml.bind.JAXBContext;.

Previously it was taking from import javax.xml.bind.JAXBContext; should be replaced from import jakarta.xml.bind.JAXBContext;.

我正在对 Demo.class 进行更改,但忘记在 Customer.class 中进行更改,因此看到了一些 defclass 问题.因此,请确保您的所有类都使用来自 Jakarta 而不是来自 Javax 的导入.

I was making changes to Demo.class and forgot to change in Customer.class so was seeing some defclass issue. So make sure all your class uses the imports from Jakarta and not from Javax.

  1. 将以下 添加到您的 pom.xml:
  1. Add the following <build> to your pom.xml:

      <build>
        <resources>
          <resource>
            <directory>src/main/java</directory>
            <excludes>
              <exclude>**/*.java</exclude>
            </excludes>
          </resource>
        </resources>
      </build>

  1. 在进行这些更改后,运行 Demo.class 这应该会为您提供预期的 XML.此外 @XmlPath 应该按预期工作.
  1. After making these changes run the Demo.class this should give you the expected XML. Also @XmlPath should work as expected.

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

Following are some of the mistakes I was making. You can check if you are not making them:

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

  1. I was having too many dependencies and some were duplicated also. Such as dependencies from com.sun.activation, javax.activation, javax.validation, org.glassfish.jaxb, etc. These were mentioned in other answers so I was trying everything. Better remove all and make a fresh start and add only the once needed. For this case, only 2 mentioned in step-2 would be sufficient.

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

The answers mentioned in most of the post on Stackoverflow is for the old version. Including the articles and blogs on various website. As there has been some changes after Java 11 better use the latest version and the steps mentioned in this answer or the other answer provided with the link above.

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

Make sure you clean and rebuild the maven project because sometimes the dependencies are not directly added when you save the pom.xml file. At least in my case when I was using the Intellij IDE. I was doing clean and build every time I added the dependency so that I am making sure everything is fine from Maven side.

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

That's all the points I feel sufficient for making this work. If you are still facing some issue then leave a comment on the other post or here. I will try to answer if I can. Have a nice day.

这篇关于@XmlPath 在 JAXB 编组期间没有影响的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆