Artigos com a Tag ‘java’

“De volta para o futuro” com Java

quarta-feira, 27 de junho de 2012

O trabalho do Dr. Emmett Brown (Back to the Future) poderia ter sido mais fácil se a plataforma Java existisse em 1985. Ele poderia ter implementado o sistema do DeLorean em Java e viajar no tempo facilmente. Vejamos um exemplo de viagem no tempo em Java.

Suponha que estamos na capital da Venezuela (Caracas) no dia 9 de Dezembro de 2007 as 02:29:59. No segundo seguinte, as 02:30:00, poderíamos viajar 30 minutos para o futuro, ou seja, viajar para as 3:00:00. Veja o código java abaixo.

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;

public class DeLoreanK19 {
	public static void main(String[] args) throws ParseException {
		TimeZone.setDefault(TimeZone.getTimeZone("America/Caracas"));

		SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");

		String s1 = "09/12/2007 02:29:59";
		String s2 = "09/12/2007 02:30:00";

		Date d1 = sdf.parse(s1);
		Date d2 = sdf.parse(s2);

		long segundos = (d2.getTime() - d1.getTime())/1000;

		System.out.println("A diferença entre as datas é: " + segundos + " segundos");
	}
}

No exemplo, utilizamos a classe java.util.TimeZone para “viajar” para a capital da Venezuela. Além disso, definimos duas datas “09/12/2007 02:29:59″ e “09/12/2007 02:30:00″. Por fim calculamos a diferença em segundos entre essas datas. O valor esperado é 1 segundo. Contudo, ao executar a classe DeLoreanK19 o valor obtido é 1801 segundos (30 minutos e 1 segundo). Por essa, nem o Dr. Emmett Brown esperava.

Infelizmente, isso não siginifica que viajamos no tempo. Também não siginifica que encontramos um Bug no Java. Na verdade, essa “viagem no tempo” é consequência da alteração no fuso horário da Venezuela que ocorreu no dia 9 de dezembro de 2007 as 3:00:00. A decisão de alterar o fuso horário da Venezuela foi tomada pelo presidente Hugo Chávez. O intuito na modificação dos horários da Venezuela é o mesmo do “Horário de Verão”, ou seja, economizar energia aproveitando melhor a luz do Sol. Veja o registro da alteração no horário da Venezuela no site timeanddate.com. Esse caso não é único. Muitos países, em algum momento, decidiram alterar o seu fuso horário por motivos políticos, econômicos, entre outros. Descubra uma outra alteração no fuso horário de algum país e tente reproduzir o problema.

Visualizar o Código Fonte Java no Eclipse

sexta-feira, 25 de maio de 2012

Nesse video, mostramos como configurar o Eclipse para mostrar o código fonte das classes do Java. Esse recurso pode ser útil para entender o funcionamento das bibliotecas Java. A configuração é bem simples e rápida. Utilizamos o Oracle JDK 7u4 que contém o código fonte das classes do Java SE em um arquivo chamado src.zip. Siga os passos apresentados no video a seguir para configurar o Eclipse Indigo no Windows 7.

JSON Simples e Prático, Parte II

terça-feira, 28 de fevereiro de 2012

Fala pessoal!

Seguindo a ideia do post anterior sobre JSON, hoje vamos a um exemplo mais palpável, real e divertido: Simular uma integração com o famoso Facebook!

O Facebook, assim como diversos sistemas, disponibiliza acesso aos seus recursos através de alguns métodos. A este conjunto de métodos, damos o nome de API.
Como visto no artigo anterior, JSON é um documento com uma estrutura bem bacana de se trabalhar.

Veja o JSON que o Facebook retorna quando chamamos certo método:

{
   "id": "19292868552",
   "name": "Facebook Platform",
   "likes": 4190683,
   "category": "Product/service",
   "is_published": true,
   "website": "http://developers.facebook.com",
   "username": "platform",
   "founded": "2007",
   "mission": "To make the web more open and social.",
   "talking_about_count": 98577
}

Interessante não? Muito fácil de ler e encontrar os dados que precisamos. Temos o id, name, likes e muitas outras informações.

Agora imagine que a nossa aplicação precisa buscar os dados de um post específico que foi colocado no Facebook. Podemos imaginar também que precisaríamos persistir esses dados em um banco pra futuras comparações, pesquisas, etc.

No nosso caso usaremos este post para estudo: www.facebook.com/98423808305.

Nao vou prolongar sobre a API do Facebook, mas para usá-la podemos usar o Graph API que o Facebook disponibiliza. Aqui temos o core da API, onde podemos ter diversos métodos para as diversas chamadas que precisamos. Caso você precise desenvolver uma app para o Face, este será o local mais odiado visitado por você! = )

Agora que você já sabe sobre a existência do Graph API, vamos usá-la!

Para o nosso exemplo vamos usar a seguinte URL:
https://graph.facebook.com/98423808305

Repare que ao clicar na URL, já temos o retorno em JSON! Isso mesmo, simples assim! Para o nosso projeto vamos precisar do Id e dos dados do From (Name e Category).

A primeira classe que criaremos é muito simples, somente para conseguirmos fazer uma chamada GET na url acima e receber o seu retorno.


package br.com.artigo.json;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;

public class Http {

    public String chamaUrl(String url) throws IOException {
      URL facebook = new URL(url);
      BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(facebook.openStream()));

      String retornoJson;

      StringBuilder builder = new StringBuilder();
      while ((retornoJson = bufferedReader.readLine()) != null)
        builder.append(retornoJson);

      bufferedReader.close();

      return builder.toString();
    }
}

A segunda classe criada será um POJO que conterá as informações que precisamos (id, name e category) vindas do facebook. Repare que esta classe facilmente poderia ser persistida, bastando inserir as anotações do JPA por exemplo! = )

package br.com.artigo.json;

public class Facebook {

	private String id;

	private String name;

	private String category;

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getCategory() {
		return category;
	}

	public void setCategory(String category) {
		this.category = category;
	}

	@Override
	public String toString() {
		return "Facebook [id=" + id + ", name=" + name + ", category="
				+ category + "]";
	}

}

A terceira classe é a ArtigoJson que será a classe principal. Ela usará a classe Http para fazer a chamada simples da API e trabalhará com o retorno JSON.

package br.com.artigo.json;

import java.io.IOException;
import java.util.Map;
import net.sf.json.JSONObject;

public class ArtigoJson {

	private static final String HTTPS_GRAPH_FACEBOOK = "https://graph.facebook.com/98423808305";

	@SuppressWarnings("unchecked")
	public static void main(String[] args) throws IOException {
		//Retorno JSON
		JSONObject object = chamadaHttp();
		System.out.println(object);

		//Retorno dos dados que precisamos
		String id = (String) object.get("id");
		Map map = (Map) object.get("from"); //Que interessante! Um cast para um Map!
		String name = map.get("name");
		String category = map.get("category");

		//Populando o objeto facebook para persistencia
		Facebook facebook = new Facebook();
		facebook.setId(id);
		facebook.setName(name);
		facebook.setCategory(category);

		//Impressão do objeto
		System.out.println(facebook);
	}

