Você está na página 1de 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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

JAX-WS
51
2.1 Web Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
2.2 JAXB . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
2.3 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
www.facebook.com/k19treinamentos

S UMRIO

2.4
2.5
2.6
2.7
2.8
2.9
2.10
2.11
2.12
2.13
3

ii

ii

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

71
71
71
72
72
73
73
75
78
80
80
81
81
82
83
84
85
86
89
90
91

www.k19.com.br

S UMRIO

Sobre a K19
A K19 uma empresa especializada na capacitao de desenvolvedores de software. Sua equipe
composta por profissionais formados em Cincia da Computao pela Universidade de So Paulo
(USP) e que possuem vasta experincia em treinamento de profissionais 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

S
TO
EN
AM
EIN
TREINAMENTOS
TR
EIN
AM
EN
TO

TR

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
geogrficas.
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 define o funcionamento de um Middleware Orientado a Mensagens atravs
da especificao Java Message Service - JMS. Todo servidor de aplicao que segue a especificao
Java EE deve oferecer uma implementao do MOM definido pela JMS. Especificaes importantes
da plataforma Java como Enterprise Java Beans (EJB), Java Transaction API (JTA) e Java Transaction
Service (JTS) possuem um relacionamento forte com a especificao JMS. A seguir veremos a arquitetura do MOM definido pela JMS.

Destinos: Filas e Tpicos


Na arquitetura JMS, os sistemas que devem ser integrados podem enviar mensagens para filas(queues) ou tpicos(topics) cadastrados anteriormente no MOM. Na terminologia JMS, as filas
e os tpicos so chamados de destinos(destinations).
Uma mensagem enviada para uma fila 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 filas e os tpicos so objetos criados pelos administradores do MOM. A especificao JMS no


define uma forma padro de criao desses objetos. Dessa maneira, cada implementao JMS possui
os seus prprios procedimentos para esse processo.
No caso do Glassfish, as filas e os tpicos podem ser criados atravs da interface web de administrao do servidor.
Toda fila ou tpico possui um nome nico no MOM.

Exerccios de Fixao

Copie o arquivo glassfish-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 glassfish-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 configurar e testar o Glassfish.


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 configurar e testar o JBoss. Pare o Glassfish 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 Glassfish. Crie uma fila JMS atravs da interface de administrao do
Glassfish 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 Glassfish seguindo exatamente os


passos das imagens abaixo:
6

www.facebook.com/k19treinamentos

13

JMS

14

Pare o Glassfish. Inicie o JBoss. Crie uma fila e um tpico JMS no JBoss alterando o arquivo
de configurao standalone-full.xml. Voc encontra esse arquivo na pasta jboss-as-7.1.1.Final/standalone/configuration.
7

1
2
3
4
5
6
7
8
9
10
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 filas ou tpicos devem obter conexes JMS
atravs das fbricas cadastradas no MOM. Assim como as filas e os tpicos, as fbricas de conexes
JMS so objetos criados pelos administradores do MOM. A especificao JMS no define uma forma
padro para criar essas fbricas, ento cada implementao define a sua prpria forma de criao.
No Glassfish as fbricas podem ser criadas atravs da interface web de administrao do servidor. possvel criar fbricas especificadas para filas 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 Glassfish. Crie uma fbrica de conexes JMS atravs da interface de
administrao do Glassfish seguindo exatamente os passos das imagens abaixo:
8

www.facebook.com/k19treinamentos

15

JMS

16

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

1
2
3
4
5
6
7
8
9
10
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 filas, 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 definido pela especificao JNDI.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

InitialContext ic = new InitialContext () ;


ConnectionFactory factory ;
factory = ( ConnectionFactory ) ic . lookup ( " ConnectionFactory " ) ;
QueueConnectionFactory factory
factory = ( QueueConnectionFactory ) ic . lookup ( " QueueConnectionFactory " ) ;
TopicConnectionFactory factory ;
factory = ( TopicConnectionFactory ) ic . lookup ( " TopicConnectionFactory " ) ;
Queue queue
queue = ( Queue ) ic . lookup ( " Queue " ) ;
Topic topic ;
topic = ( Topic ) ic . lookup ( " Topic " ) ;

