Tag Archive | marshal

Introdução ao Java Architecture for XML Biding (JAXB)

Olá, novamente um post simples, porém com uso efetivo no desenvolvimento de software. Muitas aplicações Java utilizam arquivos eXtensible Markup Language (XML) para inúmeras funcionalidades, como armazenamento de configurações de um software e informações características dos usuários.

Este post tem por objetivo introduzir com exemplos em código fonte, o uso do Java Architecture for XML Biding (JAXB), uma biblioteca que possibilita a conversão de dados contidos em um arquivo XML para objetos Java e objetos Java para XML.

O JAXB também fornece ferramentas para criação de conteúdo XML Schema Definition (XSD) e geração de classes Java utilizando conteúdo XSD. O XSD é um tópico que não será abordado neste post.

Uma outra característica, o JAXB também pode ser inserido em aplicações Android, porém, não vem como conteúdo nativo da plataforma, portanto é necessário adicionar uma biblioteca externa, mas há outros métodos para trabalhar com conteúdo XML tanto nativos como externos, alguns são mais simples e aderem mais a tendência de aplicações que ocupem pouco espaço em disco, mas isto é um post para outro assunto.

Apesar de existirem métodos com propósitos similares em Java ao JAXB, tais como Simple API for XML (SAX) e Document Object Model (DOM), o JAXB acaba sendo uma alternativa interessante e produtiva, pois trabalha com annotations e é possível uma prototipagem simples e efetiva para solução do problema.

Antes de conhecermos annotations básicas usadas no JAXB, um exemplo de arquivo XML descritor que iremos trabalhar:

Arquivo XML descritor.

Arquivo XML descritor.

A figura acima, representa um exemplo de XML da qual iremos trabalhar. Basicamente é um cadastro fictício de uma empresa, que possui um conteúdo de fácil identificação. Note que em telefones, temos dois telefones, dos quais o segundo telefone não contém um ddd. Devemos estar atento a este exemplo, principalmente por não ser um campo necessário. Verificando o código a visualização fica trivial.

Uma página interessante para validarmos um arquivo XML é o W3Schools, link:

http://www.w3schools.com/xml/xml_validator.asp

Agora, vamos conhecer as principais anotações que serão utilizadas no tutorial para trabalhar com este conteúdo XML:

  • @XmlRootElement – Conteúdo esperado de nível superior, ou seja, nome da classe geralmente;
  • @XmlAccessorType – Indica onde as anotações do XML estão: atributos ou métodos da classe;
  • @XmlAttribute – O valor contido em um campo será atributo XML;
  • @XmlType – Classe que mapeia informações específicas;
  • @XmlElement – Atributos ou métodos;
  • @XmlElementWrapper – Objetos do tipo List.

Alguns nomes de métodos que devemos conhecer:

  • Marshal – Transforma um objeto Java em um XML;
  • Unmarshal – Transforma um XML em um objeto Java.

Em JAXB precisamos instanciar um objeto determinado como JAXBContext que fornecerá Marshaller ou Unmarshaller, interfaces do pacote javax.xml.bind. O código abaixo representa a classe Telefone, fique atento para o campo “required = false” para o ddd, que não será obrigatório.

package br.com.tutorials.content;

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

@XmlRootElement(name = "telefone")
@XmlAccessorType(XmlAccessType.FIELD)
public class Telefone {
 @XmlAttribute(name = "ddd", required = false)
 private String ddd;
 @XmlElement(name = "num", required = true)
 private Long num;

public String getDdd() {
 return ddd;
 }

public void setDdd(String ddd) {
 this.ddd = ddd;
 }

public Long getNum() {
 return num;
 }

public void setNum(Long num) {
 this.num = num;
 }
}

O código abaixo representam Endereco.

package br.com.tutorials.content;

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

@XmlRootElement(name = "endereco")
@XmlAccessorType(XmlAccessType.FIELD)
public class Endereco {

 @XmlAttribute(name = "cep", required = true)
 private String cep;
 @XmlAttribute(name = "num", required = true)
 private String num;
 @XmlAttribute(name = "pais", required = true)
 private String pais;

 @XmlElement(name = "estado", required = true)
 private String estado;
 @XmlElement(name = "cidade", required = true)
 private String cidade;
 @XmlElement(name = "rua", required = true)
 private String rua;

public String getCep() {
 return cep;
 }

public void setCep(String cep) {
 this.cep = cep;
 }

public String getNum() {
 return num;
 }

public void setNum(String num) {
 this.num = num;
 }

public String getPais() {
 return pais;
 }

public void setPais(String pais) {
 this.pais = pais;
 }

public String getEstado() {
 return estado;
 }

public void setEstado(String estado) {
 this.estado = estado;
 }

public String getCidade() {
 return cidade;
 }

public void setCidade(String cidade) {
 this.cidade = cidade;
 }

public String getRua() {
 return rua;
 }

public void setRua(String rua) {
 this.rua = rua;
 }
}

