Sie sind auf Seite 1von 100

TREINAMENTOS

Integrao de Sistemas com Webservices, JMS e EJB

Integrao de Sistemas com Webservices, JMS e EJB

31 de agosto de 2013

Sumrio Sobre a K19 Seguro Treinamento Termo de Uso Cursos 1 JMS 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 1.10 1.11 1.12 1.13 1.14 1.15 1.16 1.17 1.18

i 1 2 3 4 1 1 1 2 14 15 17 18 35 35 35 38 38 39 40 46 47 50 50

Middleware Orientado a Mensagens - MOM Destinos: Filas e Tpicos . . . . . . . . . . . . Exerccios de Fixao . . . . . . . . . . . . . . Fbricas de Conexes . . . . . . . . . . . . . . Exerccios de Fixao . . . . . . . . . . . . . . Viso Geral . . . . . . . . . . . . . . . . . . . . Exerccios de Fixao . . . . . . . . . . . . . . Modos de recebimento . . . . . . . . . . . . . Percorrendo uma la . . . . . . . . . . . . . . Exerccios de Fixao . . . . . . . . . . . . . . Selecionando mensagens de um tpico . . . Exerccios de Fixao . . . . . . . . . . . . . . Tpicos Durveis . . . . . . . . . . . . . . . . Exerccios de Fixao . . . . . . . . . . . . . . JMS e EJB . . . . . . . . . . . . . . . . . . . . . Exerccios de Fixao . . . . . . . . . . . . . . Projeto - Rede de Hotis . . . . . . . . . . . . Exerccios de Fixao . . . . . . . . . . . . . .

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

JAX-WS 51 2.1 Web Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 2.2 JAXB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52 2.3 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53


www.facebook.com/k19treinamentos

S UMRIO

ii

2.4 2.5 2.6 2.7 2.8 2.9 2.10 2.11 2.12 2.13 3

Criando um web service - Java SE . . . . . . Consumindo um web service com JAX-WS Exerccios de Fixao . . . . . . . . . . . . . Autenticao . . . . . . . . . . . . . . . . . . Exerccios de Fixao . . . . . . . . . . . . . Exerccios Complementares . . . . . . . . . JAX-WS e EJB . . . . . . . . . . . . . . . . . . Exerccios de Fixao . . . . . . . . . . . . . Projeto - Txi no Aeroporto . . . . . . . . . Exerccios de Fixao . . . . . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

56 56 57 61 62 63 66 66 68 68 71 71 71 72 72 73 73 75 78 80 80 81 81 82 83 84 85 86 89 90 91

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 de Fixao . . . . . . . . . . . . . 3.7 Parmetros . . . . . . . . . . . . . . . . . . . 3.8 Exerccios de Fixao . . . . . . . . . . . . . 3.9 URI Matching . . . . . . . . . . . . . . . . . 3.10 Exerccios de Fixao . . . . . . . . . . . . . 3.11 HTTP Headers com @Context . . . . . . . . 3.12 Exerccios de Fixao . . . . . . . . . . . . . 3.13 Download de arquivos . . . . . . . . . . . . 3.14 Exerccios de Fixao . . . . . . . . . . . . . 3.15 Produzindo XML ou JSON . . . . . . . . . . 3.16 Consumindo XML ou JSON . . . . . . . . . 3.17 Exerccios de Fixao . . . . . . . . . . . . . 3.18 Implementando um Cliente . . . . . . . . . 3.19 Exerccios de Fixao . . . . . . . . . . . . . 3.20 Exerccios Complementares . . . . . . . . .

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

ii

www.k19.com.br

S UMRIO

Sobre a K19
A K19 uma empresa especializada na capacitao de desenvolvedores de software. Sua equipe composta por prossionais formados em Cincia da Computao pela Universidade de So Paulo (USP) e que possuem vasta experincia em treinamento de prossionais para rea de TI. O principal objetivo da K19 oferecer treinamentos de mxima qualidade e relacionados s principais tecnologias utilizadas pelas empresas. Atravs desses treinamentos, seus alunos se tornam capacitados para atuar no mercado de trabalho. Visando a mxima qualidade, a K19 mantm as suas apostilas em constante renovao e melhoria, oferece instalaes fsicas apropriadas para o ensino e seus instrutores esto sempre atualizados didtica e tecnicamente.

www.facebook.com/k19treinamentos

S UMRIO

Seguro Treinamento
Na K19 o aluno faz o curso quantas vezes quiser! Comprometida com o aprendizado e com a satisfao dos seus alunos, a K19 a nica que possui o Seguro Treinamento. Ao contratar um curso, o aluno poder refaz-lo quantas vezes desejar mediante a disponibilidade de vagas e pagamento da franquia do Seguro Treinamento. As vagas no preenchidas at um dia antes do incio de uma turma da K19 sero destinadas ao alunos que desejam utilizar o Seguro Treinamento. O valor da franquia para utilizar o Seguro Treinamento 10% do valor total do curso.

www.k19.com.br

S UMRIO

Termo de Uso
Termo de Uso
Todo o contedo desta apostila propriedade da K19 Treinamentos. A apostila pode ser utilizada livremente para estudo pessoal . Alm disso, este material didtico pode ser utilizado como material de apoio em cursos de ensino superior desde que a instituio correspondente seja reconhecida pelo MEC (Ministrio da Educao) e que a K19 seja citada explicitamente como proprietria do material. proibida qualquer utilizao desse material que no se enquadre nas condies acima sem o prvio consentimento formal, por escrito, da K19 Treinamentos. O uso indevido est sujeito s medidas legais cabveis.

www.facebook.com/k19treinamentos

S UMRIO

TR

S TO EN AM EIN TREINAMENTOS TR EIN AM EN TO

Conhea os nossos cursos


K01- Lgica de Programao K02 - Desenvolvimento Web com HTML, CSS e JavaScript K03 - SQL e Modelo Relacional K11 - Orientao a Objetos em Java K12 - Desenvolvimento Web com JSF2 e JPA2 K21 - Persistncia com JPA2 e Hibernate K22 - Desenvolvimento Web Avanado com JFS2, EJB3.1 e CDI K23 - Integrao de Sistemas com Webservices, JMS e EJB K41 - Desenvolvimento Mobile com Android K51 - Design Patterns em Java K52 - Desenvolvimento Web com Struts K31 - C# e Orientao a Objetos K32 - Desenvolvimento Web com ASP.NET MVC

www.k19.com.br/cursos

www.k19.com.br

CAPTULO

JMS

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.

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, as las e os tpicos so chamados de destinos(destinations). Uma mensagem enviada para uma la pode ser recebida por apenas um sistema (point-to-point). Uma mensagem enviada para um tpico pode ser recebida por diversos sistemas (publish-andsubscribe).
www.facebook.com/k19treinamentos

JMS

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.

Exerccios de Fixao

Copie o arquivo glasssh-VERSAO-with-hibernate.zip da pasta K19-Arquivos para a sua rea de Trabalho e descompacte-o.
1

Importante
Voc tambm pode obter o arquivo glasssh-VERSAO-with-hibernate.zip atravs do site da K19: www.k19.com.br/arquivos.

Copie o arquivo jboss-as-VERSAO-Final.zip da pasta K19-Arquivos para a sua rea de Trabalho e descompacte-o.
2

Importante
Voc tambm pode obter o arquivo jboss-as-VERSAO-Final.zip atravs do site da K19: www.k19.com.br/arquivos.

Siga as imagens abaixo para congurar e testar o Glasssh. No Eclipse. . .

www.k19.com.br

JMS

www.facebook.com/k19treinamentos

JMS

www.k19.com.br

JMS

www.facebook.com/k19treinamentos

JMS

www.k19.com.br

JMS

www.facebook.com/k19treinamentos

JMS
4

Siga as imagens abaixo para congurar e testar o JBoss. Pare o Glasssh antes de testar o JBoss No Eclipse. . .

www.k19.com.br

JMS

www.facebook.com/k19treinamentos

JMS

10

10

www.k19.com.br

11

JMS

www.facebook.com/k19treinamentos

11

JMS

12

Pare o JBoss. Inicie o Glasssh. Crie uma la JMS atravs da interface de administrao do Glasssh seguindo exatamente os passos das imagens abaixo:
5

12

www.k19.com.br

13

JMS

Crie um tpico JMS atravs da interface de administrao do Glasssh seguindo exatamente os passos das imagens abaixo:
6

www.facebook.com/k19treinamentos

13

JMS

14

Pare o Glasssh. Inicie o JBoss. Crie uma la e um tpico JMS no JBoss alterando o arquivo de congurao standalone-full.xml. Voc encontra esse arquivo na pasta jboss-as-7.1.1.Final/standalone/conguration.
7

1 2 3 4 5 6 7 8 9 1 11 12 13

... <jms - destinations > <jms - queue name = " pedidos " > < entry name = " queue / pedidos " / > < entry name = " java:jboss / exported / jms / queue / pedidos " / > </ jms - queue > <jms - topic name = " noticias " > < entry name = " topic / noticias " / > < entry name = " java:jboss / exported / jms / topic / noticias " / > </ jms - topic > ... </ jms - destinations > ...
Cdigo XML 1.1: standalone-full.xml

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 podem ser
14
www.k19.com.br

15

JMS

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

Exerccios de Fixao

Pare o JBoss. Inicie o Glasssh. Crie uma fbrica de conexes JMS atravs da interface de administrao do Glasssh seguindo exatamente os passos das imagens abaixo:
8

www.facebook.com/k19treinamentos

15

JMS

16

9 Pare o Glasssh. Inicie o JBoss. Crie uma fbrica de conexes JMS no JBoss alterando o arquivo de congurao standalone-full.xml. Voc encontra esse arquivo na pasta jboss-as-7.1.1.Final/standalone/conguration.

1 2 3 4 5 6 7 8 9 1 11 12 13 14

... <jms - connection - factories > < connection - factory name = " K19Factory " > < connectors > < connector - ref connector - name = " netty " / > </ connectors > < entries > < entry name = " K19Factory " / > < entry name = " java:jboss / exported / jms / K19Factory " / > </ entries > </ connection - factory > ... </ jms - connection - factories > ...
Cdigo XML 1.2: standalone-full.xml

10

Adicione um usurio no JBoss com as seguintes caractersticas:

Tipo: Application User Username: k19 Password: 1234 Roles: guest


16
www.k19.com.br

17

JMS