Normalmente, os servidores de aplicao Java EE oferecem o recurso de Injeo de Dependncia


para que as aplicaes obtenham as fbricas, filas ou tpicos.
No Glassfish, possvel injetar esses objetos atravs da anotao @Resource. Inclusive em aplicaes standalone (fora do servidor).

www.facebook.com/k19treinamentos

17

JMS

18

1 @Resource ( mappedName = " jms / ConnectionFactory " )


2 private ConnectionFactory connectionFactory ;

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

JMS

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

www.facebook.com/k19treinamentos

19

JMS

20

20

www.k19.com.br

21

JMS

www.facebook.com/k19treinamentos

21

JMS

12

22

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 fila pedidos do Glassfish.

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

22

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

www.k19.com.br

23

JMS

21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
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 (0) ;

Cdigo Java 1.11: EnviaNovoPedidoGlassfish.java

14

Pare o JBoss. Inicie o Glassfish. Execute uma vez a classe EnviaNovoPedidoGlassfish.

Crie um Java Project no eclipse para implementar uma aplicao que possa receber as mensagens da fila 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

16

JMS

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 fila pedidos do Glassfish.
17

1
2
3
4
5
6
7
8
9
10
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

28

16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
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 (0) ;

Cdigo Java 1.12: RecebePedidoGlassfish.java

18

Execute uma vez a classe RecebePedidoGlassfish.

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

1
2
3
4
5
6
7
8
9
10

28

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 ;

www.k19.com.br

29

JMS

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 " ) ;
20
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
30
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
40
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
50
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 " ) ;
60
System . exit (0) ;
61
}
62 }
Cdigo Java 1.13: AssinanteDeNoticiasGlassfish.java

20

Execute duas vez a classe AssinanteDeNoticiasGlassfish.

Adicione no pacote br.com.k19.emissores uma classe com main para enviar uma mensagem
JMS para o tpico noticias do Glassfish.
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
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62

30

import
import
import
import
import
import

javax . jms . ConnectionFactory ;


javax . jms . MessageProducer ;
javax . jms . Session ;
javax . jms . TextMessage ;
javax . jms . Topic ;
javax . naming . InitialContext ;

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 2014 ser no Brasil - "
+ System . currentTimeMillis () ) ;
// enviando
sender . send ( message ) ;
// fechando
sender . close () ;
session . close () ;
connection . close () ;
System . out . println ( " Mensagem Enviada " ) ;
System . exit (0) ;
}
}
Cdigo Java 1.14: EnviaNoticiaGlassfish.java

22

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

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

30

www.k19.com.br

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

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

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

Cdigo Java 1.15: EnviaNovoPedidoJBoss.java

www.facebook.com/k19treinamentos

31

JMS

32

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

24

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

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

32

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

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
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
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

34

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

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
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51

34

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 2014 ser no Brasil - "
+ System . currentTimeMillis () ) ;
// enviando

www.k19.com.br

35

JMS

52
53
54
55
56
57
58
59
60
61
}
62 }

sender . send ( message ) ;


// fechando
sender . close () ;
session . close () ;
connection . close () ;
System . out . println ( " Mensagem Enviada " ) ;
System . exit (0) ;

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

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


1 receiver . receiveNoWait () ;

Percorrendo uma fila


Podemos percorrer as mensagens de uma fila 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 fila pedidos do Glassfish.
31

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

36

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

www.k19.com.br

37

JMS

64 }
Cdigo Java 1.23: PercorrendoFilaGlassfish.java

32 Pare o JBoss. Inicie o Glassfish. Execute algumas vezes a classe EnviaNovoPedidoGlassfish para
popular a fila pedidos do Glassfish e depois execute a classe PercorrendoFilaGlassfish.

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
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
60
61
62
63
}
64 }

