23 de dez de 2012

XML com JAXB


O JAXB é um framework Java para processamento de documentos XML. Com ele ó possível converter um XML direto em um bean, o que não era possível por exemplo com DOM.

O JAXB usa anotações para representar elementos, atributos e valores das tags do XML. Como a intenção aqui é apenas introduzir nos senhores, com todo o respeito, vamos à algumas dessas anotações:

  • @XmlRootElement – representa o elemento principal, ou a tag principal do XML.
  • @XmlAccessorType – define onde as anotações JAXB devem ser interpretadas, nos métodos ou atributos
  • @XmlElement – representa uma tag dentro do XML
  • @XmlElementWrapper – encapsula uma lista
  • @XmlAttribute – representa um atributo dentro de uma tag


Antes de começar a desenvolver você vai precisar das dependências:

 javax.xml.bind
 jaxb-api
 2.2.6


 com.sun.xml.bind
 jaxb-impl
 2.2.6


Supunhetamos que nosso modelo de XML seja o seguinte:

    João Borra Cueca
    24
    
        
        
    


Portanto, os beans vão ficar anotados da seguinte maneira:

Pessoa.java
package com.jaxbexample.model;

import java.util.ArrayList;
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="pessoa")
@XmlAccessorType(XmlAccessType.FIELD)
public class Pessoa {
    
    @XmlElement
    private String nome;
    
    @XmlElement
    private Integer idade;
    
    @XmlElementWrapper(name="telefones")
    @XmlElement(name="telefone")
    private List telefones;

    public Integer getIdade() {
        return idade;
    }

    public void setIdade(Integer idade) {
        this.idade = idade;
    }

    public String getNome() {
        return nome;
    }

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

    public List getTelefones() {
        return telefones;
    }

    public void setTelefones(List telefones) {
        this.telefones = telefones;
    }
    
    public void addTelefone(Telefone telefone){
        if(telefones==null)
            telefones = new ArrayList();
        telefones.add(telefone);
    }
    
}

Telefone.java
package com.jaxbexample.model;

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

@XmlAccessorType(XmlAccessType.FIELD)
public class Telefone {

    @XmlAttribute(name="codArea")
    private String codArea;
    
    @XmlAttribute(name="numero")
    private String numero;

    public Telefone() {
    }

    public Telefone(String codArea, String numero) {
        this.codArea = codArea;
        this.numero = numero;
    }

    public String getCodArea() {
        return codArea;
    }

    public void setCodArea(String codArea) {
        this.codArea = codArea;
    }

    public String getNumero() {
        return numero;
    }

    public void setNumero(String numero) {
        this.numero = numero;
    }
    
}
Marshalling: é o processo de conversão do bean em xml.

Marshallling.java
package com.jaxbexample;

import com.jaxbexample.model.Pessoa;
import com.jaxbexample.model.Telefone;
import java.io.StringWriter;
import java.io.Writer;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.PropertyException;

public class Marshalling {

    public static void main(String[] args) {

        try {
            
            Pessoa pessoa = new Pessoa();
            pessoa.setNome("João Borra Cueca");
            pessoa.setIdade(24);
            pessoa.addTelefone(new Telefone("12", "1234-5678"));
            pessoa.addTelefone(new Telefone("84", "5678-0123"));
            
            Writer writer = new StringWriter();
            JAXBContext context = JAXBContext.newInstance(Pessoa.class);
            Marshaller marshaller = context.createMarshaller();
            marshaller.setProperty(javax.xml.bind.Marshaller.JAXB_FORMATTED_OUTPUT, true);
            marshaller.marshal(pessoa, writer);
            
            System.out.println(writer.toString());
            
        } catch (PropertyException e) {
            e.printStackTrace();
        } catch (JAXBException e) {
            e.printStackTrace();
        }
        
    }
}

Unmarshalling: é o inverso do marshalling, conversão de xml em um bean

Unmarshilling
package com.jaxbexample;

import com.jaxbexample.model.Pessoa;
import java.io.StringReader;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.PropertyException;
import javax.xml.bind.Unmarshaller;

public class Unmarshalling {
    
    public static void main(String[] args) {

        try {
            
            String xml = ""
                            + "Oscar Alho"
                            + "24"
                            + ""
                                + ""
                                + ""
                            + ""
                        + "";
            
            JAXBContext context = JAXBContext.newInstance(Pessoa.class);
            Unmarshaller unmarshaller = context.createUnmarshaller();
            
            Pessoa pessoa = (Pessoa)unmarshaller.unmarshal(new StringReader(xml));
            
            System.out.println(pessoa.getNome());
            
        } catch (PropertyException e) {
            e.printStackTrace();
        } catch (JAXBException e) {
            e.printStackTrace();
        }
        
    }
}