	private static JSONObject chamadaHttp() throws IOException {
		Http http = new Http();
		String retornoJson = http.chamaUrl(HTTPS_GRAPH_FACEBOOK);
		JSONObject objetoJson = JSONObject.fromObject(retornoJson);

		return objetoJson;
	}
}

Ao fazer a chamada, podemos ver um trecho do retorno:

{"id":"98423808305",
   "from":
      {"name":"Coca-Cola","category":"Food/beverages","id":"40796308305"}
}

Olha que simples! Temos neste trecho as informações que precisamos! = )
Como no artigo anterior, podemos fazer uma chamada usando uma chave. Repare que fizemos a primeira chamada usando a chave id:

//Retorno dos dados que precisamos
String id = (String) object.get("id");

Mas o mais interessante nas chamadas é o cast para um Map!

Map map = (Map) object.get("from");

Agora podemos obter os nossos dados pelo próprio Map e popular o nosso objeto facebook!

É isso pessoal! Artigo bem simples para o pessoal que está começando, somente pra mostrar uma das formas de utilização do JSON.

Você também pode encontrar este código no meu Gist Público.

Até mais!

JSON Simples e Prático, Parte I

quinta-feira, 22 de dezembro de 2011

Fala pessoal!

Esta semana percebi que muitos ainda não conhecem ou continuam na dúvida sobre o que é JSON e resolvi contribuir com mais um artigo.

Afinal, o que é JSON?
JSON é basicamente um formato leve de troca de informações/dados entre sistemas. Mas JSON significa JavaScript Object Notation, ou seja, só posso usar com JavaScript correto? Na verdade não e alguns ainda caem nesta armadilha.

O JSON além de ser um formato leve para troca de dados é também muito simples de ler. Mas quando dizemos que algo é simples, é interessante compará-lo com algo mais complexo para entendermos tal simplicidade não é? Neste caso podemos comparar o JSON com o formato XML.

Vamos visualizar esta diferença?

  <?xml version="1.0" encoding="UTF-8"?>
    <id>1</id>
    <nome>Alexandre Gama</nome>
    <endereco>R. Qualquer</endereco>
  {"id":1,"nome":"Alexandre Gama", "endereco":"R. Qualquer"}

Bom, é notável a diferença. Visualmente o segundo trecho (em JSON) é mais fácil de ler. Mas só existe essa diferença entre os dois? Na verdade não. Podemos listar algumas outras vantagens:

Vantagens do JSON:
- Leitura mais simples

- Analisador(parsing) mais fácil

- JSON suporta objetos! Sim, ele é tipado!

- Velocidade maior na execução e transporte de dados

- Arquivo com tamanho reduzido

- Quem utiliza? Google, Facebook, Yahoo!, Twitter…

Estas são algumas das vantagens apresentadas pelo JSON. Agora vamos ao que interessa: Código! :)
Vamos fazer um exemplo extremamente simples nesta primeira parte e avançaremos no próximo artigo, inclusive falando sobre JSON em páginas Web.

Qual biblioteca usar?
Existem diversas bibliotecas para trabalharmos com JSON e Java. Usaremos no nosso estudo o json.jar que você pode baixar tranquilamente neste link

O nosso caso de estudo será simples: Teremos uma classe Carro que será a nossa classe POJO e a classe EstudoJSON que terá o nosso famoso método main.

Classe Carro

package br.com.json;

public class Carro {
	private Long id;
	private String modelo;
	private String placa;

	public Long getId() {
		return id;
	}
	public void setId(Long id) {
		this.id = id;
	}
	public String getModelo() {
		return modelo;
	}
	public void setModelo(String modelo) {
		this.modelo = modelo;
	}
	public String getPlaca() {
		return placa;
	}
	public void setPlaca(String placa) {
		this.placa = placa;
	}

        //Aqui fizemos o Override do método toString() para visualizar a impressão com o System.out.println()
	@Override
	public String toString() {
		return "[id=" + id + ", modelo=" + modelo + ", placa=" + placa
				+ "]";
	}

}

Esta é uma classe simples, onde temos os atributos Id, Modelo e Placa.

Agora teremos a classe EstudoJSON

package br.com.json;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

public class EstudoJSON {
	public static void main(String[] args) throws JSONException {
		adicaoSimplesDeDados();
	}
}

Repare que criamos o método adicaoSimplesDeDados() que conterá o código de exemplo:

private static void adicaoSimplesDeDados() throws JSONException {
    //Criação do objeto carro e atribuição dos valores
	Carro carro = new Carro();
	carro.setId(1l);
	carro.setModelo("Celta");
	carro.setPlaca("AAA1234");

    //Criação do objeto carroJson
	JSONObject carroJson = new JSONObject();
    //Inserção dos valores do carro no objeto JSON
	carroJson.put("id", carro.getId());
	carroJson.put("Modelo", carro.getModelo());
	carroJson.put("Placa", carro.getPlaca());

    //Impressão do objeto JSON
	System.out.println(carroJson);
}

Se executarmos este código, veremos que foi impresso no console o seguinte:

{"id":1,"Modelo":"Celta","Placa":"AAA1234"}

Você desenvolvedor mais atento vai reparar que existe um objeto impresso: Um Long! Isso mesmo! Como vimos, o JSON consegue armazenar objetos! Podemos inclusive armazenar um objeto do tipo Carro mesmo:

Modificamos o nosso método main:

public class EstudoJSON {
	public static void main(String[] args) throws JSONException {
		adicaoSimplesDeDados();

        adicaoDeUmObjeto();
	}
}

E adicionamos o método adicaoDeUmObjeto():

private static void adicaoDeUmObjeto() throws JSONException {
	Carro carro = new Carro();
	carro.setId(1l);
	carro.setModelo("Celta");
	carro.setPlaca("AAA1234");

	JSONObject carroJson = new JSONObject();
    //Adição do objeto carro
	carroJson.put("Carro", carro);

	System.out.println(carroJson);
}

Neste caso foi impresso no console o seguinte:

{"Carro":"[id=1, modelo=Celta, placa=AAA1234]"}

Simples não?
Como o JSON trabalha com coleção de pares nome/valor, podemos imprimir um valor específico simplesmente chamando o nome que desejamos.

System.out.println(carroJson.get("Modelo"));

Veja que neste caso queremos somente o modelo do carro, bastando fazer a chamada get(“nome que desejamos”)!

Conclusão
É isso pessoal! Vimos as vantagens do JSON e vimos como é simples começar a trabalhar com ele. Nos próximos artigos veremos exemplos mais complexos e veremos algo mais real onde faremos chamadas à API do Facebook!

Você também pode encontrar este código no meu Gist Público.

Abraços!

Saiba como tirar OCJP (antiga SCJP)

quinta-feira, 13 de janeiro de 2011

Olá Pessoal,

É um prazer enorme escrever para K19. Neste post falarei um pouco sobre a SCJP/OCJP, pois há muitos mitos e discussões em fóruns desde que a Oracle fez aquisição da Sun.

O exame

