java jaxb 简单解析需要@XmlAccessorType(XmlAccessType.FIELD) 注解

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19821896/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 20:29:05  来源:igfitidea点击:

java jaxb simple parsing is requiring @XmlAccessorType(XmlAccessType.FIELD) annotation

javaxmlxml-parsingjaxbjaxb2

提问by code4jhon

I am trying to parse an xml to java objects, I've read and implemented the following tutorial:

我正在尝试将 xml 解析为 java 对象,我已经阅读并实现了以下教程:

http://www.vogella.com/articles/JAXB/article.html(works perfectly)

http://www.vogella.com/articles/JAXB/article.html(完美运行)

But when I create my own clases (similar to those in the tutorial)

但是当我创建自己的类时(类似于教程中的类)

I get: Exception in thread "main" com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions Class has two properties of the same name "clienteList"

我得到:线程“main”中的异常 com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions Class 有两个同名的属性“clienteList”

Unless I use @XmlAccessorType(XmlAccessType.FIELD) on class Clientes but in the tutorial is not being used.

除非我在类 Clientes 上使用 @XmlAccessorType(XmlAccessType.FIELD) 但在教程中没有使用。

Any ideas ?

有任何想法吗 ?

(It works fine with the @XmlAccessorType(XmlAccessType.FIELD) annotation but I want to know why is it being required with my classes while it is not for the classes in the tutorial)

(它适用于 @XmlAccessorType(XmlAccessType.FIELD) 注释,但我想知道为什么我的类需要它而教程中的类不需要它)

Thank you in advance for any information.

预先感谢您提供任何信息。

Class Cliente

班级客户

package mx.com.findep.crediseguros.dto.servicios.finsol;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "cliente")
public class Cliente {

  private String numeroPersona;

  @XmlElement(name = "numeroPersona")
  public String getNumeroPersona() {
    return numeroPersona;
  }

  public void setNumeroPersona(String numeroPersona) {
    this.numeroPersona = numeroPersona;
  }

} 

Class Clientes

班级客户

package mx.com.findep.crediseguros.dto.servicios.finsol;

import java.util.ArrayList;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "clientes")
//@XmlAccessorType(XmlAccessType.FIELD) //without this line it fails
public class Clientes {

      // XmLElementWrapper generates a wrapper element around XML representation
      @XmlElementWrapper(name = "clienteList")
      // XmlElement sets the name of the entities
      @XmlElement(name = "cliente")
      private ArrayList<Cliente> clienteList;


      public void setClienteList(ArrayList<Cliente> clienteList) {
        this.clienteList = clienteList;
      }

      public ArrayList<Cliente> getClienteList() {
        return clienteList;
      }


    }

Testing My Marshalling

测试我的编组

package mx.com.findep.crediseguros.dto.servicios.finsol;

import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;


public class TestClientesXml {

  private static final String SOME_XML = "C:/bea/user_projects/domains/DominioDesarrollo/esquemas/calculoCostoSeguroPeticion.xml";

  public static void main(String[] args) throws JAXBException, IOException {

    ArrayList<Cliente> clienteList = new ArrayList<Cliente>();

    Cliente cliente1 = new Cliente();
    cliente1.setNumeroPersona("1");

    clienteList.add(cliente1);

    Cliente cliente2 = new Cliente();
    cliente2.setNumeroPersona("2");
    clienteList.add(cliente2);

    Clientes clientes = new Clientes();

    clientes.setClienteList(clienteList);

    JAXBContext context = JAXBContext.newInstance(Clientes.class);
    Marshaller m = context.createMarshaller();
    m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);

    m.marshal(clientes, System.out);

    m.marshal(clientes, new File(SOME_XML));

    System.out.println();
    System.out.println("Output from our XML File: ");
    Unmarshaller um = context.createUnmarshaller();
    Clientes clientes2 = (Clientes) um.unmarshal(new FileReader(SOME_XML));
    ArrayList<Cliente> list = clientes2.getClienteList();
    for (Cliente cliente : list) {
      System.out.println("Cliente: " + cliente.getNumeroPersona());
    }
  }
} 

采纳答案by bdoughan

By default JAXB treats public fields and properties as mapped. If you annotate a field it then considers the field and property as mapped causing the conflict. Without @XmlAccessorType(XmlAccessType.FIELD)you should annotate the get or set method.

默认情况下,JAXB 将公共字段和属性视为映射。如果您注释一个字段,则它会将字段和属性视为导致冲突的映射。没有@XmlAccessorType(XmlAccessType.FIELD)你应该注释 get 或 set 方法。

For More Information

想要查询更多的信息

回答by Xelian

So lets say we have:

所以让我们说我们有:

@XmlRootElement(name = "book")
public class Book {
    @XmlElement(name = "book_title")
    private String title;
    public getTitle(){..}
    public setTitle(){...}
    }

if we run the code we will have Exception in thread "main"

如果我们运行代码,我们将在线程“main”中出现异常

com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions
Class has two properties of the same name "title"
    this problem is related to the following location:
        at public java.lang.String com.example.jaxb.Book.getTitle()
        at com.example.jaxb.Book
    this problem is related to the following location:
        at private java.lang.String com.example.jaxb.Book.title
        at com.example.jaxb.Book

But if we add the annotation: XmlAccessorType

但是如果我们添加注解:XmlAccessorType

@XmlRootElement(name = "book")
@XmlAccessorType(XmlAccessType.FIELD)
public class Book {

the error will disappear.

错误将消失。

When have class which want to marshall and have 10 fields, I prefer to annotate only fields, not one time the setter then the getter. So use @XmlAccessorType and annotate only the fields.

当有想要编组并有 10 个字段的类时,我更喜欢只注释字段,而不是一次是 setter 然后是 getter。所以使用@XmlAccessorType 并只注释字段。