Utilize o script add-user.sh para adicionar o usurio k19 no JBoss. Siga os passos abaixo.
cosen@k19 :~/ Desktop / jboss - as -7.1.1. Final / bin$ ./ add - user . sh What type of user do you wish to add ? a) Management User ( mgmt - users . properties ) b) Application User ( application - users . properties ) (a ): b Enter the details of the new user to add . Realm ( ApplicationRealm ) : Username : k19 Password : Re - enter Password : What roles do you want this user to belong to ? ( Please enter a comma separated list , or leave blank for none ) : guest About to add user k19 for realm ApplicationRealm Is this correct yes / no ? yes Added user k19 to file / home / cosen / Desktop / jboss - as -7.1.1. Final / standalone / configuration / application - users . properties Added user k19 to file / home / cosen / Desktop / jboss - as -7.1.1. Final / domain / configuration / application - users . properties Added user k19 with roles guest to file / home / cosen / Desktop / jboss - as -7.1.1. Final / standalone / configuration / application - roles . properties Added user k19 with roles guest to file / home / cosen / Desktop / jboss - as -7.1.1. Final / domain / configuration / application - roles . properties

Terminal 1.1: Criando um usurio no JBoss

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

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 1 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).

www.facebook.com/k19treinamentos

17

JMS
1 @Resource ( mappedName = " jms / ConnectionFactory " ) 2 private ConnectionFactory connectionFactory ;

18

1 @Resource ( mappedName = " jms / Queue " ) 2 private Queue queue ;

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 Connection connection = factory . createConnection () ;

1 Session session = connection . createSession ( false , Session . AUTO_ACKNOWLEDGE ) ;

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 ) ;

1 MessageConsumer receiver = session . createConsumer ( queue ) ;

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

Enviando Mensagens
As mensagens JMS so enviadas atravs do mtodo send() de um emissor (MessageProducer).
1 sender . send ( message ) ;

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

Exerccios de Fixao

18

www.k19.com.br

19
11

JMS

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.

www.facebook.com/k19treinamentos

19

JMS

20

20

www.k19.com.br

21

JMS

www.facebook.com/k19treinamentos

21

JMS

22

12

Crie um pacote chamado br.com.k19.emissores no projeto emissorJMS.

13 Adicione no pacote br.com.k19.emissores uma classe com main para enviar uma mensagem JMS para a la pedidos do Glasssh.

1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 16 17 18 19 2

package br . com . k19 . emissores ; import java . util . Properties ; import import import import import import import javax . jms . Connection ; javax . jms . ConnectionFactory ; javax . jms . MessageProducer ; javax . jms . Queue ; javax . jms . Session ; javax . jms . TextMessage ; javax . naming . InitialContext ;

public class EnviaNovoPedidoGlassfish { public static void main ( String [] args ) throws Exception { // servio de nomes - JNDI Properties props = new Properties () ; props . setProperty ( " java . naming . factory . initial " , " com . sun . enterprise . naming . SerialInitContextFactory " ) ;

22

www.k19.com.br

23
21 22 23 24 25 26 27 28 29 3 31 32 33 34 35 36 37 38 39 4 41 42 43 44 45 46 47 48 49 5 51 52 53 54 55 56 57 58 59 6 61 } 62 } props . setProperty ( " java . naming . factory . url . pkgs " , " com . sun . enterprise . naming " ) ; props . setProperty ( " java . naming . factory . state " , " com . sun . corba . ee . impl . presentation . rmi . JNDIStateFactoryImpl " ) ; InitialContext ic = new InitialContext ( props ) ; // 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 2 l - " + System . currentTimeMillis () ) ; // enviando sender . send ( message ) ; // fechando sender . close () ; session . close () ; connection . close () ; System . out . println ( " Mensagem Enviada " ) ; System . exit ( ) ;

JMS

Cdigo Java 1.11: EnviaNovoPedidoGlasssh.java

14

Pare o JBoss. Inicie o Glasssh. Execute uma vez a classe EnviaNovoPedidoGlasssh.

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.
15

www.facebook.com/k19treinamentos

23

JMS

24

24

www.k19.com.br

25

JMS

www.facebook.com/k19treinamentos

25

JMS

26

26

www.k19.com.br

27

JMS

16

Crie um pacote chamado br.com.k19.receptores no projeto receptorJMS.

Adicione no pacote br.com.k19.receptores uma classe com main para receber uma mensagem JMS da la pedidos do Glasssh.
17

1 2 3 4 5 6 7 8 9 1 11 12 13 14 15

package br . com . k19 . receptores ; import java . util . Properties ; import import import import import import import javax . jms . Connection ; javax . jms . ConnectionFactory ; javax . jms . MessageConsumer ; javax . jms . Queue ; javax . jms . Session ; javax . jms . TextMessage ; javax . naming . InitialContext ;

public class RecebePedidoGlassfish { public static void main ( String [] args ) throws Exception { // servio de nomes - JNDI

www.facebook.com/k19treinamentos

27

JMS
16 17 18 19 2 21 22 23 24 25 26 27 28 29 3 31 32 33 34 35 36 37 38 39 4 41 42 43 44 45 46 47 48 49 5 51 52 53 54 55 56 57 58 59 6 61 } 62 } Properties props = new Properties () ; props . setProperty ( " java . naming . factory . initial " , " com . sun . enterprise . naming . SerialInitContextFactory " ) ; props . setProperty ( " java . naming . factory . url . pkgs " , " com . sun . enterprise . naming " ) ; props . setProperty ( " java . naming . factory . state " , " com . sun . corba . ee . impl . presentation . rmi . JNDIStateFactoryImpl " ) ; InitialContext ic = new InitialContext ( props ) ; // 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 ( ) ;

28

Cdigo Java 1.12: RecebePedidoGlasssh.java

18

Execute uma vez a classe RecebePedidoGlasssh.

Adicione no pacote br.com.k19.receptores uma classe com main para receber uma mensagem JMS do tpico noticias do Glasssh.
19

1 2 3 4 5 6 7 8 9 1

package br . com . k19 . receptores ; import java . util . Properties ; import import import import import import javax . jms . Connection ; javax . jms . ConnectionFactory ; javax . jms . MessageConsumer ; javax . jms . Session ; javax . jms . TextMessage ; javax . jms . Topic ;

28

www.k19.com.br