Antes de responder a pergunta, quero dizer que o exame SCJP/OCJP realmente testa o conhecimento de Orientação a Objetos e Fundamentos em Java, pois o que é visto nesse exame, será cobrado por toda sua vida como programador Java. Já vi muitos programadores com anos de experiência em Java não serem aprovados pois subestimaram o exame acreditando que sua experiência era suficiente para obter a aprovação.

Quais as mudanças no exame SCJP/OCJP?

O candidato pode escolher fazer o exame em português (SCJP 5) e inglês (SCJP 6). Veja abaixo mais detalhes sobre cada um:

Para o exame SCJP 5 ou 6

Pré-requisito: Não tem

Idioma do exame: Disponível em português(SCJP 5),inglês etc.

Total de questões: 72

Percentual para aprovação: 59%

Tempo do exame: 175 minutos

Tipo do exame: Múltipla escolha e Drag-Drop (completar)

Para um candidato preparado o tempo é mais do que suficiente, terá condições de revisar o exame tranquilamente. Uma recomendação é não gastar mais que 1 a 2 minutos nas questões menores e no máximo 4 minutos nas maiores, cujo número de linhas de código é em torno de 40 a 50. As questões maiores não ultrapassam 20 e são as mais fáceis. Lembre-se a Sun/Oracle não define o tempo para cada questão, portanto tome cuidado com questões que você julga “fácil” e que toma muito tempo.

Dúvida sobre qual exame fazer, 5 ou 6?

Eu sempre ouvi dúvidas dos meus alunos quando ministrei cursos preparatórios para SCJP no início de 2010 sobre qual exame fazer. A dica é: Se você já vem se preparando para SCJP 5 e está com o tempo bem curto e não quer aprender o conteúdo que foi adicionado para SCJP 6, e seu inglês não é um dos melhores para esse exame, faça o exame SCJP 5. Do contrário faça a SCJP 6 por ser a mais recente.

Para SCJP 6 você precisa conhecer apenas três novas APIs: java.io.Console, java.util.NavigableSet, java.util.NavigableMap. E ter fluência suficiente para leitura em inglês para realizar a prova.

É muito importante a fluência para leitura em inglês, pois somente o inglês técnico não é suficiente para a interpretação das questões cobradas no exame. Há enunciados compostos por descrições de cenários no qual a interpretação e o conhecimento de Orientação a Objetos são imprescindíveis para respondê-la. Acostume-se a ler textos longos em inglês, caso contrário você levará mais tempo para fazer o exame.

Oracle e as mudanças

É comum ver discussões nas comunidades falando a respeito de possiveis mudanças no conteúdo das certificações, agora que a Oracle está no comando. Até o momento a mesma tem informado que as nomeclaturas realmente devem passar por modificações, mas no caso da SCJP o conteúdo será mantido. Porém, na plataforma JEE mudanças estão por vim, como podemos ver na imagem a seguir:

Uma mudança que aconteceu é na solicitação dos vouchers, na época da Sun, bastava ligar para um 0800 ou comprar pelo site naquelas promoções de ultima hora, mas agora com a Oracle é diferente. A compra é feita direto no site da Prometric com o cartão de crédito. Então aquele boleto que recebiamos via e-mail pela “mãe Sun” acabou. O valor do exame também sofreu alteração, antes custava R$ 330,00 reais, agora este varia. No site da Oracle informa $300 dólares US. Mas, ela alerta que precisa ser verificado com a Prometric, porém não deixa de informar que este valor pode variar um pouco.

A Oracle disponibilizou neste link um “Guide” sobre as certificações.

No JavaOne de 2010 que aconteceu em São Paulo, a Oracle mostrou que realmente ela tem todo interesse em manter a tecnologia Java mais viva do que nunca e apresentou as mudanças que estão por vim nas plataformas, fora que ela “parou” para ouvir a opinião da comunidade também, isso foi um dos pontos positivos.

E como estudar?

A SCJP/OCJP é um exame legal, pois o candidato não precisa gastar muito dinheiro comparado com outras certificações existentes no mercado que por menos de R$ 4 mil você não consegue tirar a mais simples. No caso da SCJP se o candidato for auto-didata, ter disciplina, objetivo e ser persistente com certeza ele será um OCJP e com um investimento financeiro menor. Há muito material hoje no mercado para estudo como livros, guias, artigos etc. E também há cursos preparatórios presenciais de qualidade. Além, do curso o candidato vai precisar de um material especifico para estudos. O livro mais recomendado é de uma das desenvolvedoras do exame a Kathy Sierra: Certificação Sun para programadores Java 5/6. Realmente o livro é fantástico com boa didática e cobre todos os objetivos. Acredito que 99% de quem passou no exame usou o livro da Kathy como referência.

Mas, eu não poderia deixar de vender meu peixe. Em maio/2010 lançei o “Guia do Exame SCJP”. Este tem como objetivo de “guia-lo” para ser um SCJP/OCJP, mostrando as possíveis “pegadinhas” existentes no exame, além de explicar os assuntos chaves através de códigos Java. Sempre recebo e-mails perguntando: O livro é válido para SCJP 6? Sim. É valido tanto para 5 ou 6, uma vez que ele foi escrito tendo como foco os assuntos chaves do exame que são Orientação a Objetos, fundamentos em Java, Threads etc. No exame real, espere por muitas questões envolvendo os assuntos citados anteriormente, o que foi adicionado na versão 6, não corresponde nem 20% das perguntas do exame.

Se o candidato não dominar Orientação a Objetos e fundamentos em Java já perdeu 50% do exame, pois a todo instante tem “pegadinhas” envolvendo estes tópicos e são as questões mais difíceis.

A seguir temos uma pequena descrição sobre o livro Guia do Exame confira:

O Guia de bolso foi escrito com o objetivo de explicar de forma objetiva, através de códigos Java, os assuntos para a certificação SCJP. Não tem como objetivo ensinar a tecnologia Java e seus derivados.

Você, leitor, vai encontrar:

• exemplo de códigos: compila, não compila, lança exceções;

•explicação dos códigos dentro de comentários Java a fim de chamar a atenção do leitor para o código;

•as nomeações das classes não seguirão as recomendações da Sun. Isso para ser mais próximo do exame real;

•uma leitura leve e descontraída.

Mais sobre o guia aqui.

Estamos disponibilizando um cupom de desconto de 30% na compra do exemplar através do site da Editora Ciência Moderna www.lcm.com.br. O livro atualmente custa R$ 49.00 + frete com o desconto fica R$ 34.30 + frete*.

Cupom de desconto: V00014.

*algumas localidades o frete é gratis, porém deve ser consultado na hora da compra no site da editora.

Vou ficando por aqui, espero que tenham gostado do post. Qualquer dúvida basta entrar em contato www.camilolopes.com.br

abracos, bons códigos. ;)

Algoritmos, Parte II – Primeiros códigos

quarta-feira, 22 de dezembro de 2010

Fala pessoal!

