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

断了今生、忘了曾经 提交于 2020-01-03 21:02:57

问题


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

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

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"

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

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)

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());
    }
  }
} 

回答1:


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.

For More Information

  • http://blog.bdoughan.com/2011/06/using-jaxbs-xmlaccessortype-to.html



回答2:


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"

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

@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.



来源:https://stackoverflow.com/questions/19821896/java-jaxb-simple-parsing-is-requiring-xmlaccessortypexmlaccesstype-field-anno

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!