38

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

Cdigo Java 1.24: PercorrendoFilaJBoss.java

Pare o Glassfish. Inicie o JBoss. Execute algumas vezes a classe EnviaNovoPedidoJBoss para
popular a fila 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 filtro 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 AssinanteDeNoticiasGlassfish 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 EnviaNoticiaGlassfish acrescentando uma propriedade mensagem enviada.


Observe o trecho de cdigo que voc deve alterar:
36

1
2
3
4
5

38

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

www.k19.com.br

39

JMS

Pare o JBoss. Inicie o Glassfish. Execute uma vez a classe AssinanteDeNoticiasGlassfish e depois
a classe EnviaNoticiaGlassfish. Observe que a mensagem recebida pelo assinante.
37

38

1
2
3
4
5

Altere o valor da propriedade da mensagem enviada.


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

39 Execute uma vez a classe EnviaNoticiaGlassfish. 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 2014 ser no Brasil - "
+ System . currentTimeMillis () ) ;

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

43

1
2
3
4
5

Altere o valor da propriedade da mensagem enviada.


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

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 especificao JMS define 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 Glassfish. Crie uma fbrica para tpicos durveis atravs da interface de
administrao do Glassfish 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 Glassfish inclusive as enviadas enquanto a aplicao estiver off-line.

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

42

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

www.k19.com.br

43
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
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 (2000) ;
while ( message != null ) {
System . out . println ( message . getText () ) ;
message = ( TextMessage ) receiver . receive (2000) ;
}
// fechando
receiver . close () ;
session . close () ;
connection . close () ;
System . out . println ( " FIM " ) ;
System . exit (0) ;

Cdigo Java 1.33: AssinanteDuravelGlassfish.java

Adicione no pacote br.com.k19.emissores uma classe com main para enviar uma mensagem
JMS durvel para o tpico noticias do Glassfish.
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
10
// 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
20
MessageProducer sender = session . createProducer ( topic ) ;
21
22
// mensagem
23
TextMessage message = session . createTextMessage () ;
24
message . setText ( " A copa do mundo de 2014 ser no Brasil - " +
25
System . currentTimeMillis () ) ;
26
27
// enviando
28
sender . send ( message ) ;
29

www.facebook.com/k19treinamentos

43

JMS

44

30
31
32
33
34
35
36
37
}
38 }

// fechando
sender . close () ;
session . close () ;
connection . close () ;
System . out . println ( " Mensagem Enviada " ) ;
System . exit (0) ;

Cdigo Java 1.34: EnviaNoticiaDuravelGlassfish.java

48

Execute uma vez a classe AssinanteDuravelGlassfish para cadastrar um assinante.

Execute algumas vezes a classe EnviaNoticiaDuravelGlassfish. Perceba que o assinante est


offline.
49

Execute a classe AssinanteDuravelGlassfish para receber as mensagens enviadas enquanto o


assinante estava offline.
50

Pare o Glassfish. Inicie o JBoss. Altere as configuraes do JBoss para criar assinantes durveis.Para isso modifique o arquivo de configurao standalone-full.xml. Voc encontra esse arquivo
na pasta jboss-as-7.1.1.Final/standalone/configuration.
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
10
11
12
13
14
15
16
17
18

44

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 " ,

www.k19.com.br

45

JMS

19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
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 (2000) ;
while ( message != null ) {
System . out . println ( message . getText () ) ;
message = ( TextMessage ) receiver . receive (2000) ;
}
// fechando
receiver . close () ;
session . close () ;
connection . close () ;
System . out . println ( " FIM " ) ;
System . exit (0) ;

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

46

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 " ) ;
20
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
30
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
40
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 2014 ser no Brasil - "
49
+ System . currentTimeMillis () ) ;
50
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 " ) ;
60
System . exit (0) ;
61
}
62 }
Cdigo Java 1.36: EnviaNoticiaDuravelJBoss.java