Idéia
Neste artigo continuaremos a série sobre Algoritmos! No primeiro artigo resolvemos 3 problemas bem simples, utilizando a idéia de pseudocódigo, onde podemos visualizar melhor os passos para a resolução de um problema e não precisamos conhecer nenhuma linguagem de programação nesta etapa.
Neste segundo artigo vamos resolver o primeiro problema apresentado anteriormente, já utilizando Java e C.

Pra você que está iniciando os estudos e não conhece muito bem a sintaxe das linguagens não se preocupe pois a idéia desta série é mostrar os passos para a resolução de um problema e vamos usar essas linguagens só para os problemas não ficarem tão vagos!
Vamos lá!

Quebrando em pequenos pedaços
Conforme havia dito no artigo anterior, podemos dividir um problema em passos para chegar na sua resolução final. A idéia de divisão de um problema em problemas menores já é antiga e facilita muito a nossa vida, pois podemos pensar na resolução de “mini-problemas”, deixando de lado a visão macro do problema. Após a resolução dos pequenos problemas, o problema maior é resolvido através da união destes.

Primeira resolução
Para o nosso primeiro código, vamos atacar o problema 1 do artigo anterior. Vamos lembrá-lo:
“Problema: Fazer a divisão de um número por outro. Se o resultado for positivo, imprimir o número encontrado pela divisão, caso seja negativo, imprimir zero. Caso o divisor seja zero, imprimir o valor -1.”

No artigo anterior também vimos a resolução deste problema através de um fluxograma e também criamos um pseudocódigo com a intenção de fazer qualquer pessoa entender o objetivo que gostaríamos de atingir, que é a resolução do problema acima.

Ambiente
Com o problema em mãos, vamos fazer o passo a passo da resolução já utilizando as duas linguagens citadas, pra que possamos visualizar o fluxo em um nível mais baixo.
Para o Java, utilizarei o Eclipse e para o C utilizarei o DevC++. Particularmente não gosto do DevC++ e uso o GCC do Ubuntu, mas o DevC++ é bem utilizado pelos que estão começando. O Eclipse talvez não seja o mais usado pelos iniciantes (o comum é usarem editores simples) , mas ele é muito conhecido. Fique à vontade para desenvolver no NetBeans, JCreator, JBuilder, etc.

Relembrando
Esqueça a sintaxe do código abaixo caso você não a entenda agora. O ponto forte aqui pra você que está começando é entender o conceito, a lógica, a idéia. Pense na situação simples: Pra você pedir um cafezinho, você segue alguns passos, como encontrar um local, chamar o garçom, escolher o café, ver o preço e pedir. E você vai fazer exatamente a mesma coisa se estiver no Brasil, Japão ou na África e só vai mudar o idioma, a “sintaxe”!
Portanto, entender os passos neste momento é muito mais útil e fundamental que entender a sintaxe, a linguagem.

Primeiro código em Java
Vamos criar o nosso primeiro código em Java. Para isso, vamos criar uma classe com o nome de “DivisaoDeNumeros“. Esta é a classe que irá conter a nossa lógica para a resolução do problema. Com a classe criada, vamos criar o método “main” para podermos executar a aplicação, ou seja, imprimir os dados.

//Classe que trata das divisões de números
public class DivisaoDeNumeros {
     public static void main(String[] args) {

  }
}

Agora com a classe e o método principal criados, vamos fazer o passo a passo do artigo anterior, porém escrevendo em código! Pra não ficar uma leitura muita cansativa e demorada fazendo cada passo, escrevi o código inteiro e comentei cada passo no próprio código.

public class DivisaoDeNumeros {

 	public static void main(String[] args) {
       //Criamos um objeto Scanner para capturar o que foi digitado
    Scanner input = new Scanner(System.in);
   		//Imprime mensagem para a inserção do primeiro valor
    System.out.println("Insira o valor do dividendo: ");
    //Guarda o valor digitado pelo usuário na variável dividendo
    int dividendo = input.nextInt();
    //Imprime mensagem para a inserção do segundo valor
    System.out.println("Insira o valor do divisor: ");
    //Guarda o valor digitado pelo usuário na variável divisor
    int divisor = input.nextInt();

    //Verifica se o valor do divisor é igual a zero
    if (divisor == 0) {
      //Imprime o valor -1 caso o divisor seja zero
      System.out.println("-1");
    }
    //Verifica se o valor do cálculo da divisão é negativo
    else if ((dividendo / divisor < 0)) {
       //Imprime o valor 0 caso o resultdo da divisão seja negativo
       System.out.println("Valor encontrado: 0");
    }
    else {
       //Como o divisor não é zero e o cálculo não é negativo, imprime o resultado da divisão
       System.out.println("Valor calculado: " + dividendo / divisor);
    }
  }
}

Você pode perceber que a execução está bem simples! Pelos comentários, podemos ver que passamos pelo “passo a passo” do artigo anterior, mas desta vez não escrevemos um pseudocódigo e sim um código em Java que podemos executar. Se você não está acostumado com a sintaxe, perceba que não foi difícil de entender o conceito, a idéia por de trás do código.

Esta é uma possível solução do problema, e não única. Podemos ter outros passos pra resolução! Mas será que se só trocarmos as condições (if’s / else if’s) teremos o mesmo resultado? Que tal tentar dar uma olhada no código abaixo e ver qual o problema?

import java.util.Scanner;

public class DivisaoDeNumeros {

   public static void main(String[] args) {
      //Criamos um objeto Scanner para capturar o que foi digitado
      Scanner input = new Scanner(System.in);
      //Imprime mensagem para a inserção do primeiro valor
      System.out.println("Insira o valor do dividendo: ");
      //Guarda o valor digitado pelo usuário na variável dividendo
      int dividendo = input.nextInt();
      //Imprime mensagem para a inserção do segundo valor
      System.out.println("Insira o valor do divisor: ");
      //Guarda o valor digitado pelo usuário na variável divisor
      int divisor = input.nextInt();

     		//Verifica se o valor do cálculo da divisão é negativo
      if ((dividendo / divisor < 0)) {
         //Imprime o valor 0 caso o resultdo da divisão seja negativo 
         System.out.println("Valor encontrado: 0");
      }
      //Verifica se o cálculo é positivo
      else if (dividendo / divisor > 0) {
         //Imprime o resultado do cálculo caso o resultado seja positivo
         System.out.println("Valor calculado: " + dividendo / divisor);
      }
      //Como o resultado não é positivo e nem negativo, podemos supor que o divisor é zero
      else {
         //Imprime o valor -1 pois o divisor é zero
         System.out.println("-1");
      }
   }
}

Erro! Veja como não precisamos entender a linguagem/sintaxe pra saber que este código terá problemas. Se olharmos com mais “carinho” vamos perceber que o código, na primeira condição, já tenta calcular a expressão. Se você inserir o valor zero para o divisor, teremos um erro no caso do Java que é o “java.lang.ArithmeticException: / by zero”, ou seja, não existe divisão por zero matematicamente falando e claro que na execução o Java vai reclamar.

Perceba que na resolução não basta simplesmente trocarmos as condições. Os passos para a resolução de um problema devem ser bem definidos e bem pensados para que nenhuma regra seja violada.

Código em C
Abaixo temos o código em C, que é muito usado nos cursos de introdução à computação.

