Como faço para marcar java.util.List com JAXB como JAX-RS (CXF e Jersey) Do [duplicado

StackOverflow https://stackoverflow.com/questions/2827788

  •  26-09-2019
  •  | 
  •  

Pergunta

Esta pergunta já tem uma resposta aqui:

Parece que os mais recentes Jax-Rs podem lidar com métodos que retornam java.util.List como o XMLROOTELEMENT, mas o Jaxb normal não pode. Eu gostaria de imitar o que CXF e Jersey estão fazendo.

Em outras palavras, eu gostaria de marcar uma lista e, assim como CXF e Jersey. Normalmente, se você tentar marcar uma lista com o JAXB, você obtém a exceção do elemento raiz. Como faço para contornar isso sem ter que fazer um objeto de embrulho?

EDIT: Obrigado pelas muitas respostas, mas estou muito familiarizado com o @xmlelementwrapper, mas isso nem chega perto de simular o que Jax-Rs está fazendo.

Jax-rs faz isso:

@XmlRootElement(name="dog")
public class Dog {
    private String name;
    public String getName() { return this.name; }
    //Setter also
}

Agora, se eu em série uma lista de cães:

serialize(List<Dog> dogs);

XML deve ser (o que Jax-Rs faz):

<dogs>
    <dog><name>Rascal</name></dog>
</dogs>

Então você pode ver que eu não quero ter que fazer um objeto de invólucro para cada objeto de domínio.

Foi útil?

Solução 7

Blaise Doughan, acredito que mostra uma boa solução para este problema aqui: É possível configurar programaticamente o JAXB?

e

http://blog.bdoughan.com/2012/11/creating-generic-list-wrapper-in-jaxb.html

E aqui, embora um caso de uso um pouco diferente:

http://blog.bdoughan.com/2012/02/xmlanyelement-and-xmladapter.html

Outras dicas

Você não poderia simplesmente acrescentar:

@XmlElementWrapper(name = "wrapperName")

Não há necessidade de fazer um objeto de invólucro. Este será então o elemento de rota em sua resposta XML marsificada.

Usei uma lista iterável personalizada usando o código a seguir, espero que isso ajude.

package bindings;

import java.io.Serializable;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

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

@XmlType
@XmlRootElement
public class CustomBindList<V> implements Iterable<V>, Serializable {
        private static final long serialVersionUID = 4449835205581297830L;

        @XmlElementWrapper(name = "List")
        @XmlElement(name = "Entry")
    private final List<V> list = new LinkedList<V>();

    public CustomBindList() {
    }

    public void add(final V obj) {
            list.add(obj);
    }

    public V get(final int index) {
        return list.get(index);
    }

    @Override
    public Iterator<V> iterator() {
        return list.iterator();
    }

    public int size() {
        return list.size();
    }
}

Eu tenho um segredo que me permite evitar estragar os mapeamentos JAXB e fazer com que tudo funcione magicamente.

Uso essa abordagem há anos, nunca passou até 5 minutos se preocupando com o Marshalling/Unarshalling. O segredo é .... não use Jaxb. :)

Na maioria dos meus projetos que usam Jax-Rs, eu configuro Jersey para usar o XStream e deixar o XStream descobrir como marechal/unarshal para mim. (ou Jackson para JSON)

Talvez existam alguns motivos para usar o JAXB em vez de algo como Xstream/Jackson, mas ainda não encontrei nenhum.

Mapear uma lista pode ser feito assim ..

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType
public class TestRootObject {

  @XmlElement(name = "testList") 
  private List<TestObj> testList;

  //getter setter
}

Confira Jackson, é muito compatível com as ligações do JAXB e, usando o MappingjsonFactory, você pode realmente usar o Java para XML para Java para JSON para Java.

Eu anotei minhas coleções com @XmlJavaTypeAdapter(value = Adapter.class). A classe adaptadora se estende de XmlAdapter<key, value> A chave é um identificador exclusivo para (un) marechal e o valor é o seu objeto de domínio.

Talvez isso possa ajudá -lo. No entanto, você precisa criar um adaptador para cada objeto de domínio.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top