Serialização XML em Java? [fechadas]

104

Qual é o análogo Java da serialização XML do .NET?

Dmitry Shechtman
fonte
6
Ah, os velhos tempos gloriosos quando perguntas curtas como esta eram bem-vindas no SO. Tão útil. Sem todo aquele absurdo "O que você tentou?" / "Forneça detalhes" que as pessoas gostam de ler hoje.
GOTO 0

Respostas:

81

Resposta de 2008 A API Java "oficial" para isso agora é JAXB - Java API para XML Binding. Veja o Tutorial da Oracle . A implementação de referência está em http://jaxb.java.net/

Atualização de 2018 Observe que os módulos Java EE e CORBA estão obsoletos no SE no JDK9 e devem ser removidos do SE no JDK11 . Portanto, para usar JAXB, ele precisará estar em seu ambiente de classe empresarial existente empacotado por seu servidor de aplicativo, por exemplo, ou você precisará trazê-lo manualmente.

Cheekysoft
fonte
2
Isso mesmo, JAXB é definitivamente a melhor opção!
ivan_ivanovich_ivanoff
1
O JAXB foi removido das distribuições java padrão a partir do Java 10, o que o torna agora uma biblioteca que você deve empacotar com seu aplicativo se quiser, a menos que esteja operando em um contexto que já empacote para você.
Theodore Murdock
69

XStream é muito bom em serializar objetos para XML sem muita configuração e dinheiro! (está sob licença BSD).

Nós o usamos em um de nossos projetos para substituir a velha serialização de java e funcionou quase fora da caixa.

Barak Schiller
fonte
3
Muito útil, ele pode ter problemas em estruturas de árvore complicadas como JGraph com objetos de nó não string.
mikek3332002
Mais simples e melhor do que outras soluções
daitangio
Eu gosto de XStream. A única coisa é que não entendo por que um caractere é adicionado antes do XML real.
James P.
17

Projeto de "serialização XML simples"

Você pode querer dar uma olhada no projeto Simple XML Serialization . É a coisa mais próxima que encontrei do System.Xml.Serialization em .Net.

ARKBAN
fonte
No entanto, requer anotações de mapeamento para cada campo.
mP.
1
Não é verdade, eu não exijo. Você pode alterar o comportamento padrão e ele usará apenas os campos presentes.
damluar
1
Eu endosso veementemente "Simples" também. Usei-o em alguns projetos com grande sucesso. "Simples" é de fato muito mais simples que JAXB. Mais apropriado quando você tem necessidades relativamente simples: Objetos adquiridos que precisam ser gravados no armazenamento para serem reidratados como objetos novamente. JAXB tem muito mais recursos e flexibilidade, mas é um tipo de coisa "80/20", na maioria das vezes, na maioria dos projetos, você pode precisar apenas de um subconjunto simples de recursos.
Basil Bourque
Funciona bem se você quiser apenas um mapeamento 1: 1. Se suas classes evoluírem e você ainda precisar desserializar o XML antigo, terá problemas porque a documentação e as mensagens de erro são um tanto vagas. Diagnosticar o problema geralmente é possível, mas descobrir como corrigi-lo pode levar vários dias.
toolforger
13

JAXB faz parte da edição padrão JDK versão 1.6+. Assim é FREEe sem bibliotecas extras para baixar e gerenciar. Um exemplo simples pode ser encontrado aqui

XStream parece estar morto. A última atualização foi em 6 de dezembro de 2008. Simpleparece tão fácil e simples quanto JAXB, mas não consegui encontrar nenhuma informação de licenciamento para avaliá-lo para uso empresarial.

so_mv
fonte
4
O XStream não está morto, ele está apenas maduro e estável - o que significa que não há muito a acrescentar à funcionalidade principal. O mesmo é verdade para a implementação de referência JAXB, sem muita atividade nos últimos dois anos.
StaxMan
9

Vale ressaltar que desde a versão 1.4, o Java possuía as classes java.beans.XMLEncoder e java.beans.XMLDecoder. Essas classes executam codificação XML que é pelo menos muito comparável à serialização XML e, em algumas circunstâncias, pode fazer o truque para você.