#include<stdio.h>
#include<stdlib.h>

int main() {
   //Declaração das variáveis para guardar os valores
   int dividendo;
   int divisor;

   //Imprime mensagem para a inserção do primeiro valor
   printf("Digite o valor do dividendo:");
   //Guarda o valor digitado pelo usuário na variável dividendo
   scanf("%d", &dividendo);

   //Imprime mensagem para a inserção do segundo valor
   printf("\nDigite o valor do divisor:");
   //Guarda o valor digitado pelo usuário na variável divisor
   scanf("%d", &divisor);   

   //Verifica se o valor do divisor é igual a zero
   if (divisor == 0) {
      //Imprime o valor -1 caso o divisor seja zero
      printf("-1\n");
   }
   //Verifica se o valor do cálculo da divisão é negativo
   else if ((dividendo / divisor < 0)) {
      //Imprime o valor 0 caso o resultdo da divisão seja negativo
      printf("Valor encontrado: 0\n");
   }
   else {
      //Como o divisor não é zero e o cálculo não é negativo, imprime o resultado da divisão
      printf("Valor calculado: %d \n", (dividendo / divisor));
   }
   //Pausa a execução
   system("PAUSE");
}

Entendimento do conceito x Sintaxe da linguagem
Volto a lembrar que não foi preciso entender 100% a sintaxe para entender o que está acontecendo. Nos comentários do código vimos o “passo a passo” para a resolução do algoritmos e basicamente traduzimos logo em seguida para a sintaxe utilizada no Java e no C.
Devemos lembrar também que não existe somente um passo para a resolução do problema e você pode ficar à vontade pra modificar os códigos acima, criando outros passos!

Finalizando
Neste artigo vimos a resolução de um problema usando Java e C e a idéia principal é entender o conceito! Entendido o problema e os passos para a resolução dele, traduzí-lo para a linguagem é o “mais fácil”. Podemos entender muito de uma linguagem, mas se não conseguirmos resolver um problema com passos bem definidos, não conseguimos fazer nada.

Nos próximos artigos desta série vamos resolver alguns problemas mais complicados (este foi bem simples, apenas para a introdução) e em breve vou falar sobre assuntos mais específicos, como Pilhas, Filas, Tempo de Algoritmo, etc.

Estes códigos você também pode encontrar em:
Código em Java
Código em C

Abraços!!!

Maven na prática Parte I – Introdução

terça-feira, 7 de dezembro de 2010

Objetivos

Neste primeiro guia sobre Maven nós vamos aprender o que é o Maven, como instalar, e criar um projeto simples a partir de um modelo usando o plugin Archetype.

Introdução

O Maven for desenvolvido com o propósito de simplificar o processo de build do projeto Jakarta Turbine. Este projeto continha vários projetos menores, cada uma com o seu próprio arquivo Ant para build. Entre os objetivos pricipais, podemos citar: criar um padrão para compilação dos projetos, permitir o compartilhamento das JARs entre os projetos dependetes, e publicar as informações de cada projeto de uma maneira simplificada.

Como resultado desta necessidade o Maven é hoje uma das principais ferramentas para building e gerenciamento de projetos Java.

Alguns dos principais objetivos do Maven são:

  • simplificar o processo de build;
  • disponibilizar um sistema de build uniforme;
  • padronizar o fornecimento de informações do projeto;
  • criação de diretrizes para o desenvolvimento de boas práticas;
  • permitir a migração transparente de novas funcionalidades.

Instalação

Antes de começar a acompanhar este tutorial, certifique-se de que o java está devidamente instalado em seu sistema e suas variáveis de ambiente definidas corretamente. Um bom tutorial sobre como instalar o java no Windows pode ser encontrado aqui.

No Ubuntu

Para instalar o Maven no ubuntu você precisa apenas rodar o seguinte comando (com direitos administrativos):

~/> sudo apt-get install maven2

No Windows

Se você utiliza o Windows, basta fazer o download na página oficial do Apache Maven. Não é necessária a instalação, apenas extraia o pacote em uma pasta conhecida e adicione o diretório que contém o binario na variável de ambiente Path do Windows.

Verificando a Instalação

Antes de prosseguir com o tutorial, verifique se o processo de instalação foi concluído com sucesso, para isto insira no terminal (tanto no Windows quanto no linux) o seguinte comando:

prompt> mvn --version

Teste de instalação

Como resultado do comando você verá a versão do Maven que você instalou entre outras informações sobre a versão do java que está instalada no seu computador e a versão do sistema operacional.

Primeiro projeto

Antes de entrar em detalhes sobre o funcionamento do Maven, vamos criar um projeto simples sem saber muito como funcionou e em seguida entender como as coisas foram feitas. O comando a seguir vai criar um projeto com um código bem simples incluso apenas com o propósito de teste / aprendizado.

No console, entre com o seguinte comando:

prompt> mvn archetype:generate -DgroupId=br.com.k19.maven2 -DartifactId=hello-world
             -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false

Executando o comando

Não se assuste com tantos parâmetros, vamos detalhá-los mais a frente.

IMPORTANTE: Se você acabou de instalar o Maven, ele fará alguns downloads necessários para que o nosso comando funcione. Isto acontece porque o Maven não vem completo, até porque ele é bastante grande e quase sempre não vamos utilizar boa parte de suas funcionalidades, por isso ele as carrega sob demanda. Pode acontecer que alguns dos repositórios estejam fora do ar, o que significa que você pode precisar rodar o comando mais de uma vez.

Para saber se o comando funcionou como esperado, procure no console ao final da saída a linha: BUILD SUCCESSFUL. Uma outra maneira, menos trabalhosa, para fazer esta verificação é ver que o Maven criou uma pasta no diretório corrente chamada hello-world.


Mas o que este comando fez?

O primeiro parâmetro do comando indica que vamos utilizar o plugin chamado archetype. Este plugin permite que o usuário crie um projeto Maven a partir de um modelo pré-programado. Em seguida definimos o que é chamado de goal. O archetype possui 4 opções goals:

  • archetype:create – (deprecated) cria um projeto Maven a partir de um modelo. Compatível com a versão 1.0-alpha-7 do Archetype Plugin.
  • archetype:generate – (que nós acabamos de utilizar) cria um projeto Maven a partir de um modelo, guiando o usuário através de um wizard que fará as configurações necessárias.
  • archetype:create-from-project – cria um archetype a partir de um projeto existente.
  • archetype:crawl – busca no repositório por archetypes e atualiza o catálogo.

Obs.: Por hora podemos definir os plugins (como o archetype) como conjuntos de goals (como o generate) desenvolvidos para um propósito geral comum.

O segundo parâmetro, groupId, define unicamente a organização ou o projeto. Não necessariamente é a estrutura de pacotes do projeto, mas é uma boa prática definí-lo assim. Obs.: Você pode perceber que parâmetros que definem valores de propriedades são precedidos de -D.

No terceiro parâmetro, artifactId, especificamos o nome pelo qual o projeto será chamado, que no nosso caso é: hello-world.