O código abaixo representa a classe Contato. Note que há o elemento Wrapper, para identificar que temos uma lista da classe Telefone, ou seja, pode existir mais de um telefone cadastrado nesta lista.

package br.com.tutorials.content;

import java.util.List;

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 = "contato")
@XmlAccessorType(XmlAccessType.FIELD)
public class Contato {
 @XmlElement(name = "email", required = false)
 private String email;

@XmlElementWrapper(name = "telefones")
 @XmlElement(name = "telefone")
 private List<Telefone> telefones;

public String getEmail() {
 return email;
 }

public void setEmail(String email) {
 this.email = email;
 }

public List<Telefone> getTelefones() {
 return telefones;
 }

public void setTelefones(List<Telefone> telefones) {
 this.telefones = telefones;
 }
}

A classe abaixo representa a Empresa cadastrada, logo possui um conteúdo indicando para as demais classes.

package br.com.tutorials.content;

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

@XmlRootElement(name = "empresa")
@XmlAccessorType(XmlAccessType.FIELD)
public class Empresa {

@XmlElement(name = "identificador", required = true)
 private String identificador;
 @XmlElement(name = "nome", required = true)
 private String nome;
 @XmlElement(name = "endereco", required = true)
 private Endereco endereco;
 @XmlElement(name = "contato", required = true)
 private Contato contato;

public String getIdentificador() {
 return identificador;
 }

public void setIdentificador(String identificador) {
 this.identificador = identificador;
 }

public String getNome() {
 return nome;
 }

public void setNome(String nome) {
 this.nome = nome;
 }

public Endereco getEndereco() {
 return endereco;
 }

public void setEndereco(Endereco endereco) {
 this.endereco = endereco;
 }

public Contato getContato() {
 return contato;
 }

public void setContato(Contato contato) {
 this.contato = contato;
 }

}

Por fim o código abaixo de teste, contém exemplos de marshal e unmarshal, com métodos simples de serem implementados.

package br.com.tutorials.content;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.StringWriter;
import java.util.ArrayList;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.transform.stream.StreamResult;

public class TestMain {

 public Object createObject() {

ArrayList<Telefone> telefones = new ArrayList<Telefone>();
 Telefone tel1 = new Telefone();
 tel1.setDdd("11");
 tel1.setNum(999999999L);

Telefone tel2 = new Telefone();
 tel2.setNum(888888888L);

telefones.add(tel1);
 telefones.add(tel2);

Contato contato = new Contato();

contato.setEmail("xmlempresa@xml.com");
 contato.setTelefones(telefones);
 Endereco endereco = new Endereco();
 endereco.setCep("43238920");
 endereco.setNum("999");
 endereco.setPais("Brasil");
 endereco.setEstado("Sao Paulo");
 endereco.setCidade("Sao Paulo");
 endereco.setRua("Rua do XML");

Empresa empresa = new Empresa();
 empresa.setIdentificador("a12130");
 empresa.setNome("Empresa de teste do XML");
 empresa.setEndereco(endereco);
 empresa.setContato(contato);

return empresa;

}
 public void marshallMethod(Object object) {
 StringWriter output = new StringWriter();
 try {
 JAXBContext jaxbContext = JAXBContext
 .newInstance(object.getClass());
 Marshaller marshal = jaxbContext.createMarshaller();
 marshal.setProperty(
 javax.xml.bind.Marshaller.JAXB_FORMATTED_OUTPUT,
 Boolean.TRUE);
 marshal.marshal(object, new StreamResult(output));
 } catch (JAXBException e) {
 e.printStackTrace();
 }
 // Pode gerar um arquivo xml com este output tambem, basta trabalhar em cima dele
 System.out.println(output);
 }

 public Object unmarshallMethod(File location) {
 try {
 JAXBContext jaxbContext = JAXBContext.newInstance(Empresa.class);
 Unmarshaller unmarshal = jaxbContext.createUnmarshaller();
 return unmarshal.unmarshal(new FileInputStream(location));
 } catch (JAXBException e) {
 e.printStackTrace();
 } catch (FileNotFoundException e) {
 e.printStackTrace();
 }
 return null;
 }

public static void main(String[] args) {
 TestMain test = new TestMain();
 Object object = test.createObject();
 test.marshallMethod(object);
 Empresa emp = (Empresa) test.unmarshallMethod(new File("post.xml"));
 // Sugiro adicionar um metodo toString para as classes: Contato,
 // Empresa, Endereco e Telefone ao inves de printar cada get
  System.out.println(emp.getIdentificador());
 }
}

Por hoje é só, espero que seja de grande ajuda o uso desta poderosa biblioteca para trabalhar com conteúdo XML, até a próxima.

Observações: O código continha muitos comentários, como anotações de retorno etc., porém o WordPress não aceitou, não entendi o motivo =/

Obrigado.

Referências:
JAXB Project. JAXB Tutorial. Disponível em: https://jaxb.java.net/tutorial/ (Acessado em: 22/09/2013) Está página contém de maneira descritiva inúmeros exemplos do uso da biblioteca, essencial para o aprendizado.

Anúncios