Você está na página 1de 53

TREINAMENTOS

Integrao de Sistemas com Webservices, JMS e EJB

Integrao de Sistemas com Webservices, JMS e EJB

20 de maio de 2011

www.k19.com.br

ii

Sumrio
1 JMS 1.1 1.2 1.3 1.4 1.5 1.6 1 1 1 2 4 5 6 6 6 6 7 7 7 7 16 16 16 17 17 18 18 20 21 22 22 23 23 24 25 27 28 28 32 32 33

1.7 1.8 1.9 1.10 1.11 1.12 1.13 1.14 1.15 1.16 1.17 1.18 2

Middleware Orientado a Mensagens - MOM Destinos: Filas e Tpicos . . . . . . . . . . Exerccios . . . . . . . . . . . . . . . . . . Fbricas de Conexes . . . . . . . . . . . . Exerccios . . . . . . . . . . . . . . . . . . Viso Geral . . . . . . . . . . . . . . . . . 1.6.1 Obtendo as fbricas e os destinos . 1.6.2 Criando Conexes e Sesses . . . . 1.6.3 Criando Emissores e Receptores . . 1.6.4 Criando Mensagens . . . . . . . . . 1.6.5 Enviando Mensagens . . . . . . . . 1.6.6 Recebendo Mensagens . . . . . . . Exerccios . . . . . . . . . . . . . . . . . . Modos de recebimento . . . . . . . . . . . Percorrendo uma la . . . . . . . . . . . . Exerccios . . . . . . . . . . . . . . . . . . Selecionando mensagens de um tpico . . . Exerccios . . . . . . . . . . . . . . . . . . Tpicos Durveis . . . . . . . . . . . . . . Exerccios . . . . . . . . . . . . . . . . . . JMS e EJB . . . . . . . . . . . . . . . . . . Exerccios . . . . . . . . . . . . . . . . . . Projeto - Rede de Hotis . . . . . . . . . . Exerccios . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . .

JAX-WS 2.1 Web Services . . . . . . . . . . . . . . . . 2.2 JAXB . . . . . . . . . . . . . . . . . . . . 2.3 Exerccios . . . . . . . . . . . . . . . . . . 2.4 Criando um web service - Java SE . . . . . 2.5 Consumindo um web service com JAX-WS 2.6 Exerccios . . . . . . . . . . . . . . . . . . 2.7 JAX-WS e EJB . . . . . . . . . . . . . . . 2.8 Exerccios . . . . . . . . . . . . . . . . . . 2.9 Projeto - Txi no Aeroporto . . . . . . . . . iii

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

SUMRIO

SUMRIO

2.10 Exerccios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34 3 JAX-RS 3.1 REST vs Padres W3C . . . . . . . . . . . 3.2 Resources, URIs, Media Types e Operaes 3.3 Web service com JAX-RS . . . . . . . . . . 3.4 Resources . . . . . . . . . . . . . . . . . . 3.5 Subresource . . . . . . . . . . . . . . . . . 3.6 Exerccios . . . . . . . . . . . . . . . . . . 3.7 Parmetros . . . . . . . . . . . . . . . . . 3.7.1 PathParam . . . . . . . . . . . . . 3.7.2 MatrixParam . . . . . . . . . . . . 3.7.3 QueryParam . . . . . . . . . . . . 3.7.4 FormParam . . . . . . . . . . . . . 3.7.5 HeaderParam . . . . . . . . . . . . 3.7.6 CookieParam . . . . . . . . . . . . 3.8 Exerccios . . . . . . . . . . . . . . . . . . 3.9 Produzindo XML ou JSON . . . . . . . . . 3.10 Consumindo XML ou JSON . . . . . . . . 3.11 Exerccios . . . . . . . . . . . . . . . . . . 3.12 Implementando um Cliente . . . . . . . . . 3.13 Exerccios . . . . . . . . . . . . . . . . . . 3.14 Projeto . . . . . . . . . . . . . . . . . . . . 35 35 35 36 36 37 37 39 39 40 40 41 41 41 41 42 43 43 46 46 47

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . .

www.k19.com.br

iv

Captulo 1 JMS
1.1 Middleware Orientado a Mensagens - MOM

Geralmente, em ambientes corporativos, existem diversos sistemas para implementar as inmeras regras de negcio da empresa. comum dividir esses sistemas por departamentos ou por regies geogrcas. Muito provavelmente, em algum momento, os diversos sistema de uma empresa devem trocar informaes ou requisitar procedimentos entre si. Essa integrao pode ser realizada atravs de interveno humana. Contudo, quando o volume de comunicao entres os sistemas muito grande, essa abordagem se torna invivel. Da surge a necessidade de automatizar a integrao entres sistemas. A abordagem mais simples para implementar essa automatizao utilizar arquivos de texto contendo os dados que devem ser transmitidos de um sistema para outro. Normalmente, um sistema compartilhado de arquivos utilizado para essa transmisso. Essa estratgia possui certas limitaes principalmente em relao a integridade das informaes armazenadas nos arquivos. Uma abordagem mais robusta para implementar essa integrao utilizar um Middleware Orientado a Mensagens (MOM). Um Middleware Orientado a Mensagens permite que um sistema receba ou envie mensagens para outros sistemas de forma assncrona. Alm disso, o sistema que envia uma mensagem no precisa conhecer os sistemas que a recebero. Da mesma forma, que os sistemas que recebem uma mensagem no precisam conhecer o sistema que a enviou. Essas caractersticas permitem que os sistemas sejam integrados com baixo acoplamento. A plataforma Java dene o funcionamento de um Middleware Orientado a Mensagens atravs da especicao Java Message Service - JMS. Todo servidor de aplicao que segue a especicao Java EE deve oferecer uma implementao do MOM denido pela JMS. Especicaes importantes da plataforma Java como Enterprise Java Beans (EJB), Java Transaction API (JTA) e Java Transaction Service (JTS) possuem um relacionamento forte com a especicao JMS. A seguir veremos a arquitetura do MOM denido pela JMS.

1.2

Destinos: Filas e Tpicos

Na arquitetura JMS, os sistemas que devem ser integrados podem enviar mensagens para las(queues) ou tpicos(topics) cadastrados anteriormente no MOM. Na terminologia JMS, 1

JMS as las e os tpicos so chamados de destinos(destinations). Uma mensagem enviada para uma la pode ser recebida por apenas um sistema (pointto-point). Uma mensagem enviada para um tpico pode ser recebida por diversos sistemas (publish-and-subscribe). As las e os tpicos so objetos criados pelos administradores do MOM. A especicao JMS no dene uma forma padro de criao desses objetos. Dessa maneira, cada implementao JMS possui os seus prprios procedimentos para esse processo. No caso do Glasssh, as las e os tpicos podem ser criados atravs da interface web de administrao do servidor. Toda la ou tpico possui um nome nico no MOM.

1.3

Exerccios

1. Na rea de Trabalho, entre na pasta K19-Arquivos e copie glasssh-3.0.1-with-hibernate.zip para o seu Desktop. Descompacte este arquivo na prpria rea de Trabalho.

2. Ainda na rea de Trabalho, entre na pasta glassshv3/glasssh/bin e execute o script startserv para executar o glasssh.

3. Verique se o glasssh est executando atravs de um navegador acessando a url: http: //localhost:8080.

4. Pare o glasssh executando o script stopserv que est na mesma pasta do script startserv.

5. No eclipse, abra a view servers e clique com o boto direito no corpo dela. Escolha a opo new e congure o glasssh.

6. Execute o glasssh pela view servers e verique se ele est funcionando atravs de um navegador a url: http://localhost:8080.

7. Crie uma la atravs da interface de administrao do Glasssh seguindo exatamente os passos das imagens abaixo: www.k19.com.br 2

JMS