O quarto parâmetro, archetypeArtifactId, definimos qual modelo será utilizado como base para a construção do nosso projeto. O modelo que estamos utilizando é: maven-archetype-quickstart. Este é um modelo para a criação de uma aplicação java simples.

Alguns outros modelos:

  • appfuse-basic-jsf – AppFuse archetype para a criação de uma aplicação web com Hibernate, Spring e JSF.
  • maven-archetype-j2ee-simple – Uma aplicação simples J2EE.
  • jpa-maven-archetype – Aplicação JPA.
  • struts2-archetype-starter – Struts 2 Archetype.

Existe um Guia de Referência onde podemos encontrar uma lista grande de outros modelos que podemos usar para diferentes tipos de projetos.

O último parâmetro, interactiveMode apenas define se o usuário irá entrar com informações extra durante a construção do projeto.

Os parâmetros de um comando do Maven podem variar muito dependendo do plugin que está sendo utilizado, no nosso caso utilizamos o plugin archetype. Existem inúmeros outros plugins disponíveis e para cada um parâmetros diferentes podem ser utilizados. Aqui existe uma lista de alguns plugins desenvolvidos para o Maven.

Se a execução do comando obteve êxito o Maven criou uma estrutura de diretório que será o esqueleto do projeto. Esta estrutura deve ser mantida de modo que o Maven consiga encontrar os arquivos sem que seja preciso especificar o local exato. Esta prática é conhecida como convention over configuration.

hello-world
|-- pom.xml
`-- src
    |-- main
    |   `-- java
    |       `-- br
    |       	`-- com
    |               `-- k19
    |                   `-- maven2
    |                       `-- App.java
    `-- test
        `-- java
            `-- br
            	`-- com
                    `-- k19
                    	`-- maven2
                            `-- AppTest.java

Neste ponto, o esqueleto do nosso projeto está construído, e agora já poderíamos inserir o código da nossa aplicação. Mas onde? Dentro do diretório principal da aplicação vamos encontrar um arquivo muito importante do Maven chamado pom.xml (que será explicado com detalhes nos próximos artigos) e uma pasta chamada src. Entrando nela existe uma outra pasta chamada main. É esta pasta que vai conter os pacotes e arquivos .java do nosso projeto. Observe que já existe uma estrutura de pastas (pacotes) br.com.k19.maven2 contendo um arquivo chamado App.java. Este arquivo define uma classe que acompanha o modelo e quando executada apenas imprime no console a saudação padrão: Hello World!.

Não vamos adicionar, por enquanto, mais código ao projeto, o que vamos fazer agora é compilar e empacotar a nossa aplicação. Entre na pasta principal do projeto (hello-world) e execute o seguinte comando:

prompt> mvn package


Mais uma vez, alguns downloads podem ser feitos pelo Maven neste momento, se é a primeira vez que voce está rodando o comando. Se tudo correu bem você vai ver na saída a mensagem: BUILD SUCCESSFUL.


O que o comando fez desta vez?

Diferentemente do primeiro comando que rodamos (archetype:generate), o comando agora é bem simples, package. Este comando, ao contrário do primeiro, não é um goal, mas sim o que vamos chamar de fase. Fase é uma parte do ciclo de build do projeto. O ciclo de build é um conjunto de fases ordenadas. Quando uma phase é dada, o Maven irá executar uma sequência de fases até chegar à fase que fornecemos. Exemplo: se executarmos a fase compile, as fases que serão executadas são:

  • validate
  • generate-sources
  • process-sources
  • generate-resources
  • process-resources
  • compile

Note que a fase compile também foi inclusa no processo.

Será que funciona?

Neste ponto nosso projeto foi compilado e empacotado pelo comando package. Só o que precisamos agora é executá-lo. Para executar esta aplicação é preciso indicar para a máquina virtual o nome da classe que contém o método main e onde ela está. Entre na pasta principal do projeto (hello-world) e execute o comando a seguir:

java -cp target/hello-world-1.0-SNAPSHOT.jar br.com.k19.maven2.App


Você deve ver impresso no terminal a famosa frase: Hello World!

Pronto! Com o que aprendemos já é possível criar aplicações java simples usando o Maven. É claro que existe muito mais para se falar sobre o Maven, e nos próximos artigos da série vou explorar mais a fundo estes conceitos.

WebService Restful utilizando JSON

sábado, 4 de dezembro de 2010

Este artigo é uma continuação direta do artigo sobre Jersey e JAX-RS. Se você ainda não viu, é bom dar uma olhada para conseguir acompanhar este artigo:

Anteriormente mostramos como criar um WebService seguindo a arquitetura REST utilizando a especificação JAX-RS. Mas apenas mostramos algumas das funcionalidades possíveis. Por exemplo, utilizamos somente XML como formato do conteúdo, tanto das requests quanto responses. Neste artigo, vamos mostrar como utilizar o formato JSON.

O que é JSON?

JSON (JavaScript Object Notation) é um padrão para formato de dados bem simples, derivado da sintaxe de objetos em Javascript. E apesar de estar diretamente relacionado à JavaScript, ele é um padrão com vários parsers em diferentes linguagens, podendo servir para diferentes propósitos. O principal uso atualmente do JSON é ser uma alternativa ao XML na transmissão de dados entre cliente e servidor,  que foi popularizado com o uso de AJAX.

Leia mais »

Relatórios em Java – JasperReports e iReport

sábado, 20 de novembro de 2010

Introdução

O JasperReports é um framework para a geração de relatórios. É uma ferramenta totalmente open source e gratuita, e a mais utilizada com esse propósito atualmente. Entre as funcionalidades do JasperReports podemos destacar:

  • é capaz de exportar relatórios para diversos formatos diferentes, tais como PDF, HTML, XML, XLS, etc.
  • aceita diversas formas de entrada de dados, tais como um arquivo XML ou CSV, conexão com o banco de dados, uma sessão do Hibernate, uma coleção de objetos em memória, etc.
  • permite o uso de diagramas, gráficos, e até códigos de barras.

Como o JasperReports funciona?

Um aspecto importante do JasperReports é que o layout do relatório é definido em um arquivo XML, geralmente com a extensão .jrxml. Este XML possui todas as informações de formatação do relatório, e além disso, possui os campos que serão preenchidos posteriormente, de acordo com a fonte de dados utilizada (data source). Como dito anteriormente, a fonte de dados pode variar, e ser uma tabela em uma base de dados, ou ser um arquivo CSV, porém a formatação do relatório será a mesma em ambos os casos.

Os passos para gerar um relatório são bem simples. O primeiro passo é compilar o relatório em XML. Depois da compilação, o resultado é um objeto do tipo JasperReport. O próximo passo é preencher o relatório com os dados, e o resultado dessa etapa fica armazenado em um objeto do tipo JasperPrint. Esse objeto já representa o relatório finalizado, a partir dele podemos enviar para impressão diretamente, ou podemos exportar para um outro formato, tal como PDF por exemplo. Veja um diagrama ilustrando o processo completo:

Leia mais »

Criando um WebService Restful em Java

sexta-feira, 12 de novembro de 2010