54

Execute uma vez a classe AssinanteDuravelJBoss para cadastrar um assinante.

55

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

Execute a classe AssinanteDuravelJBoss para receber as mensagens enviadas enquanto o assinante estava offline.
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 eficiente.
A especificao EJB define 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 () ) ;
10
} 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 Glassfish 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

58

48

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

1
2
3
4
5
6
7
8

48

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 ;

www.k19.com.br

49

JMS

9
10 @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 ) {
20
System . out . println ( " erro " ) ;
21
}
22
}
23 }
Cdigo Java 1.38: TratadorDeMensagensMDB.java

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

60

Pare o JBoss. Inicie o Glassfish. Envie uma mensagem para o tpico EnviaNoticiaGlassfish 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
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

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

50

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

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 fila com o seguinte JNDI Name jms/pagamentos no Glassfish.

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 fila 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
fila 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 confirmao para as aplicaes locais a cada mensagem de pagamento processada. Dica: Utilize um tpico JMS e faa cada aplicao
local filtrar 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 fiscais.
Hoje, as empresas podem descartar o mtodo tradicional de emisso em papel e utilizar a emisso
eletrnica. Inclusive, o servio de emisso de nota fiscal 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
Verificao 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 define alguns padres para definir o funcionamento de um web service. Em geral, as plataformas de maior uso comercial implementam a
arquitetura definida pelos padres da W3C.
Na plataforma Java, h especificaes que definem a implementao Java dos padres estabelecidos pelo W3C. A especificao 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
especificao Java, a JAXB Java Architecture for XML Binding.
A seguir mostraremos o funcionamento bsico dos recursos definidos pela especificao JAXB e
a arquitetura definida pela JAX-WS.
www.facebook.com/k19treinamentos

51

JAX-WS

52

JAXB
A ideia principal da JAXB definir 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 fim, 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 (2000) ;
conta . setSaldo (2000) ;
marshaller . marshal ( conta , new File ( " conta . xml " ) ) ;

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

52

www.k19.com.br

53

JAX-WS

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

Exerccios de Fixao

Crie um Java Project no eclipse para testar o funcionamento bsico dos recursos definidos pela
especificao 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

54

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

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 (2000) ;
9
conta . setSaldo (2000) ;
10
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 () ) ;
10
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

JAX-WS

5 }
Cdigo Java 2.10: Cliente.java

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
10 }
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
10
Conta conta = new Conta () ;
11
conta . setLimite (2000) ;
12
conta . setSaldo (2000) ;
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 () ) ;
10
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 definido pela JAX-WS. Lembrando que a especificao JAX-WS compatvel com os
padres do W3C. Essa implementao ser realizada em ambiente Java SE.
Para exemplificar, suponha um servio para gerar nmeros aleatrios. A lgica desse servio
pode ser definida atravs de um mtodo Java.
1 class Gerador {
2
public double geraNumero () {
3
return Math . random () * 200;
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 :8080/ gerador " , gerador ) ;
6
}
7 }
Cdigo Java 2.16: Publicador.java

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

8080/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 definio do mesmo em WSDL. As classes
geradas pelo wsimport no devem ser alteradas.
1 wsimport - keep http : // localhost :8080/ gerador ? wsdl

Com o apoio das classes geradas pelo wsimport podemos consumir o web service.
56

www.k19.com.br

57

JAX-WS

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
10
double numero = proxy . geraNumero () ;
11
12
System . out . println ( numero ) ;
13
}
14 }

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

13

58

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

JAX-WS

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 :8080/ random " , random ) ;
6
}
7 }

Cdigo Java 2.20: RandomPublisher.java

16

Execute a classe RandomPublisher.

Consulte atravs de um navegador a url http://localhost:8080/random?wsdl para conferir a


definio 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 :8080/ 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