29
11 import javax . naming . InitialContext ; 12 13 public class AssinanteDeNoticiasGlassfish { 14 public static void main ( String [] args ) throws Exception { 15 // servio de nomes - JNDI 16 Properties props = new Properties () ; 17 18 props . setProperty ( " java . naming . factory . initial " , 19 " com . sun . enterprise . naming . SerialInitContextFactory " ) ; 2 21 props . setProperty ( " java . naming . factory . url . pkgs " , 22 " com . sun . enterprise . naming " ) ; 23 24 props . setProperty ( " java . naming . factory . state " , 25 " com . sun . corba . ee . impl . presentation . rmi . JNDIStateFactoryImpl " ) ; 26 27 InitialContext ic = new InitialContext ( props ) ; 28 29 // fbrica de conexes JMS 3 ConnectionFactory factory = ( ConnectionFactory ) ic 31 . lookup ( " jms / K19Factory " ) ; 32 33 // tpico 34 Topic topic = ( Topic ) ic . lookup ( " jms / noticias " ) ; 35 36 // conexo JMS 37 Connection connection = factory . createConnection () ; 38 39 // sesso JMS 4 Session session = connection . createSession ( false , 41 Session . AUTO_ACKNOWLEDGE ) ; 42 43 // receptor de mensagens 44 MessageConsumer receiver = session . createConsumer ( topic ) ; 45 46 // inicializa conexo 47 connection . start () ; 48 49 // recebendo 5 TextMessage message = ( TextMessage ) receiver . receive () ; 51 52 System . out . println ( message . getText () ) ; 53 54 // fechando 55 receiver . close () ; 56 session . close () ; 57 connection . close () ; 58 59 System . out . println ( " FIM " ) ; 6 System . exit ( ) ; 61 } 62 }
Cdigo Java 1.13: AssinanteDeNoticiasGlasssh.java

JMS

20

Execute duas vez a classe AssinanteDeNoticiasGlasssh.

Adicione no pacote br.com.k19.emissores uma classe com main para enviar uma mensagem JMS para o tpico noticias do Glasssh.
21

1 package br . com . k19 . emissores ; 2 3 import java . util . Properties ; 4 5 import javax . jms . Connection ;

www.facebook.com/k19treinamentos

29

JMS
6 7 8 9 1 11 12 13 14 15 16 17 18 19 2 21 22 23 24 25 26 27 28 29 3 31 32 33 34 35 36 37 38 39 4 41 42 43 44 45 46 47 48 49 5 51 52 53 54 55 56 57 58 59 6 61 62 import import import import import import javax . jms . ConnectionFactory ; javax . jms . MessageProducer ; javax . jms . Session ; javax . jms . TextMessage ; javax . jms . Topic ; javax . naming . InitialContext ;

30

public class EnviaNoticiaGlassfish { public static void main ( String [] args ) throws Exception { // servio de nomes - JNDI Properties props = new Properties () ; props . setProperty ( " java . naming . factory . initial " , " com . sun . enterprise . naming . SerialInitContextFactory " ) ; props . setProperty ( " java . naming . factory . url . pkgs " , " com . sun . enterprise . naming " ) ; props . setProperty ( " java . naming . factory . state " , " com . sun . corba . ee . impl . presentation . rmi . JNDIStateFactoryImpl " ) ; InitialContext ic = new InitialContext ( props ) ; // 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 2 14 ser no Brasil - " + System . currentTimeMillis () ) ; // enviando sender . send ( message ) ; // fechando sender . close () ; session . close () ; connection . close () ; System . out . println ( " Mensagem Enviada " ) ; System . exit ( ) ; } }
Cdigo Java 1.14: EnviaNoticiaGlasssh.java

22

Execute uma vez a classe EnviaNoticiaGlasssh e observe os consoles dos assinantes.

Adicione no pacote br.com.k19.emissores uma classe com main para enviar uma mensagem JMS para a la pedidos do JBoss.
23

30

www.k19.com.br

31
1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 16 17 18 19 2 21 22 23 24 25 26 27 28 29 3 31 32 33 34 35 36 37 38 39 4 41 42 43 44 45 46 47 48 49 5 51 52 53 54 55 56 57 58 59 6 61 62 63 64 package br . com . k19 . emissores ; import java . util . Properties ; import import import import import import import import javax . jms . Connection ; javax . jms . ConnectionFactory ; javax . jms . MessageProducer ; javax . jms . Queue ; javax . jms . Session ; javax . jms . TextMessage ; javax . naming . Context ; javax . naming . InitialContext ;

JMS

public class EnviaNovoPedidoJBoss { public static void main ( String [] args ) throws Exception { // servio de nomes - JNDI Properties props = new Properties () ; props . setProperty ( " java . naming . factory . initial " , " org . jboss . naming . remote . client . InitialContextFactory " ) ; props . setProperty ( " java . naming . provider . url " , " remote :// localhost :4447 " ) ; props . setProperty ( " java . naming . security . principal " , " k19 " ) ; props . setProperty ( " java . naming . security . credentials " , " 1234 " ) ; InitialContext ic = new InitialContext ( props ) ; // fbrica de conexes JMS ConnectionFactory factory = ( ConnectionFactory ) ic . lookup ( " jms / K19Factory " ) ; // fila Queue queue = ( Queue ) ic . lookup ( " jms / queue / pedidos " ) ; // conexo JMS Connection connection = factory . createConnection ( " k19 " , " 1234 " ) ; // 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 2 l - " + System . currentTimeMillis () ) ; // enviando sender . send ( message ) ; // fechando sender . close () ; session . close () ; connection . close () ; System . out . println ( " Mensagem Enviada " ) ; System . exit ( ) ; } }

Cdigo Java 1.15: EnviaNovoPedidoJBoss.java

www.facebook.com/k19treinamentos

31

JMS
24

32

Pare o Glassh. Inicie o JBoss. Execute uma vez a classe EnviaNovoPedidoJBoss.

Adicione no pacote br.com.k19.receptores uma classe com main para receber uma mensagem JMS da la pedidos do JBoss.
25

1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 16 17 18 19 2 21 22 23 24 25 26 27 28 29 3 31 32 33 34 35 36 37 38 39 4 41 42 43 44 45 46 47 48 49 5 51 52 53 54 55 56 57 58 59 6 61 62

package br . com . k19 . receptores ; import java . util . Properties ; import import import import import import import javax . jms . Connection ; javax . jms . ConnectionFactory ; javax . jms . MessageConsumer ; javax . jms . Queue ; javax . jms . Session ; javax . jms . TextMessage ; javax . naming . InitialContext ;

public class RecebePedidoJBoss { public static void main ( String [] args ) throws Exception { // servio de nomes - JNDI Properties props = new Properties () ; props . setProperty ( " java . naming . factory . initial " , " org . jboss . naming . remote . client . InitialContextFactory " ) ; props . setProperty ( " java . naming . provider . url " , " remote :// localhost :4447 " ) ; props . setProperty ( " java . naming . security . principal " , " k19 " ) ; props . setProperty ( " java . naming . security . credentials " , " 1234 " ) ; InitialContext ic = new InitialContext ( props ) ; // fbrica de conexes JMS ConnectionFactory factory = ( ConnectionFactory ) ic . lookup ( " jms / K19Factory " ) ; // fila Queue queue = ( Queue ) ic . lookup ( " jms / queue / pedidos " ) ; // conexo JMS Connection connection = factory . createConnection ( " k19 " , " 1234 " ) ; // 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 ( ) ; } }

32

www.k19.com.br

33

JMS

Cdigo Java 1.16: RecebePedidoJBoss.java

26

Execute uma vez a classe RecebePedidoJBoss.

Adicione no pacote br.com.k19.receptores uma classe com main para receber uma mensagem JMS do tpico noticias do JBoss.
27

1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 16 17 18 19 2 21 22 23 24 25 26 27 28 29 3 31 32 33 34 35 36 37 38 39 4 41 42 43 44 45 46 47 48 49 5 51 52 53 54 55 56

package br . com . k19 . receptores ; import java . util . Properties ; import import import import import import import javax . jms . Connection ; javax . jms . ConnectionFactory ; javax . jms . MessageConsumer ; javax . jms . Session ; javax . jms . TextMessage ; javax . jms . Topic ; javax . naming . InitialContext ;

public class AssinanteDeNoticiasJBoss { public static void main ( String [] args ) throws Exception { // servio de nomes - JNDI Properties props = new Properties () ; props . setProperty ( " java . naming . factory . initial " , " org . jboss . naming . remote . client . InitialContextFactory " ) ; props . setProperty ( " java . naming . provider . url " , " remote :// localhost :4447 " ) ; props . setProperty ( " java . naming . security . principal " , " k19 " ) ; props . setProperty ( " java . naming . security . credentials " , " 1234 " ) ; InitialContext ic = new InitialContext ( props ) ; // fbrica de conexes JMS ConnectionFactory factory = ( ConnectionFactory ) ic . lookup ( " jms / K19Factory " ) ; // tpico Topic topic = ( Topic ) ic . lookup ( " jms / topic / noticias " ) ; // conexo JMS Connection connection = factory . createConnection ( " k19 " , " 1234 " ) ; // sesso JMS Session session = connection . createSession ( false , 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 () ;

www.facebook.com/k19treinamentos

33

JMS
57 connection . close () ; 58 59 System . out . println ( " FIM " ) ; 6 System . exit ( ) ; 61 } 62 }
Cdigo Java 1.17: AssinanteDeNoticiasJBoss.java

34

28

Execute duas vez a classe AssinanteDeNoticiasJBoss.

Adicione no pacote br.com.k19.emissores uma classe com main para enviar uma mensagem JMS para o tpico noticias do JBoss.
29

1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 16 17 18 19 2 21 22 23 24 25 26 27 28 29 3 31 32 33 34 35 36 37 38 39 4 41 42 43 44 45 46 47 48 49 5 51

package br . com . k19 . emissores ; import java . util . Properties ; import import import import import import import javax . jms . Connection ; javax . jms . ConnectionFactory ; javax . jms . MessageProducer ; javax . jms . Session ; javax . jms . TextMessage ; javax . jms . Topic ; javax . naming . InitialContext ;

public class EnviaNoticiaJBoss { public static void main ( String [] args ) throws Exception { // servio de nomes - JNDI Properties props = new Properties () ; props . setProperty ( " java . naming . factory . initial " , " org . jboss . naming . remote . client . InitialContextFactory " ) ; props . setProperty ( " java . naming . provider . url " , " remote :// localhost :4447 " ) ; props . setProperty ( " java . naming . security . principal " , " k19 " ) ; props . setProperty ( " java . naming . security . credentials " , " 1234 " ) ; InitialContext ic = new InitialContext ( props ) ; // fbrica de conexes JMS ConnectionFactory factory = ( ConnectionFactory ) ic . lookup ( " jms / K19Factory " ) ; // tpico Topic topic = ( Topic ) ic . lookup ( " jms / topic / noticias " ) ; // conexo JMS Connection connection = factory . createConnection ( " k19 " , " 1234 " ) ; // 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 2 14 ser no Brasil - " + System . currentTimeMillis () ) ; // enviando

34

www.k19.com.br

35
52 53 54 55 56 57 58 59 6 61 } 62 } sender . send ( message ) ; // fechando sender . close () ; session . close () ; connection . close () ; System . out . println ( " Mensagem Enviada " ) ; System . exit ( ) ;

JMS

Cdigo Java 1.18: EnviaNoticiaJBoss.java

30

Execute uma vez a classe EnviaNoticiaJBoss e observe os consoles dos assinantes.

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 // espera no mximo 5 segundos 2 receiver . receive (5 );

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


1 receiver . receiveNoWait () ;

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 () ; }

Exerccios de Fixao
www.facebook.com/k19treinamentos

35

JMS

36

Adicione no pacote br.com.k19.receptores uma classe com main para percorrer as mensagens da la pedidos do Glasssh.
31

1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 16 17 18 19 2 21 22 23 24 25 26 27 28 29 3 31 32 33 34 35 36 37 38 39 4 41 42 43 44 45 46 47 48 49 5 51 52 53 54 55 56 57 58 59 6 61 62 63

package br . com . k19 . receptores ; import java . util . Enumeration ; import java . util . Properties ; import import import import import import import javax . jms . Connection ; javax . jms . ConnectionFactory ; javax . jms . Queue ; javax . jms . QueueBrowser ; javax . jms . Session ; javax . jms . TextMessage ; javax . naming . InitialContext ;

public class PercorrendoFilaGlassfish { public static void main ( String [] args ) throws Exception { // servio de nomes - JNDI Properties props = new Properties () ; props . setProperty ( " java . naming . factory . initial " , " com . sun . enterprise . naming . SerialInitContextFactory " ) ; props . setProperty ( " java . naming . factory . url . pkgs " , " com . sun . enterprise . naming " ) ; props . setProperty ( " java . naming . factory . state " , " com . sun . corba . ee . impl . presentation . rmi . JNDIStateFactoryImpl " ) ; InitialContext ic = new InitialContext ( props ) ; // 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 ) ; // 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 ( ) ; }

36

www.k19.com.br

37
64 }
Cdigo Java 1.23: PercorrendoFilaGlasssh.java

JMS

32 Pare o JBoss. Inicie o Glasssh. Execute algumas vezes a classe EnviaNovoPedidoGlasssh para popular a la pedidos do Glasssh e depois execute a classe PercorrendoFilaGlasssh.

Adicione no pacote br.com.k19.receptores uma classe com main para percorrer as mensagens da la pedidos do JBoss.
33

1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 16 17 18 19 2 21 22 23 24 25 26 27 28 29 3 31 32 33 34 35 36 37 38 39 4 41 42 43 44 45 46 47 48 49 5 51 52 53 54

package br . com . k19 . receptores ; import java . util . Enumeration ; import java . util . Properties ; import import import import import import import javax . jms . Connection ; javax . jms . ConnectionFactory ; javax . jms . Queue ; javax . jms . QueueBrowser ; javax . jms . Session ; javax . jms . TextMessage ; javax . naming . InitialContext ;

public class PercorrendoFilaJBoss { public static void main ( String [] args ) throws Exception { // servio de nomes - JNDI Properties props = new Properties () ; props . setProperty ( " java . naming . factory . initial " , " org . jboss . naming . remote . client . InitialContextFactory " ) ; props . setProperty ( " java . naming . provider . url " , " remote :// localhost :4447 " ) ; props . setProperty ( " java . naming . security . principal " , " k19 " ) ; props . setProperty ( " java . naming . security . credentials " , " 1234 " ) ; InitialContext ic = new InitialContext ( props ) ; // fbrica de conexes JMS ConnectionFactory factory = ( ConnectionFactory ) ic . lookup ( " jms / K19Factory " ) ; // fila Queue queue = ( Queue ) ic . lookup ( " jms / queue / pedidos " ) ; // conexo JMS Connection connection = factory . createConnection ( " k19 " , " 1234 " ) ; // sesso JMS Session session = connection . createSession ( false , Session . AUTO_ACKNOWLEDGE ) ; // 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 ++; }

www.facebook.com/k19treinamentos

37

JMS
55 56 57 58 59 6 61 62 63 } 64 }

38

// fechando queueBrowser . close () ; session . close () ; connection . close () ; System . out . println ( " FIM " ) ; System . exit ( ) ;

Cdigo Java 1.24: PercorrendoFilaJBoss.java

Pare o Glasssh. Inicie o JBoss. Execute algumas vezes a classe EnviaNovoPedidoJBoss para popular a la pedidos do JBoss e depois execute a classe PercorrendoFilaJBoss.
34

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 ) " ) ;

Exerccios de Fixao

Altere a classe AssinanteDeNoticiasGlasssh para selecionar somente as mensagens de esporte. Observe o trecho de cdigo que voc deve alterar:
35

1 // receptor de mensagens 2 MessageConsumer receiver = session . createConsumer ( topic , " ( categoria = esporte ) " ) ;

Altere a classe EnviaNoticiaGlasssh acrescentando uma propriedade mensagem enviada. Observe o trecho de cdigo que voc deve alterar:
36

1 2 3 4 5

// mensagem TextMessage message = session . createTextMessage () ; message . setStringProperty ( " categoria " , " esporte " ) ; message . setText ( " A copa do mundo de 2 14 ser no Brasil - " + System . currentTimeMillis () ) ;

38

www.k19.com.br

39
37

JMS

Pare o JBoss. Inicie o Glasssh. Execute uma vez a classe AssinanteDeNoticiasGlasssh e depois a classe EnviaNoticiaGlasssh. Observe que a mensagem recebida pelo assinante.

38

Altere o valor da propriedade da mensagem enviada.


// mensagem TextMessage message = session . createTextMessage () ; message . setStringProperty ( " categoria " , " geral " ) ; message . setText ( " A copa do mundo de 2 14 ser no Brasil - " + System . currentTimeMillis () ) ;

1 2 3 4 5

39 Execute uma vez a classe EnviaNoticiaGlasssh. Observe que agora a mensagem no recebida pelo assinante.

Altere a classe AssinanteDeNoticiasJBoss para selecionar somente as mensagens de esporte. Observe o trecho de cdigo que voc deve alterar:
40

1 // receptor de mensagens 2 MessageConsumer receiver = session . createConsumer ( topic , " ( categoria = esporte ) " ) ;

41 Altere a classe EnviaNoticiaJBoss acrescentando uma propriedade mensagem enviada. Observe o trecho de cdigo que voc deve alterar:

1 2 3 4 5

// mensagem TextMessage message = session . createTextMessage () ; message . setStringProperty ( " categoria " , " esporte " ) ; message . setText ( " A copa do mundo de 2 14 ser no Brasil - " + System . currentTimeMillis () ) ;

Pare o Glasssh. Inicie o JBoss. Execute uma vez a classe AssinanteDeNoticiasJBoss e depois a classe EnviaNoticiaJBoss. Observe que a mensagem recebida pelo assinante.
42

43

Altere o valor da propriedade da mensagem enviada.


// mensagem TextMessage message = session . createTextMessage () ; message . setStringProperty ( " categoria " , " geral " ) ; message . setText ( " A copa do mundo de 2 14 ser no Brasil - " + System . currentTimeMillis () ) ;

1 2 3 4 5

Execute uma vez a classe EnviaNoticiaJBoss. Observe que agora a mensagem no recebida pelo assinante.
44

Tpicos Durveis

www.facebook.com/k19treinamentos

39

JMS

40

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.

Exerccios de Fixao

Pare o JBoss. Inicie o Glasssh. Crie uma fbrica para tpicos durveis atravs da interface de administrao do Glasssh seguindo exatamente os passos das imagens abaixo:
45

40

www.k19.com.br

41

JMS

www.facebook.com/k19treinamentos

41

JMS

42

46 Adicione no pacote br.com.k19.receptores uma classe com main para receber uma mensagem JMS do tpico noticias do Glasssh inclusive as enviadas enquanto a aplicao estiver off-line.

1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 16 17 18 19 2 21 22 23 24 25 26 27 28 29 3 31 32 33 34

package br . com . k19 . receptores ; import java . util . Properties ; import import import import import import import javax . jms . Connection ; javax . jms . ConnectionFactory ; javax . jms . MessageConsumer ; javax . jms . Session ; javax . jms . TextMessage ; javax . jms . Topic ; javax . naming . InitialContext ;

public class AssinanteDuravelGlassfish { public static void main ( String [] args ) throws Exception { // servio de nomes - JNDI Properties props = new Properties () ; props . setProperty ( " java . naming . factory . initial " , " com . sun . enterprise . naming . SerialInitContextFactory " ) ; props . setProperty ( " java . naming . factory . url . pkgs " , " com . sun . enterprise . naming " ) ; props . setProperty ( " java . naming . factory . state " , " com . sun . corba . ee . impl . presentation . rmi . JNDIStateFactoryImpl " ) ; InitialContext ic = new InitialContext ( props ) ; // fbrica de conexes JMS ConnectionFactory factory = ( ConnectionFactory ) ic . lookup ( " jms / K19DurableFactory " ) ; // tpico Topic topic = ( Topic ) ic . lookup ( " jms / noticias " ) ;

42

www.k19.com.br

43
35 36 37 38 39 4 41 42 43 44 45 46 47 48 49 5 51 52 53 54 55 56 57 58 59 6 61 62 63 64 65 } 66 }

JMS

// 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 (2 while ( message != null ) { System . out . println ( message . getText () ) ; message = ( TextMessage ) receiver . receive (2 } // fechando receiver . close () ; session . close () ; connection . close () ; System . out . println ( " FIM " ) ; System . exit ( ) ;

);

);

Cdigo Java 1.33: AssinanteDuravelGlasssh.java

Adicione no pacote br.com.k19.emissores uma classe com main para enviar uma mensagem JMS durvel para o tpico noticias do Glasssh.
47

1 public class EnviaNoticiaDuravelGlassfish { 2 public static void main ( String [] args ) throws Exception { 3 // servio de nomes - JNDI 4 InitialContext ic = new InitialContext () ; 5 6 // fbrica de conexes JMS 7 ConnectionFactory factory = 8 ( ConnectionFactory ) ic . lookup ( " jms / K19DurableFactory " ) ; 9 1 // tpico 11 Topic topic = ( Topic ) ic . lookup ( " jms / noticias " ) ; 12 13 // conexo JMS 14 Connection connection = factory . createConnection () ; 15 16 // sesso JMS 17 Session session = connection . createSession ( false , Session . AUTO_ACKNOWLEDGE ) ; 18 19 // emissor de mensagens 2 MessageProducer sender = session . createProducer ( topic ) ; 21 22 // mensagem 23 TextMessage message = session . createTextMessage () ; 24 message . setText ( " A copa do mundo de 2 14 ser no Brasil - " + 25 System . currentTimeMillis () ) ; 26 27 // enviando 28 sender . send ( message ) ; 29

www.facebook.com/k19treinamentos

43

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

44

Cdigo Java 1.34: EnviaNoticiaDuravelGlasssh.java

48

Execute uma vez a classe AssinanteDuravelGlasssh para cadastrar um assinante.

Execute algumas vezes a classe EnviaNoticiaDuravelGlasssh. Perceba que o assinante est ofine.
49

Execute a classe AssinanteDuravelGlasssh para receber as mensagens enviadas enquanto o assinante estava ofine.
50

Pare o Glasssh. Inicie o JBoss. Altere as conguraes do JBoss para criar assinantes durveis.Para isso modique o arquivo de congurao standalone-full.xml. Voc encontra esse arquivo na pasta jboss-as-7.1.1.Final/standalone/conguration.
51

1 2 3 4 5 6 7 8 9

... < security - settings > < security - setting match = " # " > < permission type = " createDurableQueue " roles = " guest " / > < permission type = " deleteDurableQueue " roles = " guest " / > ... </ security - setting > </ security - settings > ...
Cdigo XML 1.3: standalone-full.xml

Adicione no pacote br.com.k19.receptores uma classe com main para receber uma mensagem JMS do tpico noticias do JBoss inclusive as enviadas enquanto a aplicao estiver off-line.
52

1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 16 17 18

package br . com . k19 . receptores ; import java . util . Properties ; import import import import import import import javax . jms . Connection ; javax . jms . ConnectionFactory ; javax . jms . MessageConsumer ; javax . jms . Session ; javax . jms . TextMessage ; javax . jms . Topic ; javax . naming . InitialContext ;

public class AssinanteDuravelJBoss { public static void main ( String [] args ) throws Exception { // servio de nomes - JNDI Properties props = new Properties () ; props . setProperty ( " java . naming . factory . initial " ,

44

www.k19.com.br

45
19 2 21 22 23 24 25 26 27 28 29 3 31 32 33 34 35 36 37 38 39 4 41 42 43 44 45 46 47 48 49 5 51 52 53 54 55 56 57 58 59 6 61 62 63 64 65 66 } 67 } " org . jboss . naming . remote . client . InitialContextFactory " ) ; props . setProperty ( " java . naming . provider . url " , " remote :// localhost :4447 " ) ; props . setProperty ( " java . naming . security . principal " , " k19 " ) ; props . setProperty ( " java . naming . security . credentials " , " 1234 " ) ; InitialContext ic = new InitialContext ( props ) ; // fbrica de conexes JMS ConnectionFactory factory = ( ConnectionFactory ) ic . lookup ( " jms / K19Factory " ) ; // tpico Topic topic = ( Topic ) ic . lookup ( " jms / topic / noticias " ) ; // conexo JMS Connection connection = factory . createConnection ( " k19 " , " 1234 " ) ; connection . setClientID ( " k19 " ) ; // sesso JMS Session session = connection . createSession ( false , Session . AUTO_ACKNOWLEDGE ) ; // receptor de mensagens MessageConsumer receiver = session . createDurableSubscriber ( topic , " k19 " ) ; // inicializa conexo connection . start () ; // recebendo TextMessage message = ( TextMessage ) receiver . receive (2 while ( message != null ) { System . out . println ( message . getText () ) ; message = ( TextMessage ) receiver . receive (2 } // fechando receiver . close () ; session . close () ; connection . close () ; System . out . println ( " FIM " ) ; System . exit ( ) ;

JMS

);

);

Cdigo Java 1.35: AssinanteDuravelJBoss.java

53 Adicione no pacote br.com.k19.emissores uma classe com main para enviar uma mensagem JMS durvel para o tpico noticias do JBoss.

1 2 3 4 5 6 7 8 9 1 11 12

package br . com . k19 . emissores ; import java . util . Properties ; import import import import import import import javax . jms . Connection ; javax . jms . ConnectionFactory ; javax . jms . MessageProducer ; javax . jms . Session ; javax . jms . TextMessage ; javax . jms . Topic ; javax . naming . InitialContext ;

www.facebook.com/k19treinamentos

45

JMS
13 public class EnviaNoticiaDuravelJBoss { 14 public static void main ( String [] args ) throws Exception { 15 // servio de nomes - JNDI 16 Properties props = new Properties () ; 17 18 props . setProperty ( " java . naming . factory . initial " , 19 " org . jboss . naming . remote . client . InitialContextFactory " ) ; 2 21 props . setProperty ( " java . naming . provider . url " , " remote :// localhost :4447 " ) ; 22 23 props . setProperty ( " java . naming . security . principal " , " k19 " ) ; 24 25 props . setProperty ( " java . naming . security . credentials " , " 1234 " ) ; 26 27 InitialContext ic = new InitialContext ( props ) ; 28 29 // fbrica de conexes JMS 3 ConnectionFactory factory = ( ConnectionFactory ) ic 31 . lookup ( " jms / K19Factory " ) ; 32 33 // tpico 34 Topic topic = ( Topic ) ic . lookup ( " jms / topic / noticias " ) ; 35 36 // conexo JMS 37 Connection connection = factory . createConnection ( " k19 " , " 1234 " ) ; 38 39 // sesso JMS 4 Session session = connection . createSession ( false , 41 Session . AUTO_ACKNOWLEDGE ) ; 42 43 // emissor de mensagens 44 MessageProducer sender = session . createProducer ( topic ) ; 45 46 // mensagem 47 TextMessage message = session . createTextMessage () ; 48 message . setText ( " A copa do mundo de 2 14 ser no Brasil - " 49 + System . currentTimeMillis () ) ; 5 51 // enviando 52 sender . send ( message ) ; 53 54 // fechando 55 sender . close () ; 56 session . close () ; 57 connection . close () ; 58 59 System . out . println ( " Mensagem Enviada " ) ; 6 System . exit ( ) ; 61 } 62 }
Cdigo Java 1.36: EnviaNoticiaDuravelJBoss.java

46

54

Execute uma vez a classe AssinanteDuravelJBoss para cadastrar um assinante.

55

Execute algumas vezes a classe EnviaNoticiaDuravelJBoss. Perceba que o assinante est ofine.

Execute a classe AssinanteDuravelJBoss para receber as mensagens enviadas enquanto o assinante estava ofine.
56

JMS e EJB
46
www.k19.com.br

47

JMS

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 @MessageDriven ( mappedName = " jms / destination1 " ) 2 public class TratadorDeMensagensMDB implements MessageListener { 3 4 @Override 5 public void onMessage ( Message message ) { 6 7 try { 8 TextMessage msg = ( TextMessage ) message ; 9 System . out . println ( msg . getText () ) ; 1 } catch ( JMSException e ) { 11 System . out . println ( " erro " ) ; 12 } 13 } 14 }

Cdigo Java 1.37: TratadorDeMensagensMDB.java

Exerccios de Fixao

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

www.facebook.com/k19treinamentos

47

JMS

48

58

Crie um pacote chamado br.com.k19.mdbs no projeto receptorJMS-EJB.

Adicione no pacote br.com.k19.mdbs um Message Driven Bean para receber e processar as mensagens do tpico noticias do Glasssh.
59

1 2 3 4 5 6 7 8

package br . com . k19 . mdbs ; import import import import import import javax . ejb . ActivationConfigProperty ; javax . ejb . MessageDriven ; javax . jms . JMSException ; javax . jms . Message ; javax . jms . MessageListener ; javax . jms . TextMessage ;

48

www.k19.com.br

49
9 1 @MessageDriven ( mappedName = " jms / noticias " ) 11 public class TratadorDeMensagensMDB implements MessageListener { 12 13 @Override 14 public void onMessage ( Message message ) { 15 16 try { 17 TextMessage msg = ( TextMessage ) message ; 18 System . out . println ( msg . getText () ) ; 19 } catch ( JMSException e ) { 2 System . out . println ( " erro " ) ; 21 } 22 } 23 }
Cdigo Java 1.38: TratadorDeMensagensMDB.java

JMS

60

Implante o projeto receptorJMS-EJB no Glasssh atravs da view Servers.

Pare o JBoss. Inicie o Glasssh. Envie uma mensagem para o tpico EnviaNoticiaGlasssh e observe o console do eclipse.
61

62 Altere a classe TratadorDeMensagensMDB para receber e processar as mensagens do tpico noticias do JBoss.

1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 16 17 18 19 2 21 22 23 24 25 26 27 28 29 3

package br . com . k19 . mdbs ; import import import import import import javax . ejb . ActivationConfigProperty ; javax . ejb . MessageDriven ; javax . jms . JMSException ; javax . jms . Message ; javax . jms . MessageListener ; javax . jms . TextMessage ;

@MessageDriven ( activationConfig = { @ActivationConfigProperty ( propertyName = " destination " , propertyValue = " jms / topic / noticias " ) , @ActivationConfigProperty ( propertyName = " destinationType " , propertyValue = " javax . jms . Topic " ) }) public class TratadorDeMensagensMDB implements MessageListener { @Override public void onMessage ( Message message ) { try { TextMessage msg = ( TextMessage ) message ; System . out . println ( msg . getText () ) ; } catch ( JMSException e ) { System . out . println ( " erro " ) ; } } }
Cdigo Java 1.39: TratadorDeMensagensMDB.java

63

Implante o projeto receptorJMS-EJB no JBoss atravs da view Servers.


www.facebook.com/k19treinamentos

49

JMS
64

50

Pare o Glasssh. Inicie o JBoss. Envie uma mensagem para o tpico EnviaNoticiaJBoss e observe o console do eclipse.

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.

Exerccios de Fixao

65

Adicione uma la com o seguinte JNDI Name jms/pagamentos no Glasssh.

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.
66

1 // DICA 2 Scanner entrada = new Scanner ( System . in ) ; 3 String linha = entrada . nextLine () ;

67 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.

68 (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.

50

www.k19.com.br

CAPTULO

JAX-WS

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. A seguir mostraremos o funcionamento bsico dos recursos denidos pela especicao JAXB e a arquitetura denida pela JAX-WS.
www.facebook.com/k19treinamentos

51

JAX-WS

52

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 class Conta { 2 private double saldo ; 3 4 private double limite ; 5 6 // GETTERS AND SETTERS 7 }
Cdigo Java 2.1: Conta.java

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

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 Conta e utilizar um Marshaller para serializ-lo em XML e guardar o contedo em um arquivo.
1 2 3 4 5 Conta conta = new Conta () ; conta . setLimite (2 ); conta . setSaldo (2 ); 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 Unmarshaller unmarshaller = context . createUnmarshaller () ; 2

52

www.k19.com.br

53
3 Conta conta = ( Conta ) unmarshaller . unmarshal ( new File ( " conta . xml " ) ) ;

JAX-WS

Exerccios de Fixao

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.
1

Crie um pacote chamado jaxb no projeto jaxb.

Adicione no pacote jaxb uma classe para modelar contas bancrias. Aplique a anotao @XmlRootElement.
3

www.facebook.com/k19treinamentos

53

JAX-WS
1 @XmlRootElement 2 public class Conta { 3 private double saldo ; 4 5 private double limite ; 6 7 // GETTERS AND SETTERS 8 }
Cdigo Java 2.7: Conta.java

54

Adicione no pacote jaxb uma classe com main para serializar um objeto da classe Conta.

1 public class Serializador { 2 public static void main ( String [] args ) throws JAXBException { 3 4 JAXBContext context = JAXBContext . newInstance ( Conta . class ) ; 5 Marshaller marshaller = context . createMarshaller () ; 6 7 Conta conta = new Conta () ; 8 conta . setLimite (2 ); 9 conta . setSaldo (2 ); 1 marshaller . marshal ( conta , new File ( " conta . xml " ) ) ; 11 } 12 }
Cdigo Java 2.8: Serializador.java

Execute a classe Serializador e atualize o projeto para o arquivo conta.xml aparecer. Observe o contedo XML gerado.
5

Adicione no pacote jaxb uma classe com main para deserializar o XML criado anteriormente.

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

Execute a classe Deserializador.

Adicione no pacote jaxb uma classe para modelar os clientes donos das contas bancrias.

1 public class Cliente { 2 private String nome ; 3 4 // GETTERS AND SETTERS

54

www.k19.com.br

55
5 }
Cdigo Java 2.10: Cliente.java

JAX-WS

Altere a classe Conta para estabelecer um vnculo com a classe Cliente.

1 @XmlRootElement 2 public class Conta { 3 private double saldo ; 4 5 private double limite ; 6 7 private Cliente cliente ; 8 9 // GETTERS AND SETTERS 1 }
Cdigo Java 2.11: Conta.java

10

Altere a classe Serializacao e a teste novamente.

1 public class Serializador { 2 public static void main ( String [] args ) throws JAXBException { 3 4 JAXBContext context = JAXBContext . newInstance ( Conta . class ) ; 5 Marshaller marshaller = context . createMarshaller () ; 6 7 Cliente cliente = new Cliente () ; 8 cliente . setNome ( " Rafael Cosentino " ) ; 9 1 Conta conta = new Conta () ; 11 conta . setLimite (2 ); 12 conta . setSaldo (2 ); 13 conta . setCliente ( cliente ) ; 14 15 marshaller . marshal ( conta , new File ( " conta . xml " ) ) ; 16 } 17 }
Cdigo Java 2.12: Serializador.java

11

Altere a classe Deserializacao e a teste novamente.

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

www.facebook.com/k19treinamentos

55

JAX-WS

56

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 class Gerador { 2 public double geraNumero () { 3 return Math . random () * 2 ; 4 } 5 }
Cdigo Java 2.14: Gerador.java

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

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

A denio do web service em WSDL pode ser consultada atravs da url http://localhost:

8 8 /gerador?wsdl.

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 :8 8 / gerador ? wsdl

Com o apoio das classes geradas pelo wsimport podemos consumir o web service.
56
www.k19.com.br

57
1 public class Consumidor { 2 public static void main ( String [] args ) { 3 // Servio 4 GeradorDeNumerosService service = new GeradorDeNumerosService () ; 5 6 // Proxy 7 GeradorDeNumeros proxy = service . getGeradorDeNumerosPort () ; 8 9 // Consumindo 1 double numero = proxy . geraNumero () ; 11 12 System . out . println ( numero ) ; 13 } 14 }

JAX-WS

Cdigo Java 2.18: Consumidor.java

Exerccios de Fixao

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.
12

www.facebook.com/k19treinamentos

57

JAX-WS

58

13

Crie um pacote chamado webservices no projeto random.

Adicione no pacote webservices uma classe para implementar o servio de gerar nmeros aleatrios.
14

1 @WebService 2 public class Random { 3 public double next ( double max ) { 4 return Math . random () * max ; 5 } 6 }
Cdigo Java 2.19: Random.java

15

Adicione no pacote webservices uma classe com main para publicar o web service.

58

www.k19.com.br

59
1 public class RandomPublisher { 2 public static void main ( String [] args ) { 3 System . out . println ( " Random web service start ... " ) ; 4 Random random = new Random () ; 5 Endpoint . publish ( " http :// localhost :8 8 / random " , random ) ; 6 } 7 }

JAX-WS

Cdigo Java 2.20: RandomPublisher.java

16

Execute a classe RandomPublisher.

Consulte atravs de um navegador a url http://localhost:8 8 /random?wsdl para conferir a denio do web service em WSDL.
17

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.
18

www.facebook.com/k19treinamentos

59

JAX-WS

60

19 Gere as classes necessrias para consumir o web service atravs da ferramenta wsimport. Abra um terminal e siga os passos abaixo.
cosen@k19 :~/ workspace / randomClient / src$ wsimport - keep http :// localhost :8 8 / random ? wsdl parsing WSDL ... generating code ... compiling code ... cosen@k19 :~/ workspace / randomClient / src$

Terminal 2.1: wsimport

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

21

Adicione no pacote webservices do projeto randomClient uma classe para consumir o servio
www.k19.com.br

60

61

JAX-WS

de gerar nmeros aleatrios.


1 public class Consumer { 2 public static void main ( String [] args ) { 3 // service 4 RandomService randomService = new RandomService () ; 5 6 // proxy 7 Random proxy = randomService . getRandomPort () ; 8 9 // operation 1 double next = proxy . next (5 ) ; 11 System . out . println ( next ) ; 12 } 13 }
Cdigo Java 2.21: Consumer.java

22

Implemente outro consumidor s que agora em Ruby. Abra um terminal e siga os passos abaixo.
cosen@k19 :$ irb1 .8 irb ( main ): 1: > require soap / wsdlDriver => true irb ( main ): 2: > wsdl = http :// localhost :8 8 / random ? wsdl => " http :// localhost :8 8 / random ? wsdl " irb ( main ): 3: > proxy = SOAP :: WSDLDriverFactory . new ( wsdl ). create_rpc_driver ignored attr : {} version => #< SOAP :: RPC :: Driver :# < SOAP :: RPC :: Proxy : http :// localhost :8 8 / random > > irb ( main ): 4: > proxy . next (: arg = > 5 ). return => "22.998 548624178"

Terminal 2.2: irb

Autenticao
As especicaes WSDL e SOAP no denem como o processo de autenticao deve ser realizado nos Big Webservices. Consequentemente, h diversas abordagens diferentes para tal tarefa. Mostraremos aqui uma soluo que adotada muitos casos. O cliente do servio deve adicionar as informaes necessrias para autenticao nos headers da requisio HTTP .
1 public class Consumer { 2 public static void main ( String [] args ) { 3 // service 4 RandomService randomService = new RandomService () ; 5 6 // proxy 7 Random proxy = randomService . getRandomPort () ; 8 9 // username e password 1 BindingProvider bp = ( BindingProvider ) proxy ; 11 Map < String , List < String > > headers = new HashMap < String , List < String > >() ; 12 headers . put ( " Username " , Collections . singletonList ( " k19 " ) ) ; 13 headers . put ( " Password " , Collections . singletonList ( " k23 " ) ) ; 14 bp . getRequestContext () . put ( MessageContext . HTTP_REQUEST_HEADERS , headers ) ; 15 16 // operation 17 double next = proxy . next (5 ) ; 18 System . out . println ( next ) ; 19 } 2 }

www.facebook.com/k19treinamentos

61

JAX-WS

62

Cdigo Java 2.22: Consumer.java

Depois, essas informaes podem ser obtidas no servio.


1 @WebService 2 public class Random { 3 4 @Resource 5 WebServiceContext wsc ; 6 7 public double next ( double max ) { 8 MessageContext mc = wsc . getMessageContext () ; 9 1 // get detail from request headers 11 Map headers = ( Map ) mc . get ( MessageContext . HTTP_REQUEST_HEADERS ) ; 12 List usernameList = ( List ) headers . get ( " Username " ) ; 13 List passwordList = ( List ) headers . get ( " Password " ) ; 14 15 String username = usernameList != null ? usernameList . get ( ) . toString () : null ; 16 String password = passwordList != null ? passwordList . get ( ) . toString () : null ; 17 18 System . out . println ( username ) ; 19 System . out . println ( password ) ; 2 21 if ( " k19 " . equals ( username ) && " k23 " . equals ( password ) ) { 22 return Math . random () * max ; 23 } else { 24 throw new RuntimeException ( " usurio ou senha incorretos " ) ; 25 } 26 } 27 }
Cdigo Java 2.23: Random.java

Exerccios de Fixao

23

Altere a classe Consumer do projeto randomClient.

1 public class Consumer { 2 public static void main ( String [] args ) { 3 // service 4 RandomService randomService = new RandomService () ; 5 6 // proxy 7 Random proxy = randomService . getRandomPort () ; 8 9 // username e password 1 BindingProvider bp = ( BindingProvider ) proxy ; 11 Map < String , List < String > > headers = new HashMap < String , List < String > >() ; 12 headers . put ( " Username " , Collections . singletonList ( " k19 " ) ) ; 13 headers . put ( " Password " , Collections . singletonList ( " k23 " ) ) ; 14 bp . getRequestContext () . put ( MessageContext . HTTP_REQUEST_HEADERS , headers ) ; 15 16 // operation 17 double next = proxy . next (5 ) ; 18 System . out . println ( next ) ; 19 } 2 }
Cdigo Java 2.24: Consumer.java

62

www.k19.com.br

63
24

JAX-WS

Agora, altere a classe Random do projeto random.

1 @WebService 2 public class Random { 3 4 @Resource 5 WebServiceContext wsc ; 6 7 public double next ( double max ) { 8 MessageContext mc = wsc . getMessageContext () ; 9 1 // get detail from request headers 11 Map headers = ( Map ) mc . get ( MessageContext . HTTP_REQUEST_HEADERS ) ; 12 List usernameList = ( List ) headers . get ( " Username " ) ; 13 List passwordList = ( List ) headers . get ( " Password " ) ; 14 15 String username = usernameList != null ? usernameList . get ( ) . toString () : null ; 16 String password = passwordList != null ? passwordList . get ( ) . toString () : null ; 17 18 System . out . println ( username ) ; 19 System . out . println ( password ) ; 2 21 if ( " k19 " . equals ( username ) && " k23 " . equals ( password ) ) { 22 return Math . random () * max ; 23 } else { 24 throw new RuntimeException ( " usurio ou senha incorretos " ) ; 25 } 26 } 27 }
Cdigo Java 2.25: Random.java

Execute a classe RandomPublisher. Depois, execute a classe Consumer e observe o console do eclipse.
25

26

Altere o usurio e senha denidos na classe Consumer.

1 headers . put ( " Username " , Collections . singletonList ( " usuario " ) ) ; 2 headers . put ( " Password " , Collections . singletonList ( " senha " ) ) ;
Cdigo Java 2.26: Consumer.java

Novamente, execute a classe RandomPublisher. Depois, execute a classe Consumer e observe o console do eclipse.
27

Exerccios Complementares

Vamos monitorar as mensagens recebidas e enviadas pelo webservice do exerccio atravs dos recursos de monitoramento do Eclipse. Siga os passos abaixo.
1

Altere a classe RandomPublisher.


1 public class RandomPublisher { 2 public static void main ( String [] args ) { 3 System . out . println ( " Random web service start ... " ) ;

www.facebook.com/k19treinamentos

63

JAX-WS
4 Random random = new Random () ; 5 Endpoint . publish ( " http :// localhost :9 9 / random " , random ) ; 6 } 7 }

64

Cdigo Java 2.27: RandomPublisher.java

64

www.k19.com.br

65

JAX-WS

Execute a classe RandomPublisher e depois a classe Consumer. Observe os headers contendo os dados para autenticao na view TCP/IP Monitor.
2

www.facebook.com/k19treinamentos

65

JAX-WS

66

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 ; } }

Cdigo Java 2.28: Random.java

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

Exerccios de Fixao

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.
28

66

www.k19.com.br

67

JAX-WS

29

Crie um pacote chamado webservices no projeto randomEJB.

30

Adicione no pacote webservices uma classe para implementar o Statless Session Bean.

1 @WebService 2 @Stateless 3 public class Random {

www.facebook.com/k19treinamentos

67

JAX-WS
4 public double next ( double max ) { 5 return Math . random () * max ; 6 } 7 }

68

Cdigo Java 2.29: Random.java

31

Implante o projeto randomEJB no Glasssh atravs da view Servers.

Acesse a url http://localhost:8 8 /RandomService/Random?WSDL para obter o WSDL que dene o web service.
32

Acesse a url http://localhost:8 8 /RandomService/Random?Tester para testar o web service atravs de uma pgina criada automaticamente pelo Glasssh.
33

34 Analogamente, implemente um Stateless Session Bean que oferea as operaes fundamentais da matemtica.

35

(Opcional) Implemente um cliente Java SE para consumir esse web service.

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 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.

Exerccios de Fixao

68

www.k19.com.br

69
36

JAX-WS

Implemente com dados ctcios um web service em JAX-WS que informe a cotao das moedas.

Implemente com lgica ctcia um web service em JAX-WS que realize a validao de CPF ou CNPJ.
37

38

Implemente com dados ctcios um web service em JAX-WS que informe o preo da gasolina.

39 Implemente com dados ctcios um web service em JAX-WS que calcule a distncia entre dois locais.

40 Crie uma aplicao Java SE para implementar o servio de txi do aeroporto. Obtenha da entrada padro as seguintes informaes

1. Moeda utilizada para o pagamento 2. CPF ou CNPJ 3. 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.

41 (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.

42

(Opcional) Substitua a lgica ctcia de validao de CPF ou CNPJ pela lgica real.

43 (Opcional) Pesquise algum servio que calcule a distncia entre dois pontos e implemente um cliente.

www.facebook.com/k19treinamentos

69

JAX-WS

70

70

www.k19.com.br

CAPTULO

JAX-RS

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 e o funcionamento bsico dos recursos denidos pela especicao JAX-RS.

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.
1 < html > 2 < head > 3 < title > Rafael Cosentino </ title > 4 < head > 5 6 < body > 7 < h1 > Rafael Cosentino </ h1 > 8 <p > Lder de treinamentos da K19 </ p > 9 </ body >

www.facebook.com/k19treinamentos

71

JAX-RS
1 </ html >

72

1 < pessoa > 2 < nome > Rafael Cosentino </ nome > 3 < descricao > Lder de treinamentos da K19 </ descricao > 4 < pessoa >

1 { " 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

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).

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 @Path ( " / Cotacao " ) 2 public class CotacaoResource { 3 ... 4 }
Cdigo Java 3.1: CotacaoResource.java

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 mapeamento.
1 @Path ( " / Cotacao " ) 2 class CotacaoResource { 3 4 @GET 5 public String getCotacao () { 6 // implementao 7 } 8 }

72

www.k19.com.br

73

JAX-RS

Cdigo Java 3.2: CotacaoResource.java

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

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 @Path ( " / Cotacao " ) 2 class CotacaoResource { 3 4 @GET 5 @Path ( " / DollarToReal " ) 6 @Produces ( MediaType . TEXT_PLAIN ) 7 public String getCotacaoDollarToReal () { 8 // implementao 9 } 1 11 @GET 12 @Path ( " / EuroToReal " ) 13 @Produces ( MediaType . TEXT_PLAIN ) 14 public String getCotacaoEuroToReal () { 15 // implementao 16 } 17 }
Cdigo Java 3.4: CotacaoResource.java

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.

Exerccios de Fixao

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.
1

www.facebook.com/k19treinamentos

73

JAX-RS

74

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.3.1.jar, jersey-bundle-1.12.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.

Adicione esses arquivos no classpath do projeto.

Crie um pacote chamado resources no projeto jax-rs.

Adicione no pacote br.com.k19.resources uma classe para implementar um resource de cotao de moeda.
6

1 2 3 4 5 6

package br . com . k19 . resources ; import import import import javax . ws . rs . GET ; javax . ws . rs . Path ; javax . ws . rs . Produces ; javax . ws . rs . core . MediaType ;

74

www.k19.com.br

75
7 8 @Path ( " / Cotacao " ) 9 public class CotacaoResource { 1 11 @GET 12 @Path ( " / DollarToReal " ) 13 @Produces ( MediaType . TEXT_PLAIN ) 14 public String getCotacaoDollarToReal () { 15 return " 1.6 " ; 16 } 17 18 @GET 19 @Path ( " / EuroToReal " ) 2 @Produces ( MediaType . TEXT_PLAIN ) 21 public String getCotacaoEuroToReal () { 22 return " 3.1 " ; 23 } 24 }
Cdigo Java 3.5: CotacaoResource.java

JAX-RS

Crie um pacote chamado br.com.k19.main no projeto jax-rs.

Adicione no pacote br.com.k19.main uma classe para publicar o web service.


package br . com . k19 . main ; import java . io . IOException ; import com . sun . jersey . api . container . httpserver . HttpServerFactory ; import com . sun . net . httpserver . HttpServer ;

public class Publicador { public static void main ( String [] args ) throws IllegalArgumentException , IOException { 1 HttpServer server = HttpServerFactory . create ( " http :// localhost :8 8 / " ) ; 11 server . start () ; 12 } 13 }
Cdigo Java 3.6: Publicador.java

1 2 3 4 5 6 7 8 9

Execute a classe Publicador.

10 Abra o refox e acesse as seguintes urls: http://localhost:8 8 /Cotacao/DollarToReal e http://localhost:8 8 /Cotacao/EuroToReal.

No refox abra o Poster (clique no link no canto inferior direito) e faa uma requisio para cada uma das seguintes urls: http://localhost:8 8 /Cotacao/DollarToReal e http://localhost: 8 8 /Cotacao/EuroToReal.
11

Parmetros
A especicao JAX-RS dene um mecanismo bem simples para injetar os dados contidos nas
www.facebook.com/k19treinamentos

75

JAX-RS

76

requisies HTTP nos mtodos Java das resource classes. Veremos a seguir que tipo de dados podem ser injetados e como injet-los.

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 @PathParam.
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 @Path ( " / Cotacao " ) 2 public class CotacaoResource { 3 4 @GET 5 @Path ( " /{ M1 }/{ M2 } " ) 6 @Produces ( MediaType . TEXT_PLAIN ) 7 public String cotacao ( @PathParam ( " M1 " ) String m1 , @PathParam ( " M2 " ) String m2 ) { 8 // implementacao 9 } 1 }
Cdigo Java 3.8: CotacaoResource.java

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 @Path ( " / Cotacao " ) 2 public class CotacaoResource { 3 4 @GET 5 @Produces ( MediaType . TEXT_PLAIN ) 6 public String cotacao ( @MatrixParam ( " M1 " ) String m1 , @MatrixParam ( " M2 " ) String m2 ) {

76

www.k19.com.br

77
7 // implementacao 8 } 9 }
Cdigo Java 3.9: CotacaoResource.java

JAX-RS

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 @Path ( " / Cotacao " ) 2 public class CotacaoResource { 3 4 @GET 5 @Produces ( MediaType . TEXT_PLAIN ) 6 public String cotacao ( @QueryParam ( " M1 " ) String m1 , @QueryParam ( " M2 " ) String m2 ) { 7 // implementacao 8 } 9 }
Cdigo Java 3.10: CotacaoResource.java

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

1 @Path ( " / Cotacao " ) 2 public class CotacaoResource { 3 4 @POST 5 @Produces ( MediaType . TEXT_PLAIN ) 6 public String cotacao ( @FormParam ( " M1 " ) String m1 , @FormParam ( " M2 " ) String m2 ) { 7 // implementacao 8 } 9 }
Cdigo Java 3.11: CotacaoResource.java

www.facebook.com/k19treinamentos

77

JAX-RS

78

HeaderParam
Os headers HTTP podem ser recuperados atravs da anotao @HeaderParam.
1 @Path ( " / test - header - params " ) 2 public class UserAgentResource { 3 4 @GET 5 @Produces ( MediaType . TEXT_PLAIN ) 6 public String userAgent ( @HeaderParam ( " User - Agent " ) String userAgent ) { 7 return userAgent ; 8 } 9 }
Cdigo Java 3.12: UserAgentResource.java

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

Exerccios de Fixao

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

1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 16 17 18 19

package br . com . k19 . resources ; import import import import import javax . ws . rs . GET ; javax . ws . rs . Path ; javax . ws . rs . PathParam ; javax . ws . rs . Produces ; javax . ws . rs . core . MediaType ;

@Path ( " / path - param " ) public class TestaPathParamResource { @GET @Path ( " /{ p1 }/{ p2 } " ) @Produces ( MediaType . TEXT_PLAIN ) public String pathParam ( @PathParam ( " p1 " ) String p1 , @PathParam ( " p2 " ) String p2 ) { return " P1 = " + p1 + " , P2 = " + p2 ; } }
Cdigo Java 3.14: TestaPathParamResource.java

78

www.k19.com.br

79
13

JAX-RS

Execute a classe Publicador.

14

Acesse as seguintes URIs para testar: http://localhost:8 8 /path-param/1/2 http://localhost:8 8 /path-param/java/csharp

Adicione no pacote br.com.k19.resources do projeto jax-rs uma classe para testar os matrix params.
15

1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 16 17 18

package br . com . k19 . resources ; import import import import import javax . ws . rs . GET ; javax . ws . rs . MatrixParam ; javax . ws . rs . Path ; javax . ws . rs . Produces ; javax . ws . rs . core . MediaType ;

@Path ( " / matrix - param " ) public class TestaMatrixParamResource { @GET @Produces ( MediaType . TEXT_PLAIN ) public String pathParam ( @MatrixParam ( " p1 " ) String p1 , @MatrixParam ( " p2 " ) String p2 ) { return " P1 = " + p1 + " , P2 = " + p2 ; } }
Cdigo Java 3.15: TestaMatrixParamResource.java

16

Execute a classe Publicador.

17

Acesse as seguintes URIs para testar: http://localhost:8 8 /matrix-param;p1=1;p2=2 http://localhost:8 8 /matrix-param;p1=java;p2=csharp

Adicione no pacote br.com.k19.resources do projeto jax-rs uma classe para testar os query params.
18

1 2 3 4 5 6 7 8 9 1

package br . com . k19 . resources ; import import import import import javax . ws . rs . GET ; javax . ws . rs . Path ; javax . ws . rs . Produces ; javax . ws . rs . QueryParam ; javax . ws . rs . core . MediaType ;

@Path ( " / query - param " ) public class TestaQueryParamResource {

www.facebook.com/k19treinamentos

79

JAX-RS
11 12 13 14 15 16 17 18 }

80

@GET @Produces ( MediaType . TEXT_PLAIN ) public String pathParam ( @QueryParam ( " p1 " ) String p1 , @QueryParam ( " p2 " ) String p2 ) { return " P1 = " + p1 + " , P2 = " + p2 ; }

Cdigo Java 3.16: TestaQueryParamResource.java

19

Execute a classe Publicador.

20

Acesse as seguintes URIs para testar: http://localhost:8 8 /query-param?p1=1&p2=2 http://localhost:8 8 /query-param?p1=java&p2=csharp

URI Matching
Podemos utilizar expresso regular para restringir o formato das URIs associadas aos Resources.
1 @Path ( " / uri - matching " ) 2 public class URIMatchingResource { 3 4 @GET 5 @Path ( " /{ a : \\ d *}/{ b : \\ d *} " ) 6 @Produces ( MediaType . TEXT_PLAIN ) 7 public String soma ( @PathParam ( " a " ) double a , @PathParam ( " b " ) double b ) { 8 return a + b + " " ; 9 } 1 11 @GET 12 @Path ( " /{ a }/{ b } " ) 13 @Produces ( MediaType . TEXT_PLAIN ) 14 public String concatena ( @PathParam ( " a " ) String a , @PathParam ( " b " ) String b ) { 15 return a + b ; 16 } 17 }
Cdigo Java 3.17: URIMatchingResource.java

Exerccios de Fixao

21 Adicione no pacote br.com.k19.resources do projeto jax-rs uma classe para testar o URI Matching.

1 package br . com . k19 . resources ; 2 3 import javax . ws . rs . GET ; 4 import javax . ws . rs . Path ;

80

www.k19.com.br

81
5 6 7 8 9 1 11 12 13 14 15 16 17 18 19 2 21 22 23 24 25 import javax . ws . rs . PathParam ; import javax . ws . rs . Produces ; import javax . ws . rs . core . MediaType ; @Path ( " / uri - matching " ) public class URIMatchingResource { @GET @Path ( " /{ a : \\ d *}/{ b : \\ d *} " ) @Produces ( MediaType . TEXT_PLAIN ) public String soma ( @PathParam ( " a " ) double a , @PathParam ( " b " ) double b ) { return a + b + " " ; } @GET @Path ( " /{ a }/{ b } " ) @Produces ( MediaType . TEXT_PLAIN ) public String concatena ( @PathParam ( " a " ) String a , @PathParam ( " b " ) String b ) { return a + b ; } }
Cdigo Java 3.18: URIMatchingResource.java

JAX-RS

22

Execute a classe Publicador.

23

Acesse as seguintes URIs para testar: http://localhost:8 8 /uri-matching/1 /2 http://localhost:8 8 /uri-matching/1 7/3 http://localhost:8 8 /uri-matching/k/19 http://localhost:8 8 /uri-matching/rafael/cosentino

HTTP Headers com @Context


Podemos recuperar os herders HTTP atravs da injeo com @Context
1 @Path ( " / http - headers " ) 2 public class HttpHeadersResource { 3 4 @GET 5 public String addUser ( @Context HttpHeaders headers ) { 6 7 String userAgent = headers . getRequestHeader ( " user - agent " ) . get ( ) ; 8 9 return " user - agent : " + userAgent ; 1 } 11 }
Cdigo Java 3.19: HttpHeadersResource.java

Exerccios de Fixao
www.facebook.com/k19treinamentos

81

JAX-RS

82

Adicione no pacote br.com.k19.resources do projeto jax-rs uma classe para testar a injeo do HttpHeaders.
24

1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 16 17 18

package br . com . k19 . resources ; import import import import javax . ws . rs . GET ; javax . ws . rs . Path ; javax . ws . rs . core . Context ; javax . ws . rs . core . HttpHeaders ;

@Path ( " / http - headers " ) public class HttpHeadersResource { @GET public String addUser ( @Context HttpHeaders headers ) { String userAgent = headers . getRequestHeader ( " user - agent " ) . get ( ) ; return " user - agent : " + userAgent ; } }
Cdigo Java 3.20: HttpHeadersResource.java

25

Execute a classe Publicador.

26

Acesse a seguintes URI para testar: http://localhost:8 8 /http-headers

Download de arquivos
Podemos realizar downloads de arquivos de texto, imagens, pdfs, entre outros com jax-rs.
1 @Path ( " / download " ) 2 public class DownloadResource { 3 4 @GET 5 @Path ( " / texto " ) 6 @Produces ( " text / plain " ) 7 public Response getTexto () { 8 9 File file = new File ( " texto . txt " ) ; 1 11 ResponseBuilder response = Response . ok (( Object ) file ) ; 12 response . header ( " Content - Disposition " , 13 " attachment ; filename =\" texto . txt \" " ) ; 14 return response . build () ; 15 16 } 17 18 @GET 19 @Path ( " / imagem " ) 2 @Produces ( " image / png " ) 21 public Response getImagem () {

82

www.k19.com.br

83
22 23 24 25 26 27 28 29 3 } 31 }

JAX-RS

File file = new File ( " k19 - logo . png " ) ; ResponseBuilder response = Response . ok (( Object ) file ) ; response . header ( " Content - Disposition " , " attachment ; filename =\" k19 - logo . png \" " ) ; return response . build () ;

Cdigo Java 3.21: DownloadResource.java

Exerccios de Fixao

Adicione no pacote br.com.k19.resources do projeto jax-rs uma classe para testar o download de arquivos.
27

1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 16 17 18 19 2 21 22 23 24 25 26 27 28 29 3 31 32 33 34 35 36 37 38 39 4 41

package br . com . k19 . resources ; import java . io . File ; import import import import import javax . ws . rs . GET ; javax . ws . rs . Path ; javax . ws . rs . Produces ; javax . ws . rs . core . Response ; javax . ws . rs . core . Response . ResponseBuilder ;

@Path ( " / download " ) public class DownloadResource { @GET @Path ( " / texto " ) @Produces ( " text / plain " ) public Response getTexto () { File file = new File ( " texto . txt " ) ; ResponseBuilder response = Response . ok (( Object ) file ) ; response . header ( " Content - Disposition " , " attachment ; filename =\" texto . txt \" " ) ; return response . build () ; } @GET @Path ( " / imagem " ) @Produces ( " image / png " ) public Response getImagem () { File file = new File ( " k19 - logo . png " ) ; ResponseBuilder response = Response . ok (( Object ) file ) ; response . header ( " Content - Disposition " , " attachment ; filename =\" k19 - logo . png \" " ) ; return response . build () ; } }
Cdigo Java 3.22: DownloadResource.java

www.facebook.com/k19treinamentos

83

JAX-RS
28

84

Crie um arquivo chamado texto.txt no projeto jax-rs. Adicione algum contedo aleatrio nesse arquivo.

Copie o arquivo k19-logo.png da pasta K19-Arquivos/imagens da rea de Trabalho para o projeto jax-rs.
29

30

Execute a classe Publicador.

31

Acesse a seguintes URI para testar: http://localhost:8 8 /download/texto http://localhost:8 8 /download/imagem

32

Analogamente aos exerccios anteriores, implemente o download de um arquivo PDF.

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 class Produto { 2 private String nome ; 3 4 private Double preco ; 5 6 private Long id ; 7 8 // GETTERS AND SETTERS 9 }
Cdigo Java 3.23: Produto.java

Adicionando a anotao @XMLRootElement da especicao JAXB na classe Produto, podemos gerar produtos em XML ou JSON.
1 @XMLRootElement 2 class Produto { 3 ... 4 }
Cdigo Java 3.24: Produto.java

Agora, basta denir o Media Type nos mtodos de uma resource class de acordo com o formato que desejamos utilizar, XML ou JSON.

84

www.k19.com.br

85
1 @Path ( " / produtos " ) 2 class ProdutoResource { 3 4 @GET 5 @Path ( " /{ id }/ xml " ) 6 @Produces ( MediaType . APPLICATION_XML ) 7 public Produto getProdutoAsXML ( @PathParam ( " id " ) int id ) { 8 // implementacao 9 } 1 11 @GET 12 @Path ( " /{ id }/ json " ) 13 @Produces ( MediaType . APPLICATION_JSON ) 14 public Produto getProdutoAsJSON ( @PathParam ( " id " ) int id ) { 15 // implementacao 16 } 17 }
Cdigo Java 3.25: Produto.java

JAX-RS

Consumindo XML ou JSON


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

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

1 @Path ( " / produtos " ) 2 public class ProdutoResource { 3 @POST 4 @Consumes ( MediaType . APPLICATION_JSON ) 5 public void adiciona ( Produto p ) { 6 // implementacao 7 } 8 }
Cdigo Java 3.28: ProdutoResource.java

www.facebook.com/k19treinamentos

85

JAX-RS

86

Exerccios de Fixao

33

Crie um pacote chamado br.com.k19.entities no projeto jax-rs.

34

Adicione no pacote br.com.k19.entities uma classe para modelar produtos.


package br . com . k19 . entities ; import javax . xml . bind . annotation . XmlRootElement ; @XmlRootElement public class Produto { private String nome ; private Double preco ; private Long id ; // GETTERS E SETTERS }
Cdigo Java 3.29: Produto.java

1 2 3 4 5 6 7 8 9 1 11 12 13 14

35

Adicione no pacote br.com.k19.resources uma classe para produzir produtos em XML e JSON.
package br . com . k19 . resources ; import import import import import javax . ws . rs . GET ; javax . ws . rs . Path ; javax . ws . rs . PathParam ; javax . ws . rs . Produces ; javax . ws . rs . core . MediaType ;

1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 16 17 18 19 2 21 22 23 24 25 26 27 28 29 3 31 32 33 34 35

import br . com . k19 . entities . Produto ; @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 (5 . * id ) ; p . setId ( id ) ; return p ; }

86

www.k19.com.br

87
36 }
Cdigo Java 3.30: ProdutoResource.java

JAX-RS

36

Execute a classe Publicador.

37

Acesse as seguintes URIs para testar:

http://localhost:8 8 /produtos/1/xml http://localhost:8 8 /produtos/1/json

Adicione no pacote br.com.k19.resources uma classe converter produtos de XML para JSON e vice versa.
38

1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 16 17 18 19 2 21 22 23 24 25 26 27 28 29

package br . com . k19 . resources ; import import import import import javax . ws . rs . Consumes ; javax . ws . rs . POST ; javax . ws . rs . Path ; javax . ws . rs . Produces ; javax . ws . rs . core . MediaType ;

import br . com . k19 . entities . Produto ; @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 ; } }
Cdigo Java 3.31: ConversorDeProdutoResource.java

39

Execute a classe Publicador.

40

Abra o refox e depois o Poster (clique no canto inferior direito).

41

Faa uma requisio atravs do Poster como mostra a imagem abaixo:


www.facebook.com/k19treinamentos

87

JAX-RS

88

42

Agora, faa outra requisio atravs do Poster como mostra a imagem abaixo:
www.k19.com.br

88

89

JAX-RS

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 " ) ;

www.facebook.com/k19treinamentos

89

JAX-RS

90

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 ) ;

Exerccios de Fixao

43

Crie um pacote chamado br.com.k19.client no projeto jax-rs.

44

Adicione no pacote client uma classe para interagir com o resource de cotao de moeda.
package br . com . k19 . client ; import com . sun . jersey . api . client . Client ; import com . sun . jersey . api . client . WebResource ; public class TesteCotacaoResource { public static void main ( String [] args ) { Client client = Client . create () ; WebResource resource = client . resource ( " http :// localhost :8 8 / Cotacao / DollarToReal " ) ; String cotacao = resource . get ( String . class ) ; System . out . println ( cotacao ) ; } }
Cdigo Java 3.35: TesteCotacaoResource.java

1 2 3 4 5 6 7 8 9 1 11 12 13 14

45

Adicione no pacote br.com.k19.client uma classe para interagir com o resource de produtos.
package br . com . k19 . client ; import br . com . k19 . entities . Produto ; import com . sun . jersey . api . client . Client ; import com . sun . jersey . api . client . WebResource ; public class TesteProdutoResource { public static void main ( String [] args ) { Client client = Client . create () ; WebResource resourceXML = client . resource ( " http :// localhost :8 8 / 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 :8 8 / produtos /1/ json " ) ;

1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 16 17 18 19 2 21 22 23 24 25 26

90

www.k19.com.br

91
27 28 29 3 31 32 33 34 35 36 37 } 38 }

JAX-RS

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 () ) ;

Cdigo Java 3.36: TesteProdutoResource.java

Adicione no pacote br.com.k19.client uma classe para interagir com o resource de converso de formato dos produtos.
46

1 2 3 4 5 6 7 8 9 1 11 12 13 14 15 16 17 18 19 2 21 22 23 24 25 26 27 28 29

package br . com . k19 . client ; import br . com . k19 . entities . Produto ; import com . sun . jersey . api . client . Client ; import com . sun . jersey . api . client . WebResource ; public class TesteConversorDeProdutoResource { public static void main ( String [] args ) { Produto p = new Produto () ; p . setId (1 L ) ; p . setNome ( " Bola " ) ; p . setPreco (45.67) ; Client client = Client . create () ; System . out . println ( " Convertendo para XML " ) ; WebResource resource1 = client . resource ( " http :// localhost :8 8 / 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 :8 8 / produtos / converte / xml / json " ) ; String json = resource2 . type ( " application / xml " ) . post ( String . class , p ) ; System . out . println ( json ) ; } }

Cdigo Java 3.37: TesteConversorDeProdutoResource.java

Exerccios Complementares

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.
1

Utilize os seguinte esquema de URIs e operaes para os resources do seu web service:
www.facebook.com/k19treinamentos

91

JAX-RS

92

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

Implementes clientes atravs da API do projeto Jersey para testar o web service.

92

www.k19.com.br