8. Crie um tpico atravs da interface de administrao do Glasssh seguindo exatamente os passos das imagens abaixo: 3 K19 Treinamentos

JMS

1.4

Fbricas de Conexes

Os sistemas que desejam trocar mensagens atravs de las ou tpicos devem obter conexes JMS atravs das fbricas cadastradas no MOM. Assim como as las e os tpicos, as fbricas de conexes JMS so objetos criados pelos administradores do MOM. A especicao JMS no dene uma forma padro para criar essas fbricas, ento cada implementao dene a sua prpria forma de criao. No Glasssh as fbricas podem ser criadas atravs da interface web de administrao do servidor. possvel criar fbricas especicadas para las ou para tpicos ou genricas que www.k19.com.br 4

JMS podem ser utilizadas para os dois tipos de destino. Toda fbrica possui um nome nico no MOM.

1.5

Exerccios

9. Crie uma fbrica de conexes JMS atravs da interface de administrao do Glasssh seguindo exatamente os passos das imagens abaixo:

K19 Treinamentos

JMS

1.6

Viso Geral

Inicialmente, sem se ater a detalhes, vamos mostrar os passos necessrios para enviar ou receber mensagens atravs da arquitetura JMS.

1.6.1

Obtendo as fbricas e os destinos

As las, tpicos e fbricas so objetos criados pelos administradores do MOM. Quando uma aplicao deseja utilizar esses objetos, ela deve obt-los atravs de pesquisas ao servio de nomes do MOM. O servio de nomes denido pela especicao JNDI.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 InitialContext ic = new InitialContext(); ConnectionFactory factory; factory = (ConnectionFactory)ic.lookup("ConnectionFactory"); QueueConnectionFactory factory factory = (QueueConnectionFactory)ic.lookup("QueueConnectionFactory"); TopicConnectionFactory factory; factory = (TopicConnectionFactory)ic.lookup("TopicConnectionFactory"); Queue queue queue = (Queue)ic.lookup("Queue"); Topic topic; topic = (Topic)ic.lookup("Topic");

Normalmente, os servidores de aplicao Java EE oferecem o recurso de Injeo de Dependncia para que as aplicaes obtenham as fbricas, las ou tpicos. No Glasssh, possvel injetar esses objetos atravs da anotao @Resource. Inclusive em aplicaes standalone (fora do servidor).
1 2 1 2 @Resource(mappedName = "jms/ConnectionFactory") private ConnectionFactory connectionFactory; @Resource(mappedName = "jms/Queue") private Queue queue;

1.6.2

Criando Conexes e Sesses

As sesses JMS so responsveis pela criao das mensagens JMS, dos emissores e dos receptores de mensagens. As sesses JMS so criadas pelas conexes JMS que por sua vez so obtidas atravs de uma fbrica de conexes.
1 1 Connection connection = factory.createConnection(); Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

1.6.3

Criando Emissores e Receptores

Atravs de uma sesso JMS, podemos criar emissores e receptores de mensagens. Esses objetos so criados j ligados a um destino especco.
1 MessageProducer sender = session.createProducer(queue);

www.k19.com.br

JMS
1 MessageConsumer receiver = session.createConsumer(queue);

1.6.4

Criando Mensagens

As mensagens so criadas pelas sesses JMS. O tipo mais simples de mensagem o TextMessage.
1 2 TextMessage message = session.createTextMessage(); message.setText("Ol");

1.6.5

Enviando Mensagens

As mensagens JMS so enviadas atravs do mtodo send() de um emissor (MessageProducer).


1 sender.send(message);

1.6.6

Recebendo Mensagens

Para receber mensagens JMS, necessrio inicializar a conexo e depois utilizar o mtodo receive() de um receptor (MessageConsumer).
1 2 connection.start(); TextMessage message = (TextMessage)receiver.receive();

1.7

Exerccios

10. Crie um Java Project no eclipse para implementar uma aplicao que possa enviar mensagens para a la e o tpico criados anteriormente. Voc pode digitar CTRL+3 em seguida new Java Project e ENTER. Depois, siga exatamente as imagens abaixo. 7 K19 Treinamentos

JMS

www.k19.com.br

JMS

K19 Treinamentos

JMS