60

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

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
10
double next = proxy . next (50) ;
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 ):001:0 > require soap / wsdlDriver
=> true
irb ( main ):002:0 > wsdl = http :// localhost :8080/ random ? wsdl
=> " http :// localhost :8080/ random ? wsdl "
irb ( main ):003:0 > proxy = SOAP :: WSDLDriverFactory . new ( wsdl ). create_rpc_driver
ignored attr : {} version
=> #< SOAP :: RPC :: Driver :# < SOAP :: RPC :: Proxy : http :// localhost :8080/ random > >
irb ( main ):004:0 > proxy . next (: arg0 = > 50). return
=> "22.9980548624178"

Terminal 2.2: irb

Autenticao
As especificaes WSDL e SOAP no definem 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
10
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 (50) ;
18
System . out . println ( next ) ;
19
}
20 }

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
10
// 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 (0) . toString () : null ;
16
String password = passwordList != null ? passwordList . get (0) . toString () : null ;
17
18
System . out . println ( username ) ;
19
System . out . println ( password ) ;
20
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
10
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 (50) ;
18
System . out . println ( next ) ;
19
}
20 }
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
10
// 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 (0) . toString () : null ;
16
String password = passwordList != null ? passwordList . get (0) . toString () : null ;
17
18
System . out . println ( username ) ;
19
System . out . println ( password ) ;
20
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 definidos 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

64

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

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 definidos pela
especificao 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 especificaes, 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

68

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

Cdigo Java 2.29: Random.java

31

Implante o projeto randomEJB no Glassfish atravs da view Servers.

Acesse a url http://localhost:8080/RandomService/Random?WSDL para obter o WSDL que


define o web service.
32

Acesse a url http://localhost:8080/RandomService/Random?Tester para testar o web service


atravs de uma pgina criada automaticamente pelo Glassfish.
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 fiscal para brasileiros, o servio de txi deve verificar a validade do CPF do
passageiro ou do CNPJ da empresa que ficar responsvel pelo pagamento. Essa verificao 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 fictcios um web service em JAX-WS que informe a cotao das moedas.

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

38

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

39 Implemente com dados fictcios 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 fictcia 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 definio 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 especificaes que definem o modelo de programao de web services
Java que seguem os princpios REST. A principal especificao 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 definidos pela especificao 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 identificador nico. Esse identificador ser utilizado para que o
resource possa ser acessado. Na internet ou em uma intranet um web resources identificado por
uma URI(Uniform Resource Identifier - http://tools.ietf.org/html/rfc3986). Por exemplo, a
URI www.k19.com.br/cursos identifica 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

72

10 </ html >

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 fixo de operaes deve ser definido 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 especificao JAX-RS define 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 definida 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 definido 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 define apenas um resource. Porm, podemos definir 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
}
10
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 sufixo da URI de um subresource definido 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 sufixos: /Cotacao/DollarToReal e /Cotacao/EuroToReal.

Exerccios de Fixao

Crie um Java Project no eclipse para testar o funcionamento bsico dos recursos definidos pela
especificao 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 especificao. Para testar os recursos definidos nessa especificao 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

74

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 ;

www.k19.com.br

75

JAX-RS

7
8 @Path ( " / Cotacao " )
9 public class CotacaoResource {
10
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 " )
20
@Produces ( MediaType . TEXT_PLAIN )
21
public String getCotacaoEuroToReal () {
22
return " 3.1 " ;
23
}
24 }
Cdigo Java 3.5: CotacaoResource.java

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.

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

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 {
HttpServer server = HttpServerFactory . create ( " http :// localhost :8080/ " ) ;
server . start () ;
}
}
Cdigo Java 3.6: Publicador.java

Execute a classe Publicador.

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

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

Parmetros
A especificao JAX-RS define 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 definir parmetros na URI de um resource
atravs da anotao @PathParam.
1 @Path { " /{ M1 }/{ M2 } " }

Os parmetros definidos 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
}
10 }
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