Se sua classe seguir a especificação JavaBeans para seus getters e setters, esse método é direto de usar e você não precisa de um esquema. Com as seguintes ressalvas:

  • Tal como acontece com a serialização Java normal
    • codificação e decodificação executados em um InputStream e OutputStream
    • o processo usa os métodos familar writeObject e readObject
  • Em contraste com a serialização Java normal
    • a codificação, mas também a decodificação, faz com que os construtores e inicializadores sejam chamados
    • codificação e decodificação funcionam independentemente se sua classe implementa Serializable ou não
    • modificadores transitórios não são levados em consideração
    • funciona apenas para classes públicas, que têm construtores públicos

Por exemplo, tome a seguinte declaração:

public class NPair {
  public NPair() { }
  int number1 = 0;
  int number2 = 0;
  public void setNumber1(int value) { number1 = value;}
  public int getNumber1() { return number1; }
  public void setNumber2(int value) { number2 = value; }
  public int getNumber2() {return number2;}
}

Executando este código:

NPair fe = new NPair();
fe.setNumber1(12);
fe.setNumber2(13);
FileOutputStream fos1 = new FileOutputStream("d:\\ser.xml");
java.beans.XMLEncoder xe1 = new java.beans.XMLEncoder(fos1);
xe1.writeObject(fe);
xe1.close();

Resultaria no seguinte arquivo:

<?xml version="1.0" encoding="UTF-8"?>
<java version="1.7.0_02" class="java.beans.XMLDecoder">
 <object class="NPair">
  <void property="number1">
   <int>12</int>
  </void>
  <void property="number2">
   <int>13</int>
  </void>
 </object>
</java>
Mishax
fonte
Esteja ciente de que o uso de java.beans.XMLDecoderdados fornecidos pelo usuário pode introduzir vulnerabilidades de execução de código arbitrário em seu código.
aventurin de
2

XMLBeans funciona muito bem se você tiver um esquema para seu XML. Ele cria objetos Java para o esquema e métodos de análise fáceis de usar.

John Meagher
fonte
0

Se você está falando sobre serialização XML automática de objetos, verifique o Castor :

Castor é uma estrutura de vinculação de dados de código aberto para Java [tm]. É o caminho mais curto entre objetos Java, documentos XML e tabelas relacionais. O Castor fornece vinculação Java para XML, persistência de Java para SQL e muito mais.

Theo
fonte
0

Normalmente, eu uso jaxb ou XMLBeans se preciso criar objetos serializáveis ​​para XML. Agora, posso ver que o XStream pode ser muito útil, pois não é intrusivo e tem uma API muito simples. Vou brincar com ele em breve e provavelmente usá-lo. A única desvantagem que percebi é que não consigo criar o id do objeto sozinho para referência cruzada.

@Barak Schiller
Obrigado por postar link para o XStream!

Bartosz Bierkowski
fonte
O problema é que jaxb e xmlbeans requerem um esquema de mapeamento e não são auto ...
mP.
0

se você deseja uma solução estruturada (como ORM), o JAXB2 é uma boa solução.

Se você deseja uma serialização como DOT NET, então você pode usar Long Term Persistence of JavaBeans Components

A escolha depende do uso de serialização.

m.genova
fonte
-1
public static String genXmlTag(String tagName, String innerXml, String properties )
{
    return String.format("<%s %s>%s</%s>", tagName, properties, innerXml, tagName);
}

public static String genXmlTag(String tagName, String innerXml )
{
    return genXmlTag(tagName, innerXml, "");
}

public static <T> String serializeXML(List<T> list)
{
    String result = "";
    if (list.size() > 0)
    {
        T tmp = list.get(0);
        String clsName = tmp.getClass().getName();
        String[] splitCls = clsName.split("\\.");
        clsName = splitCls[splitCls.length - 1];
        Field[] fields = tmp.getClass().getFields();

        for (T t : list)
        {
            String row = "";
            try {
                for (Field f : fields)
                {
                    Object value = f.get(t);
                    row += genXmlTag(f.getName(), value == null ? "" : value.toString());
                }
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
            row = genXmlTag(clsName, row);

            result += row;
        }
    }

    result = genXmlTag("root", result);
    return result;
}
user4067649
fonte
Muitos problemas: Reinvenção da classe # getSimpleName *** Reinvenção de PropertyDescriptor *** Presume que todas as propriedades são campos acessíveis *** Não armazena em cache os resultados de reflexão (lento) *** Não há como personalizar nada (por exemplo, eu precisaria substituir nomes de classes e arquivos) *** Sem desserialização
toolforger