11. Crie um pacote chamado emissores no projeto emissorJMS. 12. Adicione no pacote emissores uma classe com main para enviar uma mensagem JMS para a la pedidos.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 public class EnviaNovoPedido { public static void main(String[] args) throws Exception { // servio de nomes - JNDI InitialContext ic = new InitialContext(); // fbrica de conexes JMS ConnectionFactory factory = (ConnectionFactory) ic .lookup("jms/K19Factory"); // fila Queue queue = (Queue) ic.lookup("jms/pedidos"); // conexo JMS Connection connection = factory.createConnection(); // sesso JMS Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); // emissor de mensagens MessageProducer sender = session.createProducer(queue); // mensagem TextMessage message = session.createTextMessage(); message.setText("Uma pizza de cinco queijos e uma coca-cola 2l - " + System. currentTimeMillis()); // enviando sender.send(message);

www.k19.com.br

10

JMS
30 31 32 33 34 35 36 37 38 // fechando sender.close(); session.close(); connection.close(); System.out.println("Mensagem Enviada"); System.exit(0); } }

13. Execute uma vez a classe EnviaNovoPedido.

14. Crie um Java Project no eclipse para implementar uma aplicao que possa receber as mensagens da la e do tpico criados anteriormente. Voc pode digitar CTRL+3 em seguida new Java Project e ENTER. Depois, siga exatamente as imagens abaixo.

11

K19 Treinamentos

JMS

www.k19.com.br

12

JMS

13

K19 Treinamentos

JMS 15. Crie um pacote chamado receptores no projeto receptorJMS. 16. Adicione no pacote receptores uma classe com main para receber uma mensagem JMS da la pedidos.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 public class RecebePedido { public static void main(String[] args) throws Exception { // servio de nomes - JNDI InitialContext ic = new InitialContext(); // fbrica de conexes JMS ConnectionFactory factory = (ConnectionFactory) ic .lookup("jms/K19Factory"); // fila Queue queue = (Queue) ic.lookup("jms/pedidos"); // conexo JMS Connection connection = factory.createConnection(); // sesso JMS Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); // receptor de mensagens MessageConsumer receiver = session.createConsumer(queue); // inicializa conexo connection.start(); // recebendo TextMessage message = (TextMessage) receiver.receive(); System.out.println(message.getText()); // fechando receiver.close(); session.close(); connection.close(); System.out.println("FIM"); System.exit(0); } }

17. Execute uma vez a classe RecebePedido. 18. Adicione no pacote receptores uma classe com main para receber uma mensagem JMS do tpico noticias.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 public class AssinanteDeNoticias { public static void main(String[] args) throws Exception { // servio de nomes - JNDI InitialContext ic = new InitialContext(); // fbrica de conexes JMS ConnectionFactory factory = (ConnectionFactory) ic .lookup("jms/K19Factory"); // tpico Topic topic = (Topic) ic.lookup("jms/noticias"); // conexo JMS Connection connection = factory.createConnection(); // sesso JMS Session session = connection.createSession(false,

www.k19.com.br

14

JMS
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 Session.AUTO_ACKNOWLEDGE); // receptor de mensagens MessageConsumer receiver = session.createConsumer(topic); // inicializa conexo connection.start(); // recebendo TextMessage message = (TextMessage) receiver.receive(); System.out.println(message.getText()); // fechando receiver.close(); session.close(); connection.close(); System.out.println("FIM"); System.exit(0); } }

19. Execute duas vez a classe AssinanteDeNoticias. 20. Adicione no pacote emissores uma classe com main para enviar uma mensagem JMS para o tpico noticias.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 public class EnviaNoticia { public static void main(String[] args) throws Exception { // servio de nomes - JNDI InitialContext ic = new InitialContext(); // fbrica de conexes JMS ConnectionFactory factory = (ConnectionFactory)ic.lookup("jms/K19Factory"); // tpico Topic topic = (Topic)ic.lookup("jms/noticias"); // conexo JMS Connection connection = factory.createConnection(); // sesso JMS Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); // emissor de mensagens MessageProducer sender = session.createProducer(topic); // mensagem TextMessage message = session.createTextMessage(); message.setText("A copa do mundo de 2014 ser no Brasil - " + System. currentTimeMillis()); // enviando sender.send(message); // fechando sender.close(); session.close(); connection.close(); System.out.println("Mensagem Enviada"); System.exit(0); } }

21. Execute uma vez a classe EnviaNoticia e observe os consoles dos assinantes. 15 K19 Treinamentos

JMS

1.8

Modos de recebimento

As mensagens JMS podem ser recebidas atravs de um MessageConsumer de trs maneiras diferentes: Bloqueante: A execuo no continua at o recebimento da mensagem.
1 receiver.receive();

Semi-Bloqueante: A execuo no continua at o recebimento da mensagem ou at o trmino de um perodo estipulado.


1 2 // espera no mximo 5 segundos receiver.receive(5000);

No-Bloqueante: A execuo no interrompida se a mensagem no for recebida imediatamente.


1 receiver.receiveNoWait();

1.9

Percorrendo uma la

Podemos percorrer as mensagens de uma la sem retir-las de l. Para isso, devemos utilizar um QueueBrowser.
1 2 3 4 5 6 QueueBrowser queueBrowser = session.createBrowser(queue); Enumeration<TextMessage> messages = queueBrowser.getEnumeration(); while (messages.hasMoreElements()) { TextMessage message = messages.nextElement(); }

1.10

Exerccios

22. Adicione no pacote receptores uma classe com main para percorrer as mensagens da la pedidos.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 public class PercorrendoFila { public static void main(String[] args) throws Exception { // servio de nomes - JNDI InitialContext ic = new InitialContext(); // fbrica de conexes JMS ConnectionFactory factory = (ConnectionFactory) ic .lookup("jms/K19Factory"); // fila Queue queue = (Queue) ic.lookup("jms/pedidos"); // conexo JMS Connection connection = factory.createConnection(); // sesso JMS Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

www.k19.com.br

16

JMS
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 // queue browser QueueBrowser queueBrowser = session.createBrowser(queue); Enumeration<TextMessage> messages = queueBrowser.getEnumeration(); int count = 1; while (messages.hasMoreElements()) { TextMessage message = messages.nextElement(); System.out.println(count + " : " + message.getText()); count++; } // fechando queueBrowser.close(); session.close(); connection.close(); System.out.println("FIM"); System.exit(0); } }

23. Execute algumas vezes a classe EnviaNovoPedido para popular a la pedidos e depois execute a classe PercorrendoFila.

1.11

Selecionando mensagens de um tpico

Podemos anexar propriedades s mensagens enviadas a um tpico JMS. As propriedades podem servir como ltro para os assinantes do tpico selecionarem as mensagens que eles desejam receber. O cdigo abaixo acrescenta uma propriedade a uma mensagem JMS.
1 message.setStringProperty("categoria", "esporte");

Quando um receptor criado associado a um tpico, podemos aplicar o critrio de seleo das mensagens desejadas.
1 MessageConsumer receiver = session.createConsumer(topic, "(categoria = esporte)");

1.12

Exerccios

24. Altere a classe AssinanteDeNoticias para selecionar somente as mensagens de esporte. Observe o trecho de cdigo que voc deve alterar:
1 2 // receptor de mensagens MessageConsumer receiver = session.createConsumer(topic, "(categoria = esporte)");

25. Altere a classe EnviaNoticia acrescentando uma propriedade mensagem enviada. Observe o trecho de cdigo que voc deve alterar:
1 2 3 4 // mensagem TextMessage message = session.createTextMessage(); message.setStringProperty("categoria", "esporte"); message.setText("A copa do mundo de 2014 ser no Brasil - " + System.currentTimeMillis ());

17

K19 Treinamentos

JMS 26. Execute uma vez a classe AssinanteDeNoticias e depois a classe EnviaNoticia. Observe que a mensagem recebida pelo assinante. 27. Altere o valor da propriedade da mensagem enviada.
1 2 3 4 // mensagem TextMessage message = session.createTextMessage(); message.setStringProperty("categoria", "geral"); message.setText("A copa do mundo de 2014 ser no Brasil - " + System.currentTimeMillis ());

28. Execute uma vez a classe EnviaNoticia. Observe que agora a mensagem no recebida pelo assinante.

1.13

Tpicos Durveis

As mensagens enviadas para tpicos JMS normais s podem ser recebidas pelos assinantes que estiverem conectados no momento do envio. Dessa forma, se um assinante estiver desconectado ele perder as mensagens enviadas durante o perodo off-line. A especicao JMS dene um tipo especial de tpico que armazena as mensagens dos assinantes desconectados e as envia assim que eles se conectarem. Esses so os tpicos durveis.

1.14

Exerccios

29. Crie uma fbrica para tpicos durveis atravs da interface de administrao do Glasssh seguindo exatamente os passos das imagens abaixo:

www.k19.com.br

18

JMS

30. Adicione no pacote receptores uma classe com main para receber uma mensagem JMS do tpico noticias inclusive as enviadas enquanto a aplicao estiver off-line.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 public class AssinanteDuravel { public static void main(String[] args) throws Exception { // servio de nomes - JNDI InitialContext ic = new InitialContext(); // fbrica de conexes JMS ConnectionFactory factory = (ConnectionFactory) ic .lookup("jms/K19DurableFactory"); // tpico Topic topic = (Topic) ic.lookup("jms/noticias"); // conexo JMS Connection connection = factory.createConnection(); // sesso JMS Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); // receptor de mensagens MessageConsumer receiver = session.createDurableSubscriber(topic, "Assinante1"); // inicializa conexo connection.start(); // recebendo TextMessage message = (TextMessage) receiver.receive(2000); while(message != null){ System.out.println(message.getText()); message = (TextMessage) receiver.receive(2000); } // fechando receiver.close(); session.close(); connection.close(); System.out.println("FIM"); System.exit(0); } }

19

K19 Treinamentos

JMS 31. Adicione no pacote emissores uma classe com main para enviar uma mensagem JMS durvel para o tpico noticias.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 public class EnviaNoticiaDuravel { public static void main(String[] args) throws Exception { // servio de nomes - JNDI InitialContext ic = new InitialContext(); // fbrica de conexes JMS ConnectionFactory factory = (ConnectionFactory)ic.lookup("jms/ K19DurableFactory"); // tpico Topic topic = (Topic)ic.lookup("jms/noticias"); // conexo JMS Connection connection = factory.createConnection(); // sesso JMS Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); // emissor de mensagens MessageProducer sender = session.createProducer(topic); // mensagem TextMessage message = session.createTextMessage(); message.setText("A copa do mundo de 2014 ser no Brasil - " + System. currentTimeMillis()); // enviando sender.send(message); // fechando sender.close(); session.close(); connection.close(); System.out.println("Mensagem Enviada"); System.exit(0); } }

32. Execute uma vez a classe AssinanteDuravel para cadastrar um assinante. 33. Execute algumas vezes a classe EnviaNoticiaDuravel. Perceba que o assinante est ofine. 34. Execute a classe AssinanteDuravel para receber as mensagens enviadas enquanto o assinante estava ofine.

1.15

JMS e EJB

A arquitetura JMS intrinsecamente relacionada com a arquitetura EJB. Uma aplicao EJB pode receber e processar mensagens JMS de uma forma simples e eciente. A especicao EJB dene um tipo de objeto especializado no recebimento de mensagens JMS. Esse objetos so os Message Driven Beans (MDBs). Para implementar um MDB, devemos aplicar a anotao @MessageDriven e implementar a interface MessageListener.
1 2 3 @MessageDriven(mappedName="jms/destination1") public class TratadorDeMensagensMDB implements MessageListener{

www.k19.com.br

20

JMS
4 5 6 7 8 9 10 11 12 13 14 @Override public void onMessage(Message message) { try { TextMessage msg = (TextMessage) message; System.out.println(msg.getText()); } catch (JMSException e) { System.out.println("erro"); } } }

1.16

Exerccios

35. Crie um EJB Project no eclipse para implementar uma aplicao que possa receber as mensagens do tpico noticias criado anteriormente. Voc pode digitar CTRL+3 em seguida new EJB Project e ENTER. Depois, siga exatamente a imagem abaixo.

36. Crie um pacote chamado mdbs no projeto receptorJMS-EJB. 37. Adicione no pacote mdbs um Message Driven Bean para receber e processar as mensagens do tpico noticias.
1 2 3 4 5 6 @MessageDriven(mappedName="jms/noticias") public class TratadorDeMensagensMDB implements MessageListener{ @Override public void onMessage(Message message) {

21

K19 Treinamentos

JMS
7 8 9 10 11 12 13 14 try { TextMessage msg = (TextMessage) message; System.out.println(msg.getText()); } catch (JMSException e) { System.out.println("erro"); } } }

38. Implante o projeto receptorJMS-EJB no Glasssh atravs da view Servers. 39. Envie uma mensagem para o tpico noticias e observe o console do eclipse.

1.17

Projeto - Rede de Hotis

Para praticar os conceitos da arquitetura JMS, vamos implementar aplicaes que devem se comunicar de forma automatizada. Suponha que uma rede de hotis possua uma aplicao central para administrar os pagamentos realizados pelos clientes em qualquer unidade da rede. Cada hotel controlado por uma aplicao local que deve enviar os dados necessrios de cada pagamento para aplicao central.

1.18

Exerccios

40. Adicione uma la com o seguinte JNDI Name jms/pagamentos no Glasssh. 41. Implemente a aplicao local que deve executar em cada unidade da rede de hotis atravs de uma aplicao Java SE. Essa aplicao deve obter os dados dos pagamentos atravs do Console do Eclipse e enviar uma mensagem JMS para a la jms/pagamentos com esses dados. Utilize a classe Scanner para obter os dados digitados do Console.
1 2 3 // DICA Scanner entrada = new Scanner(System.in); String linha = entrada.nextLine();

42. Implemente a aplicao central da rede de hotis que deve tratar todas as mensagens enviada la jms/pagamentos atravs de uma aplicao EJB. Essa aplicao deve utilizar Message Driven Beans. Simplesmente imprima no Console do Eclipse os dados extrados das mensagens recebidas. 43. (Opcional) Faa a aplicao central enviar uma mensagem de conrmao para as aplicaes locais a cada mensagem de pagamento processada. Dica: Utilize um tpico JMS e faa cada aplicao local ltrar as mensagens desse tpico que correspondem a pagamentos que ela enviou aplicao central.

www.k19.com.br

22

Captulo 2 JAX-WS
2.1 Web Services

Muitas vezes, necessrio que os servios oferecidos por uma organizao sejam acessados diretamente pelos sistemas de outras organizaes sem interveno humana. Por exemplo, o Ministrio da Fazendo do Brasil introduziu recentemente uma nova sistemtica de emisso de notas scais. Hoje, as empresas podem descartar o mtodo tradicional de emisso em papel e utilizar a emisso eletrnica. Inclusive, o servio de emisso de nota scal eletrnica pode ser acessado diretamente pelos sistemas de cada empresa, automatizando o processo e consequentemente diminuindo gastos. Diversos outros servios possuem caractersticas semelhantes: Cotao de Moedas Previso do Tempo Vericao de CPF ou CPNJ Cotao de Frete Alm da necessidade de serem acessados diretamente por sistemas e no por pessoas, geralmente, esses servios devem ser disponibilizados atravs da internet para atingir um grande nmero de sistemas usurios. Nesse cenrio, outra condio importante que no exista nenhuma restrio quanto a plataforma utilizada em cada sistema. Da surge o conceito de web service. Resumidamente, um web service um servio oferecido por um sistema que pode ser acessado diretamente por outro sistema desenvolvido em qualquer tecnologia atravs de uma rede como a internet. Cada plataforma oferece os recursos necessrios para que os desenvolvedores possam disponibilizar ou acessar web services. A organizao W3C dene alguns padres para denir o funcionamento de um web service. Em geral, as plataformas de maior uso comercial implementam a arquitetura denida pelos padres da W3C. Na plataforma Java, h especicaes que denem a implementao Java dos padres estabelecidos pelo W3C. A especicao java diretamente relacionada a Web Services que seguem os padres da W3C a Java API for XML-Based Web Services - JAX-WS. A JAX-WS depende fortemente de outra especicao Java, a JAXB Java Architecture for XML Binding. 23

JAX-WS A seguir mostraremos o funcionamento bsico dos recursos denidos pela especicao JAXB e a arquitetura denida pela JAX-WS.

2.2

JAXB

A ideia principal da JAXB denir o mapeamento e transformao dos dados de uma aplicao Java para XML e vice versa. Com os recursos do JAXB podemos transformar uma rvore de objetos Java em texto XML ou vice versa. Suponha uma simples classe Java para modelar contas bancrias.
1 2 3 4 5 6 7 class Conta { private double saldo; private double limite; //GETTERS AND SETTERS }

Para poder transformar objetos da classe conta em texto XML, devemos aplicar a anotao @XMLRootElement.
1 2 3 4 @XMLRootElement class Conta { ... }

O contexto do JAXB deve ser criado para que as anotaes de mapeamento possam ser processadas. O seguinte cdigo cria o contexto do JAXB.
1 JAXBContext context = JAXBContext.newInstance(Conta.class);

O processo de transformar um objeto Java em texto XML chamado de marshal ou serializao. Para serializar um objeto Java em XML, devemos obter atravs do contexto do JAXB um objeto da interface Marshaller.
1 Marshaller marshaller = context.createMarshaller();

Por m, podemos criar um objeto da classe C ONTA e utilizar um Marshaller para serializlo em XML e guardar o contedo em um arquivo.
1 2 3 4 5 Conta conta = new Conta(); conta.setLimite(2000); conta.setSaldo(2000); marshaller.marshal(conta, new File("conta.xml"));

O processo inverso, ou seja, transformar um texto XML em um objeto da classe conta denominado unmarshal ou deserializao. Para deserializar um XML, devemos obter atravs do contexto do JAXB um objeto da interface Unmarshaller.
1 2 3 Unmarshaller unmarshaller = context.createUnmarshaller(); Conta conta = (Conta) unmarshaller.unmarshal(new File("conta.xml"));

www.k19.com.br

24

JAX-WS

2.3

Exerccios

1. Crie um Java Project no eclipse para testar o funcionamento bsico dos recursos denidos pela especicao JAXB. Voc pode digitar CTRL+3 em seguida new Java Project e ENTER. Depois, siga exatamente a imagem abaixo.

2. Crie um pacote chamado jaxb no projeto jaxb. 3. Adicione no pacote jaxb uma classe para modelar contas bancrias. Aplique a anotao @XmlRootElement.
1 2 3 4 5 6 7 8 @XmlRootElement public class Conta { private double saldo; private double limite; // GETTERS AND SETTERS }

4. Adicione no pacote jaxb uma classe com main para serializar um objeto da classe C ONTA.
1 2 3 4 5 6 7 8 public class Serializador { public static void main(String[] args) throws JAXBException { JAXBContext context = JAXBContext.newInstance(Conta.class); Marshaller marshaller = context.createMarshaller(); Conta conta = new Conta(); conta.setLimite(2000);

25

K19 Treinamentos

JAX-WS
9 10 11 12 conta.setSaldo(2000); marshaller.marshal(conta, new File("conta.xml")); } }

5. Execute a classe Serializador e atualize o projeto para o arquivo conta.xml aparecer. Observe o contedo XML gerado. 6. Adicione no pacote jaxb uma classe com main para deserializar o XML criado anteriormente.
1 2 3 4 5 6 7 8 9 10 11 12 public class Deserializador { public static void main(String[] args) throws JAXBException { JAXBContext context = JAXBContext.newInstance(Conta.class); Unmarshaller unmarshaller = context.createUnmarshaller(); Conta conta = (Conta) unmarshaller.unmarshal(new File("conta.xml")); System.out.println(conta.getLimite()); System.out.println(conta.getSaldo()); } }

7. Execute a classe Deserializador. 8. Adicione no pacote jaxb uma classe para modelar os clientes donos das contas bancrias.
1 2 3 4 5 public class Cliente { private String nome; // GETTERS AND SETTERS }

9. Altere a classe Conta para estabelecer um vnculo com a classe C LIENTE.


1 2 3 4 5 6 7 8 9 10 @XmlRootElement public class Conta { private double saldo; private double limite; private Cliente cliente; // GETTERS AND SETTERS }

10. Altere a classe Serializacao e a teste novamente.


1 2 3 4 5 6 7 8 9 10 11 12 13 14 public class Serializador { public static void main(String[] args) throws JAXBException { JAXBContext context = JAXBContext.newInstance(Conta.class); Marshaller marshaller = context.createMarshaller(); Cliente cliente = new Cliente(); cliente.setNome("Rafael Cosentino"); Conta conta = new Conta(); conta.setLimite(2000); conta.setSaldo(2000); conta.setCliente(cliente);

www.k19.com.br

26

JAX-WS
15 16 17 marshaller.marshal(conta, new File("conta.xml")); } }

11. Altere a classe Deserializacao e a teste novamente.


1 2 3 4 5 6 7 8 9 10 11 12 13 public class Deserializador { public static void main(String[] args) throws JAXBException { JAXBContext context = JAXBContext.newInstance(Conta.class); Unmarshaller unmarshaller = context.createUnmarshaller(); Conta conta = (Conta) unmarshaller.unmarshal(new File("conta.xml")); System.out.println(conta.getLimite()); System.out.println(conta.getSaldo()); System.out.println(conta.getCliente().getNome()); } }

2.4

Criando um web service - Java SE

Para comear, implementaremos um servio e o disponibilizaremos como Web Service atravs dos recursos denido pela JAX-WS. Lembrando que a especicao JAX-WS compatvel com os padres do W3C. Essa implementao ser realizada em ambiente Java SE. Para exemplicar, suponha um servio para gerar nmeros aleatrios. A lgica desse servio pode ser denida atravs de um mtodo Java.
1 2 3 4 5 class Gerador { public double geraNumero(){ return Math.random() * 200; } }

Para que essa classe seja interpretada como um web service devemos aplicar a anotao @WebService.
1 2 3 4 @WebService class Gerador { ... }

Podemos publicar o servio implementado pela classe Gerador atravs da classe Endpoint.
1 2 3 4 5 6 7 public class Publicador { public static void main(String[] args) { System.out.println("web service - Gerador Inicializado"); Gerador gerador = new Gerador(); Endpoint.publish("http://localhost:8080/gerador", geradorDeNumeros); } }

A denio do web service em WSDL pode ser consultada atravs da url http://localhost: 8080/gerador?wsdl. 27 K19 Treinamentos

JAX-WS

2.5

Consumindo um web service com JAX-WS

Agora, implementaremos um cliente de um web service que seja compatvel com os padres W3C utilizando os recursos do JAX-WS. O primeiro passo utilizar a ferramenta wsimport para gerar as classes necessrias para acessar o web service a partir da denio do mesmo em WSDL. As classes geradas pelo wsimport no devem ser alteradas.
1 wsimport -keep http://localhost:8080/gerador?wsdl

Com o apoio das classes geradas pelo wsimport podemos consumir o web service.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 public class Consumidor { public static void main(String[] args) { // Servio GeradorDeNumerosService service = new GeradorDeNumerosService(); // Proxy GeradorDeNumeros proxy = service.getGeradorDeNumerosPort(); // Consumindo double numero = proxy.geraNumero(); System.out.println(numero); } }

2.6

Exerccios

12. Crie um Java Project no eclipse para implementar um web service que gere nmeros aleatrios. Voc pode digitar CTRL+3 em seguida new Java Project e ENTER. Depois, siga exatamente a imagem abaixo. www.k19.com.br 28

JAX-WS

13. Crie um pacote chamado webservices no projeto random. 14. Adicione no pacote webservices uma classe para implementar o servio de gerar nmeros aleatrios.
1 2 3 4 5 6 @WebService public class Random { public double next(double max){ return Math.random() * max; } }

15. Adicione no pacote webservices uma classe com main para publicar o web service.
1 2 3 4 5 6 7 public class RandomPublisher { public static void main(String[] args) { System.out.println("Random web service start..."); Random random = new Random(); Endpoint.publish("http://localhost:8080/random", random); } }

16. Execute a classe RandomPublisher. 17. Consulte atravs de um navegador a url http://localhost:8080/random?wsdl para conferir a denio do web service em WSDL. 18. Crie um Java Project no eclipse para consumir o web service que gera nmeros aleatrios implementado anteriormente. Voc pode digitar CTRL+3 em seguida new Java Project e ENTER. Depois, siga exatamente a imagem abaixo. 29 K19 Treinamentos

JAX-WS

19. Gere as classes necessrias para consumir o web service atravs da ferramenta wsimport. Abra um terminal e siga os passos abaixo.

www.k19.com.br

30

JAX-WS 20. Atualize o projeto randomClient. Clique com o boto direito em cima desse projeto e depois clique com o esquerdo em refresh.

21. Adicione no pacote webservices do projeto randomClient uma classe para consumir o servio de gerar nmeros aleatrios.
1 2 3 4 5 6 7 8 9 10 11 12 13 public class Consumer { public static void main(String[] args) { // service RandomService randomService = new RandomService(); // proxy Random proxy = randomService.getRandomPort(); // operation double next = proxy.next(50); System.out.println(next); } }

22. Implemente outro consumidor s que agora em Ruby. Abra um terminal e siga os passos abaixo.

31

K19 Treinamentos

JAX-WS

2.7

JAX-WS e EJB

Os recursos da arquitetura EJB podem ser utilizados juntamento com os recursos denidos pela especicao JAX-WS. Podemos expor um Stateless Session Bean ou um Singleton Session Bean como um Web Service que segue os padres da W3C pois a duas especicaes, EJB e JAX-WS, esto relacionadas. Do ponto de vista da aplicao, basta aplicar a anotao @WebService na classe que implementa um Stateless Session Bean ou um Singleton Session Bean.
1 2 3 4 5 6 7 @WebService @Stateless public class Random { public double next(double max){ return Math.random() * max; } }

O container EJB publicar o web service ao inicializar a aplicao.

2.8

Exerccios

23. Crie um EJB Project no eclipse para implementar um Stateless Session Bean que gere nmeros aleatrios e exponha o como um web service. Voc pode digitar CTRL+3 em seguida new EJB Project e ENTER. Depois, siga exatamente a imagem abaixo. www.k19.com.br 32

JAX-WS

24. Crie um pacote chamado webservices no projeto randomEJB. 25. Adicione no pacote webservices uma classe para implementar o Statless Session Bean.
1 2 3 4 5 6 7 @WebService @Stateless public class Random { public double next(double max){ return Math.random() * max; } }

26. Implante o projeto randomEJB no Glasssh atravs da view Servers. 27. Acesse a url http://localhost:8080/RandomService/Random?WSDL para obter o WSDL que dene o web service. 28. Acesse a url http://localhost:8080/RandomService/Random?Tester para testar o web service atravs de uma pgina criada automaticamente pelo Glasssh. 29. Analogamente, implemente um Stateless Session Bean que oferea as operaes fundamentais da matemtica. 30. (Opcional) Implemente um cliente Java SE para consumir esse web service.

2.9

Projeto - Txi no Aeroporto

Para melhorar o atendimento aos seus clientes, a diretoria de um aeroporto decidiu implantar um servio prprio de txi. Ela acredita que dessa forma conseguir oferecer preos 33 K19 Treinamentos

JAX-WS menores e maior qualidade para os seus passageiros. O aeroporto funcionar como um intermedirio entre os passageiros e os taxistas. Os pagamentos sero realizados para o aeroporto e depois repassados para o proprietrio do txi. A contratao desse servio pode ser realizada na chegada do passageiro ao aeroporto ou atravs da internet. Como o aeroporto recebe pessoas de todas as partes do mundo, a diretoria quer oferecer a possibilidade dos seus passageiros efetuarem o pagamento do servio de txi com dinheiro de qualquer pas. Da surge a necessidade de obter a cotao das moedas. A equipe de TI decidiu obter as cotaes atravs de um web service. Para a emitir nota scal para brasileiros, o servio de txi deve vericar a validade do CPF do passageiro ou do CNPJ da empresa que car responsvel pelo pagamento. Essa vericao deve ser realizada atravs um web service. O valor cobrado dos passageiros depender do preo atual da gasolina e da distncia a ser percorrida. Para obter o preo do combustvel e calcular a distncia, o servio de txi dever consultar web services.

2.10

Exerccios

31. Implemente com dados ctcios um web service em JAX-WS que informe a cotao das moedas. 32. Implemente com lgica ctcia um web service em JAX-WS que realize a validao de CPF ou CNPJ. 33. Implemente com dados ctcios um web service em JAX-WS que informe o preo da gasolina. 34. Implemente com dados ctcios um web service em JAX-WS que calcule a distncia entre dois locais. 35. Crie uma aplicao Java SE para implementar o servio de txi do aeroporto. Obtenha da entrada padro as seguintes informaes: (a) Moeda utilizada para o pagamento (b) CPF ou CNPJ (c) Endereo de destino Acesse os web services criados anteriormente para obter as informaes necessrias e imprima na sada padro o valor a ser pago pelo passageiro. 36. (Opcional) Substitua o web service de cotao de moeda implementado anteriormente pelo web service da WebserviceX.NET. O WSDL desse web service pode ser obtido atravs da http://www.webservicex.net/CurrencyConvertor.asmx?WSDL. 37. (Opcional) Substitua a lgica ctcia de validao de CPF ou CNPJ pela lgica real. 38. (Opcional) Utilize o servio do google para calcular a distncia entre duas localidades.

www.k19.com.br

34

Captulo 3 JAX-RS
3.1 REST vs Padres W3C

No captulo 2, vimos como implementar web services seguindo os padres da W3C (WSDL, SOAP e XML). Em geral, a complexidade de evoluir um web service que segue os padres W3C alta pois qualquer alterao no servio implica em uma nova denio em WSDL. Consequentemente, os proxies dos clientes devem ser atualizados. Como alternativa, podemos desenvolver web services seguindo apenas os princpios do estilo arquitetural REST(Representational State Transfer - http://www.ics.uci.edu/ ~fielding/pubs/dissertation/rest_arch_style.htm). Em geral, web services que seguem os princpios REST so mais fceis de implementar e evoluir. Na plataforma Java, h especicaes que denem o modelo de programao de web services Java que seguem os princpios REST. A principal especicao para esse tipo de web service a API for RESTful Web Services JAX-RS. A seguir mostraremos os conceitos principais do estilo arquitetural REST funcionamento bsico dos recursos denidos pela especicao JAX-RS.

3.2

Resources, URIs, Media Types e Operaes

No estilo arquitetural REST, qualquer informao disponvel um Resource. O cadastro de uma pessoa, uma imagem, um documento e a cotao de uma moeda so exemplos de resources. Cada resource deve possuir um identicador nico. Esse identicador ser utilizado para que o resource possa ser acessado. Na internet ou em uma intranet um web resources identicado por uma URI(Uniform Resource Identier - http://tools.ietf.org/html/ rfc3986). Por exemplo, a URI www.k19.com.br/cursos identica na internet a pgina com os cursos da K19. Os resources tambm podem ser representados em diversos formatos (Media Type). Novamente, na internet ou em uma intranet, seria normal que o cadastro de uma pessoa pudesse ser obtido em html, xml e json. 35

JAX-RS
1 2 3 4 5 6 7 8 9 10 <html> <head> <title>Rafael Cosentino</title> <head> <body> <h1>Rafael Cosentino</h1> <p>Lder de treinamentos da K19</p> </body> </html>

1 2 3 4

<pessoa> <nome>Rafael Cosentino</nome> <descricao>Lder de treinamentos da K19</descricao> <pessoa>

{"nome": "Rafael Cosentino", "descricao": "Lder de treinamentos da K19"}

Em uma arquitetura REST, um conjunto pequeno e xo de operaes deve ser denido previamente. As operaes so utilizadas para manipular os recursos de alguma forma. Por exemplo, na internet ou em uma intranet, os recursos so manipulados pelos mtodos do protocolo HTTP. Podemos atribuir uma semntica diferente para cada mtodo HTTP.

Resource www.k19.com.br/cursos www.k19.com.br/cursos

Mtodo HTTP GET POST

Semntica pega a lista de cursos adiciona um curso na lista

3.3

Web service com JAX-RS

A especicao JAX-RS dene um modelo de programao para a criao de web services restful (web service que seguem os princpios do estilo arquitetural REST).

3.4

Resources

De acordo com a JAX-RS, os web resources so implementados por classes Java (resource classes). Todo web resource deve possuir uma URI que denida parcialmente pela anotao @Path.
1 2 3 4 @Path("/Cotacao") class CotacaoResource { ... }

Os mtodos HTTP podem ser mapeados para mtodos Java de uma resource class. As anotaes @GET, @PUT, @POST, @DELETE e @HEAD so utilizadas para realizar esse www.k19.com.br 36

JAX-RS mapeamento.
1 2 3 4 5 6 7 8 @Path("/Cotacao") class CotacaoResource { @GET public String getCotacao(){ // implementao } }

O Media Type que ser utilizado para a representao do resource pode ser denido atravs da anotao @Produces e o do enum MediaType.
1 2 3 4 5 6 7 8 9 @Path("/Cotacao") class CotacaoResource { @GET @Produces(MediaType.TEXT_PLAIN) public String getCotacao(){ // implementao } }

3.5

Subresource

A princpio, uma resource class dene apenas um resource. Porm, podemos denir subresources dentro de uma resource class atravs de mtodos anotados com @Path.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 @Path("/Cotacao") class CotacaoResource { @GET @Path("/DollarToReal") @Produces(MediaType.TEXT_PLAIN) public String getCotacaoDollarToReal(){ // implementao } @GET @Path("/EuroToReal") @Produces(MediaType.TEXT_PLAIN) public String getCotacaoEuroToReal(){ // implementao } }

O suxo da URI de um subresource denido pela concatenao do valor da anotao @PATH aplicada na resource class com o valor da anotao @PATH aplicada no mtodo correspondente ao subresource. No exemplo acima, temos dois subresources com URI que possuem os seguintes suxos: /Cotacao/DollarToReal e /Cotacao/EuroToReal.

3.6

Exerccios

1. Crie um Java Project no eclipse para testar o funcionamento bsico dos recursos denidos pela especicao JAX-RS. Voc pode digitar CTRL+3 em seguida new Java Project e ENTER. Depois, siga exatamente a imagem abaixo. 37 K19 Treinamentos

JAX-RS

2. JAX-RS uma especicao. Para testar os recursos denidos nessa especicao temos que escolher uma implementao. Aqui, utilizaremos o projeto Jersey que implementa a JAX-RS. Crie uma pasta chamada lib no projeto jax-rs. 3. Copie os arquivos asm-3.1.jar, jersey-bundle-1.6.jar e jsr311-api-1.1.jar para a pasta lib. Esses arquivos podem ser encontrados na pasta K19-Arquivos na sua rea de Trabalho. 4. Adicione esses arquivos no classpath do projeto. 5. Crie um pacote chamado resources no projeto jax-rs. 6. Adicione no pacote resources uma classe para implementar um resource de cotao de moeda.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 @Path("/Cotacao") class CotacaoResource { @GET @Path("/DollarToReal") @Produces(MediaType.TEXT_PLAIN) public String getCotacaoDollarToReal(){ return "1.6"; } @GET @Path("/EuroToReal") @Produces(MediaType.TEXT_PLAIN) public String getCotacaoEuroToReal(){ return "3.1"; } }

www.k19.com.br

38

JAX-RS 7. Crie um pacote chamado main no projeto jax-rs. 8. Adicione no pacote main uma classe para publicar o web service.
1 2 3 4 5 6 public class Publicador { public static void main(String[] args) throws IllegalArgumentException, IOException { HttpServer server = HttpServerFactory.create("http://localhost:8080/"); server.start(); } }

9. Execute a classe Publicador. 10. Abra o refox e acesse as seguintes urls: http://localhost:8080/Cotacao/ DollarToReal e http://localhost:8080/Cotacao/EuroToReal. 11. No refox abra o Poster (clique no link no canto inferior direito) e faa uma requisio para cada uma das seguintes urls: http://localhost:8080/Cotacao/ DollarToReal e http://localhost:8080/Cotacao/EuroToReal.

3.7

Parmetros

A especicao JAX-RS dene um mecanismo bem simples para injetar os dados contidos nas requisies HTTP nos mtodos Java das resource classes. Veremos a seguir que tipo de dados podem ser injetados e como injet-los.

3.7.1

PathParam

Suponha que desejamos utilizar uris com o seguinte formato para realizar a cotao de moedas. /Cotacao/Dollar/Real: Valor do Dollar em Real. /Cotacao/Euro/Real: Valor do Euro em Real. /Cotacao/Moeda1/Moeda2: Valor da Moeda1 na Moeda2. Para trabalhar com uris com esse formato, podemos denir parmetros na URI de um resource atravs da anotao @PATH PARAM.
1 @Path{"/{M1}/{M2}"}

Os parmetros denidos atravs da anotao @PATH podem ser recuperados atravs da anotao @PathParam que deve ser aplicada nos argumentos dos mtodos de uma resource class.
1 2 3 4 5 6 7 @Path("/Cotacao") public class CotacaoResource { @GET @Path("/{M1}/{M2}") @Produces(MediaType.TEXT_PLAIN) public String cotacao(@PathParam("M1") String m1, @PathParam("M2") String m2){

39

K19 Treinamentos

JAX-RS
8 9 10 // implementacao } }

3.7.2

MatrixParam

Suponha que desejamos utilizar uris com o seguinte formato para realizar a cotao de moedas. /Cotacao;M1=dollar;M2=real: Valor do Dollar em Real. /Cotacao;M1=euro;M2=real: Valor do Euro em Real. /Cotacao;M1=moeda1;M2=moeda2: Valor da Moeda1 na Moeda2. As URIs acima possuem dois matrix params: M1 e M2. Esses parmetros podem ser recuperados atravs da anotao @MatrixParam que deve ser aplicada nos argumentos dos mtodos de uma resource class.
1 2 3 4 5 6 7 8 9 @Path("/Cotacao") public class CotacaoResource { @GET @Produces(MediaType.TEXT_PLAIN) public String cotacao(@MatrixParam("M1") String m1, @MatrixParam("M2") String m2){ // implementacao } }

3.7.3

QueryParam

Suponha que desejamos utilizar uris com o seguinte formato para realizar a cotao de moedas. /Cotacao?M1=dollar&M2=real: Valor do Dollar em Real. /Cotacao?M1=euro&M2=real: Valor do Euro em Real. /Cotacao?M1=moeda1&M2=moeda2: Valor da Moeda1 na Moeda2. As URIs acima possuem dois query params: M1 e M2. Esses parmetros podem ser recuperados atravs da anotao @QueryParam que deve ser aplicada nos argumentos dos mtodos de uma resource class.
1 2 3 4 5 6 7 8 9 @Path("/Cotacao") public class CotacaoResource { @GET @Produces(MediaType.TEXT_PLAIN) public String cotacao(@QueryParam("M1") String m1, @QueryParam("M2") String m2){ // implementacao } }

www.k19.com.br

40

JAX-RS

3.7.4

FormParam

Parmetros enviados atravs de formulrios HTML que utilizam o mtodo POST do HTTP podem ser recuperados atravs da anotao @FormParam.
1 2 3 4 <form action="http://www.k19.com.br/Cotacao" method="POST"> Moeda1: <input type="text" name="M1"> Moeda2: <input type="text" name="M2"> </form>

1 2 3 4 5 6 7 8 9

@Path("/Cotacao") public class CotacaoResource { @GET @Produces(MediaType.TEXT_PLAIN) public String cotacao(@FormParam("M1") String m1, @FormParam("M2") String m2){ // implementacao } }

3.7.5
1 2 3 4 5 6 7 8 9

HeaderParam

Os headers HTTP podem ser recuperados atravs da anotao @HeaderParam.


@Path("/User-Agent") public class UserAgentResource { @GET @Produces(MediaType.TEXT_PLAIN) public String userAgent(@HeaderParam("User-Agent") String userAgent){ return userAgent; } }

3.7.6

CookieParam

Os valores dos cookies enviados nas requisies HTTP podem ser recuperados atravs da anotao @CookieParam.
1 2 3 4 5 6 7 8 9 @Path("/cookie") public class CookieResource { @GET @Produces(MediaType.TEXT_PLAIN) public String userAgent(@CookieParam("clienteID") String clienteID){ return clienteID; } }

3.8
1 2 3

Exerccios
@Path("/path-param") class TestaPathParamResource {

12. Adicione no pacote resources do projeto jax-rs uma classe para testar os path params.

41

K19 Treinamentos

JAX-RS
4 5 6 7 8 9 10 @GET @Path("/{p1}/{p2}") @Produces(MediaType.TEXT_PLAIN) public String pathParam(@PathParam("p1") String p1, @PathParam("p2") String p2){ return "P1 = " + p1 + ", P2 = " + p2; } }

13. Execute a classe Publicador. 14. Acesse as seguintes URIs para testar: http://localhost:8080/path-param/1/2 http://localhost:8080/path-param/java/csharp 15. (Opcional) Analogamente aos exerccios anteriores teste os matrix params e os query params.

3.9

Produzindo XML ou JSON

A especicao JAX-RS utiliza como base os recursos denidos pela especicao JAXB para produzir XML e JSON. A princpio os recursos do JAXB possibilitam apenas a produo de XML. Contudo, a arquitetura JAXB exvel e pode ser facilmente estendida para produzir JSON tambm. Suponha que seja necessrio implementar um web service que manipule a seguinte entidade:
1 2 3 4 5 6 7 8 9 class Produto { private String nome; private Double preco; private Long id; // GETTERS AND SETTERS }

Adicionando a anotao @XMLRootElement da especicao JAXB na classe P RODUTO, podemos gerar produtos em XML ou JSON.
1 2 3 4 @XMLRootElement class Produto { ... }

Agora, basta denir o Media Type nos mtodos de uma resource class de acordo com o formato que desejamos utilizar, XML ou JSON.
1 2 3 4 5 6 7 8 9 10 @Path("/produtos") class ProdutoResource { @GET @Path("/{id}/xml") @Produces(MediaType.APPLICATION_XML) public Produto getProdutoAsXML(@PathParam("id") int id) { // implementacao }

www.k19.com.br

42

JAX-RS
11 12 13 14 15 16 17 @GET @Path("/{id}/json") @Produces(MediaType.APPLICATION_JSON) public Produto getProdutoAsJSON(@PathParam("id") int id) { // implementacao } }

3.10

Consumindo XML ou JSON

Os recursos do JAXB tambm so utilizados para consumir XML ou JSON. Novamente suponha a seguinte entidade anotada com @XMLROOT E LEMENT:
1 2 3 4 5 6 7 8 9 10 @XMLRootElement class Produto { private String nome; private Double preco; private Long id; // GETTERS AND SETTERS }

Nos mtodos da resource class, devemos aplicar a anotao @Consumes nos mtodos.
1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8 @Path("/produtos") public class ProdutoResource { @POST @Consumes(MediaType.APPLICATION_XML) public void adiciona(Produto p) { // implementacao } } @Path("/produtos") public class ProdutoResource { @POST @Consumes(MediaType.APPLICATION_JSON) public void adiciona(Produto p) { // implementacao } }

3.11

Exerccios

16. Crie um pacote chamado entities no projeto jax-rs. 17. Adicione no pacote entities uma classe para modelar produtos.
1 2 3 4 5 6 7 8 9 10 @XmlRootElement public class Produto { private String nome; private Double preco; private Long id; // GETTERS AND SETTERS }

43

K19 Treinamentos

JAX-RS 18. Adicione no pacote resources uma classe para produzir produtos em XML e JSON.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 @Path("/produtos") public class ProdutoResource { @GET @Path("/{id}/xml") @Produces(MediaType.APPLICATION_XML) public Produto getProdutoAsXML(@PathParam("id") long id) { return this.geraProdutoFalso(id); } @GET @Path("/{id}/json") @Produces(MediaType.APPLICATION_JSON) public Produto getProdutoAsJSON(@PathParam("id") long id) { return this.geraProdutoFalso(id); } public Produto geraProdutoFalso(long id){ Produto p = new Produto(); p.setNome("produto" + id); p.setPreco(50.0*id); p.setId(id); return p; } }

19. Execute a classe Publicador. 20. Acesse as seguintes URIs para testar: http://localhost:8080/produtos/1/xml http://localhost:8080/produtos/1/json 21. Adicione no pacote resources uma classe converter produtos de XML para JSON e vice versa.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 @Path("/produtos/converte") public class ConversorDeProdutoResource { @POST @Path("/json/xml") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_XML) public Produto transformToXML(Produto p) { return p; } @POST @Path("/xml/json") @Consumes(MediaType.APPLICATION_XML) @Produces(MediaType.APPLICATION_JSON) public Produto transformToJSON(Produto p) { return p; } }

22. Execute a classe Publicador. 23. Abra o refox e depois o Poster (clique no canto inferior direito). www.k19.com.br 44

JAX-RS 24. Faa uma requisio atravs do Poster como mostra a imagem abaixo:

25. Agora, faa outra requisio atravs do Poster como mostra a imagem abaixo:

45

K19 Treinamentos

JAX-RS

3.12

Implementando um Cliente

A especicao JAX-RS no dene uma API para padronizar o desenvolvimento de clientes Java de web services restful. Algumas implementaes JAX-RS denem uma API no padronizada para a criao desses clientes. Veremos a seguir um pouco da API para implementao de consumidores Java de web services restful do projeto Jersey. O primeiro passo para utilizar a Client API do Jersey criar um objeto da classe Client atravs do mtodo esttico create() dessa mesma classe.
1 Client client = Client.create();

Depois, necessrio denir com qual resource queremos interagir atravs da URI do mesmo. Um objeto do tipo WebResource deve ser obtido atravs do mtodo resource() do cliente.
1 WebResource resource = client.resource("http://www.k19.com.br/cursos/k23");

Por m, podemos executar uma operao HTTP no resource atravs dos mtodos da classe WebResource. O tipo do resultado da operao denido previamente atravs do parmetro da operao escolhida.
1 Curso curso = resource.get(Curso.class);

3.13

Exerccios

26. Crie um pacote chamado client no projeto jax-rs. 27. Adicione no pacote client uma classe para interagir com o resource de cotao de moeda.
1 2 3 4 5 6 7 8 public class TesteCotacaoResource { public static void main(String[] args) { Client client = Client.create(); WebResource resource = client.resource("http://localhost:8080/Cotacao/ DollarToReal"); String cotacao = resource.get(String.class); System.out.println(cotacao); } }

28. Adicione no pacote client uma classe para interagir com o resource de produtos.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 public class TesteProdutoResource { public static void main(String[] args) { Client client = Client.create(); WebResource resourceXML = client.resource("http://localhost:8080/produtos/1/ xml"); System.out.println("TESTANDO COM XML"); String xml = resourceXML.get(String.class); System.out.println(xml); Produto produto1 = resourceXML.get(Produto.class); System.out.println(produto1.getId()); System.out.println(produto1.getNome()); System.out.println(produto1.getPreco()); WebResource resourceJSON = client.resource("http://localhost:8080/produtos/1/ json");

www.k19.com.br

46

JAX-RS
18 19 20 21 22 23 24 25 26 27 28 29

System.out.println("TESTANDO COM JSON"); String json = resourceJSON.get(String.class); System.out.println(json); Produto produto2 = resourceJSON.get(Produto.class); System.out.println(produto2.getId()); System.out.println(produto2.getNome()); System.out.println(produto2.getPreco()); } }

29. Adicione no pacote client uma classe para interagir com o resource de converso de formato dos produtos.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 public class TesteConversorDeProdutoResource { public static void main(String[] args) { Produto p = new Produto(); p.setId(1L); p.setNome("Bola"); p.setPreco(45.67); Client client = Client.create(); System.out.println("Convertendo para XML"); WebResource resource1 = client.resource("http://localhost:8080/produtos/ converte/json/xml"); String xml = resource1.type("application/json").post(String.class, p); System.out.println(xml); System.out.println("Convertendo para JSON"); WebResource resource2 = client.resource("http://localhost:8080/produtos/ converte/xml/json"); String json = resource2.type("application/xml").post(String.class, p); System.out.println(json); } }

3.14

Projeto

30. Para consolidar os recursos da JAX-RS e do projeto Jersey, implemente um web service restful para funcionar como CRUD de clientes. Os dados podem ser mantidos apenas em memria. Utilize os seguinte esquema de URIs e operaes para os resources do seu web service:

Resource localhost:8080/clientes localhost:8080/clientes localhost:8080/clientes/id localhost:8080/clientes/id

Mtodo HTTP GET POST PUT DELETE

Semntica lista dos clientes adiciona um cliente atualiza um cliente remove um cliente

Consulte o artigo sobre web services restful da K19. http://www.k19.com.br/ artigos/criando-um-webservice-restful-em-java/ 47 K19 Treinamentos

JAX-RS 31. Implementes clientes atravs da API do projeto Jersey para testar o web service.

www.k19.com.br

48