Utilizar um WebService é uma das maneiras mais comuns de se integrar aplicações diferentes. Existem diferentes tipos de arquiteturas para web services, e o RESTful é mais simples em comparação aos outros web services, que geralmente utilizam o SOAP.

Dada essa simplicidade, isso faz com que a arquitetura RESTful seja uma escolha popular principalmente para serviços abertos ao público. Por exemplo, o Twitter possui uma API Restful. Além do Twitter, o Flickr também possui uma API que segue os princípios da arquitetura REST. De certa forma é uma tendência que os serviços conhecidos como a “Web 2.0″ disponibilizem uma API (geralmente REST),  pois é cada vez maior a necessidade que esses serviços sejam integrados com diversos tipos aplicações.

Características de um web service RESTful

Este post não pretende explicar a fundo o que é REST, ou explicar todos os príncipios da arquitetura, pretende apenas mostrar uma introdução de como desenvolver o web service. Para quem quiser estudar mais a fundo a definição da arquitetura, existe disponível a própria tese do Roy Fielding sobre o tema. O artigo sobre REST na Wikipedia também é uma boa referência. Porém, para uma breve introdução como a que será mostrada aqui, não é necessário conhecer todos os termos e princípios.

O que é importante ter em mente é que o principal em um restful web service são as URLs do sistema (geralmente são referidas como restful url’s), e os resources. Um resource é um recurso, uma entidade, ou seja, é um objeto com informação que será representado por meio de um XML. Em geral, a URL para acessar esse recurso será sempre a mesma, porém caso mudemos o método HTTP (GET, POST, PUT, DELETE) o resultado da requisição será diferente. Veja os exemplos tabela abaixo:

Método exemplo.com/recurso exemplo.com/recurso/1
GET lista os recursos detalhes de um recurso
POST adiciona um recurso -
PUT - atualiza um recurso
DELETE - remove um recurso

Porém saiba que no REST não existe um padrão definido, as operações listadas acima são apenas uma sugestão. Ao desenvolver um web service você não é obrigado a implementar todas as operações para seguir um determinado padrão, você só precisa implementar o que é necessário no seu contexto. Por exemplo, eu posso decidir que os recursos não podem ser apagados e não implementar nenhuma operação para o método DELETE. O que deve ser levado em consideração é a convenção das ações. GET deve ser usado para “leitura”, por exemplo listar os detalhes de um recurso. POST deve ser usado para adicionar novos recursos. PUT deve ser utilizado para alterar recursos já existentes. E DELETE para apagar recursos.

JAX-RS e Jersey

O JAX-RS é uma especificação (a JSR-311) que define a criação de um WebService com arquitetura RESTful. Na sua API, são utilizadas anotações, que simplificam a necessidade extra de configurações. Atualmente, o JAX-RS é parte integrante do Java EE.

Como o JAX-RS é apenas uma especificação, é necessário escolher uma implementação. Entre os projetos que o implementam, temos o Jersey, que é open source e mantido pela Oracle, e que é a
implementação de referência do JAX-RS.

Configurando o ambiente

O Jersey deve ser baixado no seu site oficial. Atualmente está na versão 1.4. Haverá duas opções, uma é um arquivo zip com todas as dependências e documentação inclusas.
A outra é o jersey-bundle, um jar que já inclui todas as dependências necessárias. Neste exemplo, vamos utilizar o zip mesmo. Haverão quatro jars que devem ser adicionados ao projeto:

  • asm.jar
  • jersey-core
  • jersey-server
  • jsr311-api

Estes são os jars obrigatórios em qualquer projeto utilizando o Jersey. Claro que se você quiser mais funcionalidades, como o suporte a JSON terá que adicionar mais jars, como o jersey-json, por exemplo.

No caso do JAX-RS, para rodar o nosso web service RESTful é necessário um Web Container. No exemplo irei utilizar o Tomcat, porém qualquer outro WebContainer como o Jetty, ou
mesmo um servidor de aplicação Java EE como o Glassfish ou o JBoss, que já possuem um WebContainer, funcionariam do mesmo jeito. Para começar, devemos criar um projeto do tipo Dynamic Web Project no Eclipse.

criando o projeto java

Em seguida, dê um nome ao projeto e selecione o WebContainer (target runtime). Escolhi como nome jersey-tutorial e o Tomcat, como disse anteriormente.

escolhendo o Tomcat

Copie as jars anteriormente para a pasta WebContent/WEB-INF/lib, e pronto, já podemos começar a escrever um pouco de código.

Criando o WebService

Primeiro vamos fazer o famigerado “Hello World” apenas para testar se o ambiente está configurado corretamente. Veja a classe abaixo:

package com.k19.restful.resources;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;

@Path("/helloworld")
public class HelloWorldResource {
	@GET
	@Produces("text/plain")
	public String showHelloWorld() {
		return "Olá mundo!";
	}
}

Antes de rodar o exemplo, devemos configurar o web.xml e cadastrar a servlet do Jersey. Preste atenção que devemos passar um parâmetro na inicialização. Esse parâmetro corresponde ao pacote onde estão os nossos resources. Basta seguir o exemplo conforme abaixo:

<?xml version="1.0" encoding="UTF-8"?>
<web-app>
  <display-name>jersey-tutorial</display-name>
  <servlet>
    <servlet-name>Jersey REST Service</servlet-name>
    <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
    <init-param>
      <param-name>com.sun.jersey.config.property.packages</param-name>
      <param-value>com.k19.restful.resources</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>Jersey REST Service</servlet-name>
    <url-pattern>/*</url-pattern>
  </servlet-mapping>
</web-app>

Ao tentar rodar o exemplo pela primeira vez, possivelmente o Eclipse mostrará uma caixa de diálogo para escolher qual servidor utilizar. Lembre-se que você já deve ter o Tomcat instalado e configurado no Eclipse para que ele apareça como uma das opções. Bem, após clicar no botão de executar, caso não tenha aparecido nenhuma exception, podemos testar acessando http://localhost:8080/jersey-tutorial/helloworld na barra de endereços do navegador. Altere a URL caso você tenha dado um nome diferente para a aplicação, ou tenha configurado o Tomcat em outra porta. Se tudo estiver certo, você deve ver a mensagem “Olá mundo!”. Nada muito complicado, mas já é o suficiente para saber que está funcionando.

Anotações

Pelo nosso exemplo anterior, já vimos o Jersey em ação e a única coisa que nós fizemos foi adicionar algumas anotações à nossa classe. O Jersey é todo baseado em anotações, e existem várias delas. Vamos listar as mais importantes.

  • @Path – essa anotação recebe uma string como parâmentro e indica qual é o path da URL. No exemplo anterior, tivemos a classe anotada com o valor ”/helloworld”, e por isso que acessamos a URL como http://localhost:8080/jersey-tutorial/helloworld.
  • @GET – anotação que indica qual o método correspondente do HTTP. Como dito anteriormente, podemos ter a mesma URL para ações diferentes desde que o método HTTP também seja diferente. Da mesma forma, temos as anotações @POST, @PUT e @DELETE.
  • @Produces – anotação que indica qual o mime-type do conteúdo da resposta que será enviada para o cliente. No exemplo acima, foi “text/plain” para indicar que é texto puro. Em um web service isso é pouco usual, em geral vamos utilizar valores como “text/xml” para devolver XML.
  • @Consumes – anotação que indica qual o mime-type do conteúdo da requisição. Em geral é utilizado principalmente em requisições do tipo POST ou PUT, em que o cliente precisa enviar a informação do que ele deseja adicionar/alterar. Do mesmo jeito que o web service “devolve” XML, ele pode “consumir” (receber) conteúdo XML.

Exemplo de CRUD

Agora vamos fazer um exemplo bem simples de CRUD. Primeiro vamos precisar de uma entidade, um bean para conter as informações que nós queremos manipular. Veja o exemplo abaixo:

package br.com.k19.models;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Banda {

	private String nome;
	private int anoDeFormacao;
	private int id;

	// getters e setters
}

Note a presença da anotação @XmlRootElement na definição da nossa classe. Ela é fundamental para que o Jersey conheça a representação do objeto banda em XML. Desse modo os atributos irão se tornar nós no momento em que o XML for enviado ao cliente. E do mesmo jeito, quando chegar um XML no corpo de uma requisição, o Jersey vai saber converter esse XML em um objeto do tipo Banda.

O próximo passo é criar o nosso WebResource. No mundo real, geralmente você vai ter uma tabela “Banda” em alguma base de dados e vai desejar buscar a informação quando for requisitado. Aqui para que o exemplo fique mais simples e a gente mantenha o foco apenas na funcionalidade do Jersey, vamos utilizar um Map para simular a nossa base de dados. Veja o exemplo abaixo:

package br.com.k19.resources;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;

import br.com.k19.models.Banda;

@Path("/bandas")
public class BandaResource {

	// vamos utilizar um Map estático para
	// "simular" uma base de dados
	static private Map<Integer, Banda> bandasMap;

	static {
		bandasMap = new HashMap<Integer, Banda>();

		Banda b1 = new Banda();
		b1.setId(1);
		b1.setNome("Led Zeppelin");
		b1.setAnoDeFormacao(1968);

		bandasMap.put(b1.getId(), b1);

		Banda b2 = new Banda();
		b2.setId(2);
		b2.setNome("AC/DC");
		b2.setAnoDeFormacao(1973);

		bandasMap.put(b2.getId(), b2);
	}

	@GET
	@Produces("text/xml")
	public List<Banda> getBandas() {
		return new ArrayList<Banda>(bandasMap.values());
	}
	// continua depois ...

Para testar, basta acessar a url http://localhost:8080/jersey-tutorial/bandas em qualquer navegador, que o resultado será um XML parecido com esse:

<bandas>
    <banda>
        <anoDeFormacao>1968</anoDeFormacao>
        <id>1</id>
        <nome>Led Zeppelin</nome>
       </banda>
    <banda>
        <anoDeFormacaov1973</anoDeFormacao>
        <id>2</id>
        <nome>AC/DC</nome>
    </banda>
</bandas>

E caso queiramos listar apenas uma banda em vez de todas? Também podemos incluir a anotação @Path nos métodos igual ao exemplo abaixo:

@Path("{id}")
@GET
@Produces("text/xml")
public Banda getBanda(@PathParam("id") int id) {
	return bandasMap.get(id);
}

Nesse caso, a url para acessar o recurso passa a ser http://localhost:8080/jersey-tutorial/bandas/{id}. As chaves indicam que id é um parâmetro, assim podemos passar diferentes valores para acessar diferentes recursos. Note também o uso da anotação @PathParam no parâmetro id, que serve para indicar que o parâmetro do método se refere ao parâmetro no path. Como teste, podemos acessar http://localhost:8080/jersey-tutorial/bandas/1 e ver algo parecido com o XML abaixo:

<banda>
    <anoDeFormacao>1968</anoDeFormacao>
    <id>1</id>
    <nome>Led Zeppelin</nome>
</banda>

Agora que conseguimos listar as bandas, precisamos também de uma maneira de adicioná-las. Veja o exemplo abaixo:

@POST
@Consumes("text/xml")
@Produces("text/plain")
public String adicionaBanda(Banda banda) {
	banda.setId(bandasMap.size() + 1);
	bandasMap.put(banda.getId(), banda);
	return banda.getNome() + " adicionado.";
}

Temos uma mudança de método do HTTP, de GET passou para POST. Fora essa mudança, a URL é a mesma de quando listávamos todas as bandas, ou seja, http://localhost:8080/jersey-tutorial/bandas. E agora também recebemos (ou consumimos) um XML que vai representar a banda. E se você reparar bem, também vê que o nosso método recebe uma banda como parâmetro.
É isso mesmo que você está pensando, o objeto banda é instanciado pelo Jersey e será preenchido com os valores do XML que vierem no conteúdo da requisição. O problema é que agora não temos como testar usando simplesmente o navegador, porque o padrão é que ele execute as requisições como GET, e não teríamos como enviar o XML contendo as informações da nova banda. Para quem
usa Firefox, uma opção é utilizar o add-on Poster, que permite customizar a requisição de várias maneiras, alterando headers, adicionando conteúdo, etc. Outra opção para quem usa linux, é usar o
comando curl. Veja um exemplo para adicionar uma banda:

$ curl -X POST -H "Content-type:text/xml" \
    -d "<banda><nome>Teste</nome><anoDeFormacao>2010</anoDeFormacao></banda>" \

http://localhost:8080/jersey-tutorial/bandas

O parâmetro -X serve para alterar o método HTTP. O -H serve para alterar o cabeçalho da requisição. Nesse caso precisamos alterar para informar que estamos enviando um XML. O parâmetro -d são os dados que serão enviados no conteúdo da requisição. E por fim passamos a URL.

Abaixo temos o restante do exemplo de CRUD, com as operações para atualizar e remover bandas. O exemplo com PUT é bem semelhante ao de adicionar uma nova banda, a diferença é que devemos atualizar uma banda já existente. Já o exemplo do DELETE é ainda mais simples, pois não precisamos consumir nenhum XML, apenas identificamos o id pela URL e excluímos a banda correspondente.

@Path("{id}")
@PUT
@Consumes("text/xml")
@Produces("text/plain")
public String atualizaBanda(Banda banda, @PathParam("id") int id) {
	Banda atual = bandasMap.get(id);
	atual.setNome(banda.getNome());
	atual.setAnoDeFormacao(banda.getAnoDeFormacao());
	return banda.getNome() + " atualizada.";
}

@Path("{id}")
@DELETE
@Produces("text/plain")
public String removeBanda(@PathParam("id") int id) {
	bandasMap.remove(id);
	return "Banda removida.";
}

Concluindo

Esta foi uma rápida introdução ao JAX-RS e ao Jersey, apenas para servir de ponto de partida. Existem muito mais detalhes na documentação oficial.
Em breve teremos mais exemplos, mostrando como utilizar JSON e como desenvolver um Cliente em Java utilizando as classes do Jersey.

Download do código: jersey-tutorial.zip