JAX-RS

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

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

JAX-RS

13

Execute a classe Publicador.

14

Acesse as seguintes URIs para testar:


http://localhost:8080/path-param/1/2
http://localhost:8080/path-param/java/csharp

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
10
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:8080/matrix-param;p1=1;p2=2
http://localhost:8080/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
10

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:8080/query-param?p1=1&p2=2
http://localhost:8080/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
}
10
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
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

JAX-RS
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

22

Execute a classe Publicador.

23

Acesse as seguintes URIs para testar:


http://localhost:8080/uri-matching/10/20
http://localhost:8080/uri-matching/107/3
http://localhost:8080/uri-matching/k/19
http://localhost:8080/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 (0) ;
8
9
return " user - agent : " + userAgent ;
10
}
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
10
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 (0) ;
return " user - agent : " + userAgent ;
}
}
Cdigo Java 3.20: HttpHeadersResource.java

25

Execute a classe Publicador.

26

Acesse a seguintes URI para testar:


http://localhost:8080/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 " ) ;
10
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 " )
20
@Produces ( " image / png " )
21
public Response getImagem () {

82

www.k19.com.br

83

JAX-RS

22
23
24
25
26
27
28
29
30
}
31 }

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
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

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

84

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

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:8080/download/texto
http://localhost:8080/download/imagem

32

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

Produzindo XML ou JSON


A especificao JAX-RS utiliza como base os recursos definidos pela especificao JAXB para produzir XML e JSON. A princpio os recursos do JAXB possibilitam apenas a produo de XML. Contudo,
a arquitetura JAXB flexvel 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 especificao 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 definir 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

JAX-RS

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

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

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

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

35

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

86

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 ;

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 (50.0 * id ) ;
p . setId ( id ) ;
return p ;
}

www.k19.com.br

87

JAX-RS

36 }
Cdigo Java 3.30: ProdutoResource.java

36

Execute a classe Publicador.

37

Acesse as seguintes URIs para testar:

http://localhost:8080/produtos/1/xml
http://localhost:8080/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
10
11
12
13
14
15
16
17
18
19
20
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 firefox 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

42

88

88

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

89

JAX-RS

Implementando um Cliente
A especificao JAX-RS no define uma API para padronizar o desenvolvimento de clientes Java
de web services restful. Algumas implementaes JAX-RS definem 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 definir 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 fim, podemos executar uma operao HTTP no resource atravs dos mtodos da classe WebResource. O tipo do resultado da operao definido 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.

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

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 :8080/ Cotacao / DollarToReal " ) ;
String cotacao = resource . get ( String . class ) ;
System . out . println ( cotacao ) ;
}
}
Cdigo Java 3.35: TesteCotacaoResource.java

45

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

90

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 :8080/ produtos /1/ xml " ) ;
System . out . println ( " TESTANDO COM XML " ) ;
String xml = resourceXML . get ( String . class ) ;
System . out . println ( xml ) ;
Produto produto1 = resourceXML . get ( Produto . class ) ;
System . out . println ( produto1 . getId () ) ;
System . out . println ( produto1 . getNome () ) ;
System . out . println ( produto1 . getPreco () ) ;
WebResource resourceJSON = client
. resource ( " http :// localhost :8080/ produtos /1/ json " ) ;

www.k19.com.br

91

JAX-RS

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

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
10
11
12
13
14
15
16
17
18
19
20
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 :8080/ produtos / converte / json / xml " ) ;
String xml = resource1 . type ( " application / json " ) . post ( String . class , p ) ;
System . out . println ( xml ) ;
System . out . println ( " Convertendo para JSON " ) ;
WebResource resource2 = client
. resource ( " http :// localhost :8080/ produtos / converte / xml / json " ) ;
String json = resource2 . type ( " application / xml " ) . post ( String . class , p ) ;
System . out . println ( json ) ;
}
}

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

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

92

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

92

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

www.k19.com.br

Você também pode gostar