O JAXB é bastante usado, principalmente em frameworks para implementação de web-services. Mas isso é assunto para um outro post.

Código Fonte: http://depositfiles.com/files/i8np23h4f

É isso ae, peixe! Aqui é Java!

8 de dez de 2012

Spring Injection - NoSuchBeanDefinitionException: No unique bean of type


Como vimos no post anterior, injeção de dependência é o bicho. Usando annotations o trabalho fica ainda mais simples. Mas como nem tudo nessa vida são flores...

Vamos imaginar o seguinte cenário. Usando o mesmo exemplo do post anterior, com uma modificação. Agora Printer é uma interface com duas implementações:

Printer.java
public interface Printer {
    
    void print(String text);
    
}

ConsolePrinter.java
@Component
public class ConsolePrinter implements Printer{

    public void print(String text) {
        System.out.print(text);
    }
    
}

FilePrinter.java
@Component
public class FilePrinter implements Printer{

    public void print(String text) {
        ...
    }   
}

Compile o programa... Opa, funcionou!

Execute o programa... Ops!!! Runtime Exception.

org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [com.springinjectionexample2.Printer] is defined: expected single matching bean but found 2: [consolePrinter, filePrinter]

E agora???

O Spring não é vidente, existem dois beans que implementam a interface Printer. Você precisa indicar qual deles deseja usar.

O @Qualifier vai nos ajudar. Vamos fazer uma pequena modificação no AppServices.java
@Service
public class AppServices {
    
    @Autowired
    @Qualifier("consolePrinter") //ou @Qualifier("filePrinter")
    private Printer printer;
    
    public void print(String text){
        printer.print(text);
    }
    
    public void print(Integer number){
        if(number!=null)
            printer.print(number.toString());
    }   
}

Pronto, agora o Spring já sabe qual bean deve utilizar!

O ensinamento de hoje foi esse, pequeno Padawan! May the Java be with you!

Código Fonte: http://depositfiles.com/files/fkrwow6mr

É isso ae, cambada. Aqui é Java!

5 de dez de 2012

Injeção de dependência usando Spring e Annotations


Acho que muitos já ouviram falar ou já trabalharam com Spring. Pois bem, o Spring é um framework Java muito poderoso que implementa entre outras funcionalidades a Injeção de Dependência.

Usando o Spring você poderia muito bem fazer a injeção através de um arquivo XML, criando os beans e referências, o que não é muito complexo. Mas convenhamos, que trabalho de corno!

Para tornar a vida do programador mais fácil, existe a possibilidade e fazer as injeções usando annotations e é isso que veremos a seguir.

Primeiramente você vai precisar da biblioteca do Spring. Segue a dependência para configurar no maven:

 org.springframework
 spring
 2.5.6            


No segundo passo vamos criar as classes da nossa aplicação. Repare nas annotations, elas servirão de referência para o Spring criar as instâncias e injetar as dependências:
  • @Component – indica que é uma classe componente, isto é, quando o Spring efetuar o scanning do código ele deve criar uma instância para a classe. Funciona exatamente como a tag na configuração do XML.
  • @Service – ele extende o @Component, funciona da mesma maneira só que indica que é uma classe específica de serviço.
  • @Autowired – busca a instância da classe criada pelo Spring e insere no atributo.

Printer.java
package com.springinjectionexample;

import org.springframework.stereotype.Component;

@Component
public class Printer {

    public void print(String text){
        System.out.println(text);
    }
    
}

AppServices.java
package com.springinjectionexample;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class AppServices {
    
    @Autowired
    private Printer printer;
    
    public void print(String text){
        printer.print(text);
    }
    
    public void print(Integer number){
        if(number!=null)
            printer.print(number.toString());
    }
}

No XML de configuração do Spring vamos inserir a seguinte tag:


A tag indica ao Spring que ele deve efetuar o scan de componentes no pacote “com.springinjectionexample”, criar as instâncias e fazer as injeções.

applicationContext.xml

 
 
 


Pronto, agora é só colocar a aplicação abaixo para rodar:

App.java
package com.springinjectionexample;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App{
    
    public static void main( String[] args ){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        
        AppServices appServices = (AppServices)context.getBean("appServices");
        
        appServices.print("Me imprime!");
        appServices.print(99);        
    }
}

Só fazendo uma comparação, se fossemos utilizar a configuração apenas com o applicationContext.xml ele ficaria assim:


 
 
  
 
 
 
 



Referência: http://static.springsource.org/spring/docs/2.5.3/reference/beans.html

Código Fonte: http://depositfiles.com/files/dewske0wz

É isso ae, cambada. Aqui é Java!