Web Services REST (Java)

20
19/02/2015 Web Services REST http://www.linhadecodigo.com.br/artigo/2059/webservicesrest.aspx 1/20 Log In / Cadastrese Desenvolvimento Java Web Services REST O objetivo deste artigo é partir de um exemplo rico o suficiente de arquitetura orientada a serviços e então fazer a modelagem e desenvolvimento dos mesmos com uso de uma abordagem RESTful. por Bruno Luiz Pereira da Silva Introdução Este artigo fala sobre web services REST. Esta linha de web services vem se tornando cada vez mais popular e é uma excelente opção para integração este sistemas de diferentes plataformas. Neste artigo abordarei os principais conceitos deste tipo de serviços, utilizarei um exemplo de leilão do Mercado Livre para ilustrar o problema, e mostrarei detalhes da arquitetura e implementação. Definição REpresentation State Transfer Estilo de arquitetura de software para sistemas distribuídos Termo proposto por Roy Fielding em sua tese de doutorado Web services com a arquitetura da internet Exploração extensa dos recursos do HTTP Surgimento Roy Fielding é um dos principais autores do protocolo HTTP, e ele propôs em sua tese de doutorado um estilo de arquitetura que faz extenso uso dos recursos oferecidos por este protocolo. Enquanto nos serviços WSI os recursos do HTTP são muito pouco explorados (inclusive porque o SOAP é independente de transporte), nos serviços REST umas das principais características é a utilização de muitos recursos do HTTP para elaborar um protocolo de comunicação conciso e claro. REST ? TCP/IP WSI ? OSI WSI: Publicidade Seguir @linhadecodigo 3.162 seguidores 2.460 Pesquisar HOME DESENVOLVIMENTO FRONTEND BANCO DE DADOS EM DESTAQUE TODOS PUBLIQUE 0 6 Like .net Mag 120 Easy .net mag 39 ASSINE VER TODAS REVISTAS DEVMEDIA 1 Comandos básicos em SQL insert, update, delete e select 2 HTML Básico 3 Excel: Como verificar se existe valores duplicados 4 Menu em CSS Menu dropdown horizontal com HTML5 e CSS3 5 Criando um sistema de cadastro e login com PHP e MySql 6 Calendário em jQuery Criando Calendários com DatePicker 7 Formato dos registros do Sintegra 8 SQL: Utilizando o Operador UNION e UNION ALL 9 Código para background HTML e CSS 10 Excel: Comparando Listas VER TODOS TOP 10 ARTIGOS TOP 10 AUTORES 49 11 0 32

description

Ótima explicação do modelo de serviços REST, juntamente com um guia de implementação usando a plataforma JAVA.Com esse pequeno artigo, os desenvolvedores podem aprender facilmente a implementação de web services REST usando a linguagem Java.

Transcript of Web Services REST (Java)

Page 1: Web Services REST (Java)

19/02/2015 Web Services REST

http://www.linhadecodigo.com.br/artigo/2059/webservicesrest.aspx 1/20

Log In / Cadastrese

Desenvolvimento Java

Web Services RESTO objetivo deste artigo é partir de um exemplo rico o suficiente de arquitetura orientada a serviços e então fazera modelagem e desenvolvimento dos mesmos com uso de uma abordagem RESTful.por Bruno Luiz Pereira da Silva

IntroduçãoEste artigo fala sobre web services REST. Esta linha de web services vem se tornando cada vez maispopular e é uma excelente opção para integração este sistemas de diferentes plataformas.

Neste artigo abordarei os principais conceitos deste tipo de serviços, utilizarei um exemplo de leilão doMercado Livre para ilustrar o problema, e mostrarei detalhes da arquitetura e implementação.

Definição

REpresentation State TransferEstilo de arquitetura de software para sistemas distribuídosTermo proposto por Roy Fielding em sua tese de doutoradoWeb services com a arquitetura da internetExploração extensa dos recursos do HTTP

SurgimentoRoy Fielding é um dos principais autores do protocolo HTTP, e ele propôs em sua tese de doutoradoum estilo de arquitetura que faz extenso uso dos recursos oferecidos por este protocolo.

Enquanto nos serviços WSI os recursos do HTTP são muito pouco explorados (inclusive porque oSOAP é independente de transporte), nos serviços REST umas das principais características é autilização de muitos recursos do HTTP para elaborar um protocolo de comunicação conciso e claro.

REST ? TCP/IP WSI ? OSI

WSI:

Publicidade

Seguir @linhadecodigo 3.162 seguidores 2.460

PesquisarEnviar

HOME DESENVOLVIMENTO FRONTEND BANCO DE DADOS EM DESTAQUE TODOS PUBLIQUE

0 6Like

.net Mag 120 Easy .net mag 39

ASSINEVER TODAS

REVISTAS DEVMEDIA

1 Comandos básicos em SQL insert,update, delete e select

2 HTML Básico

3 Excel: Como verificar se existe valoresduplicados

4 Menu em CSS Menu dropdown horizontalcom HTML5 e CSS3

5 Criando um sistema de cadastro e logincom PHP e MySql

6 Calendário em jQuery CriandoCalendários com DatePicker

7 Formato dos registros do Sintegra

8 SQL: Utilizando o Operador UNION eUNION ALL

9 Código para background HTML e CSS

10 Excel: Comparando Listas

VER TODOS

TOP 10 ARTIGOS TOP 10 AUTORES

49 11 0 32

Page 2: Web Services REST (Java)

19/02/2015 Web Services REST

http://www.linhadecodigo.com.br/artigo/2059/webservicesrest.aspx 2/20

Muitas especificações antes das implementaçõesMuitos documentos e complexidade para definir as implementaçõesModelo semelhante a waterfall/cascata

REST:

Conjunto de regras simplesEspecificações criadas após uso maduroEspecificações por grupos de estudo do IETFModelo incremental de desenvolvimento dos padrões/boas práticas

Motivação

Por que implementar serviços REST?

Protocolos menos complexosMais poder e flexibilidade nas comunicaçõesArquitetura amplamente disponível nas empresasMenos overhead de protocolo

Quando NÃO implementar serviços REST?

Integrações com produtos fechados WS*Quando WSTransaction fizer sentidoQuando WSSecurity fizer sentidoQuando não houver API HTTP razoável no servidor e/ou clientesalvo

ArquiteturaA arquitetura dos web services WS* se baseia em um protocolo bem definido, com regras precisasquanto ao formato dos dados trafegados e seguindo padrões acordados em consórcios de grandescorporações. Contrastando com isso, arquitetura dos web services REST é radicalmente diferente.

Poderíamos ilustrar as filosofias de projeto de serviços WS* e REST com as sentenças a seguir.

WS*: “Já temos o protocolo e os padrões, devemos definir os serviços que vamos oferecer e osdocumentos que desejamos trocar entre as partes.”

REST: “Vamos identificar os recursos envolvidos e utilizar extensamente os recursos do HTTP paradefinir um bom protocolo de interação com estes recursos.”

Estilos de acesso aos serviços

REST: Clientes interagem com os Recursos através de requisições HTTP GET, PUT, POST e DELETE

WS*: Clientes invocam diferentes operações, com conjuntos variados de parâmetros de entrada esaída

Estilo Declarativo x Imperativo

Page 3: Web Services REST (Java)

19/02/2015 Web Services REST

http://www.linhadecodigo.com.br/artigo/2059/webservicesrest.aspx 3/20

A URI deve indicar o que você está manipulando e o método (ou verbo) HTTP indicará como vocêestá manipulando. Neste exemplo, a URI /usuario/123456 nos indica que estamos manipulando umusuário específico. Sabendo que estamos usando o método HTTP GET, temos a clara indicação deque estamos buscando os dados deste usuário. Este estilo de invocação de serviços pode serconsiderado Declarativo.

Em bons protocolos REST, a junção do método HTTP com a URI do recurso já nos indica na maioriados casos qual é a operação sendo realizada. Assim, com um pequeno trecho do cabeçalho HTTP jásomos capazes de compreender a comunicação.

Nos web services WS*, a informação da operação que está sendo realizada fica encapsulada no corpoda requisição. Mesmo quando a camada de transporte das mensagens SOAP é HTTP, a URI nãoesclarece de forma alguma a operação envolvida. A informação dos serviços disponíveis fica descritapor elementos operation de um documento WSDL, geralmente em um formato fazerEssaOperacao.Esta maneira de desenvolver web services é classificada como Imperativa.

Modelagem dos serviçosNesta seção falaremos da modelagem e desenvolvimento dos serviços utilizando REST. Para ilustrarbem os cenários abordados, trabalharemos em cima de um problema proposto: um processo de leilãodo Mercado Livre.

Apresentação do problema

O problema que buscaremos resolver envolve serviços referentes a um processo de leilão do MercadoLivre. Num leilão típico, um usuário cadastrado no site coloca para venda um produto (novo ou usado),definindo um valor para o lance inicial e então aguarda pelas ofertas de compra por parte de outrosusuários interessados no produto.

Após receber algumas ofertas pelo produto, em um determinado momento o vendedor decide aceitar amelhor oferta recebida, e então vende o produto para o comprador que fez esta oferta, encerrandoneste momento o leilão. Em seguida à venda, ocorrem os trâmites de pagamento e entrega do produto(que não trataremos aqui) e no final, vendedor e comprador avaliam um ao outro, o que é essencialpara os usuários sentirem maior segurança ao realizar negociações futuras deste gênero.

Na modelagem desta aplicação, quatro entidades serão utilizadas: Usuário, Item, Oferta e Avaliação.

Modelagem com Recursos

O ponto de partida do desenvolvimento com REST é definir quais são os recursos envolvidos, combase nos requisitos do sistema e nos serviços que se deseja oferecer. No nosso exemplo, esta etapanão é complexa. Os recursos que manipularemos são: Usuario, Item, Oferta e Avaliacao.

Embora esta identificação tenha sido trivial no domínio que definimos, em alguns casos este processopode ser um dos mais complexos na modelagem da aplicação. De uma maneira geral, quanto mais a

Page 4: Web Services REST (Java)

19/02/2015 Web Services REST

http://www.linhadecodigo.com.br/artigo/2059/webservicesrest.aspx 4/20

aplicação se aproxima de um CRUD, mais fácil é a identificação dos recursos.

Para este processo de leilão, os serviços que disponibilizaremos serão os da Tabela 1:

Serviço Descrição

Anunciar item Permite que um usuário coloque um produto à venda.

Buscar itens dovendedor

Pesquisa os itens à venda de um vendedor.

Cadastrar usuário Realiza o cadastro de um novo usuário no site.

Realizar oferta Permite que um comprador faça uma oferta por um produto.

Retirar oferta Permite a remoção de uma oferta por parte do comprador.

Buscar ofertas doitem

Pesquisa por todas as ofertas feitas sobre um produto.

Buscar melhoroferta

Busca a melhor oferta feita até o momento sobre um produto.

Aceitar melhoroferta

Permite que um vendedor aceite a melhor oferta feita sobre o seuproduto, e com isso encerre o leilão do mesmo.

Avaliar usuário Realiza a avaliação de um usuário por parte de outro usuário, após otérmino do processo de compra.

Buscar avaliaçõesdo usuário

Pesquisa por todas as avaliações recebidas por um usuário.

Tabela 1. Serviços oferecidos para interação com o processo de leilão.

Protocolo de comunicação REST

Tendo definido os recursos e os serviços que precisamos oferecer, é necessário definir asmanipulações possíveis sobre os recursos existentes. Esta etapa é a tradução de operações denegócio em interações diretas sobre usuários, ítens, ofertas e avaliações. Esta tradução feitaexplorando os recursos do HTTP nos levará a um conjunto de URIs que a aplicação oferece para osclientes.

Para elaborar um bom protocolo de comunicação REST, devemos pensar em algumas questõesimportantes, como estas:

Quais são os recursos?Quais são as URIs?Quais são os formatos manipulados?Que métodos HTTP são aceitos em cada URI?Que status HTTP deve ser retornado em cada situação?Que cabeçalhos HTTP são relevantes em cada situação?

A definição das URIs e dos métodos HTTP aceitos é primordial para um protocolo REST com clareza ede fácil utilização e extensão. Ao ler as URIs já devemos ser capazes de entender quais são osrecursos presentes nas mesmas, e o casamento delas com os métodos HTTP deve ser intuitivo.

A Tabela 2 descreve todas as URIs disponíveis na aplicação e quais métodos HTTP podem serinvocados em cada uma delas. Além disso, são especificados os recursos manipulados por cadarequisição e o efeito que uma determinada chamada exerce sobre os recursos existentes.

URI Método Formato Efeito

GET Item Busca um item.

Page 5: Web Services REST (Java)

19/02/2015 Web Services REST

http://www.linhadecodigo.com.br/artigo/2059/webservicesrest.aspx 5/20

/item/id

PUT Item Atualiza um item.

/item/id/ofertas

GETColeção deofertas

Busca ofertas feitas sobre um item.

POST Oferta Adiciona oferta a um item.

/oferta/id

GET Oferta Busca uma oferta.

PUT Oferta Atualiza uma oferta.

DELETE Remove uma oferta.

/usuario POST Usuario Cadastra um usuário.

/usuario/id

GET Usuario Busca um usuário.

PUT Usuario Atualiza um usuário.

/usuario/id/avaliacoes GETColeção deavaliações

Busca as avaliações recebidas por umusuário.

/usuario/id/itens

GETColeção de

ítensBusca os ítens anunciados por umdeterminado usuário.

POST Item Usuário coloca novo item à venda.

/avaliacao/id GET Avaliação Busca uma determinada avaliação.

/avaliacao/de/id/para/id POST Avaliação Realização da avaliação de umusuário sobre outro.

/services GETColeção de

URIsConsulta URIs e métodos HTTPdisponíveis para acesso.

Tabela 2. URIs de acesso a recursos e métodos HTTP aceitos por cada uma delas

Implementação com a JAXRS (Java API for RESTFul Web Services)Para oferecer melhor suporte a serviços REST em Java, foi criada a JSR311. Veja os objetivos destaJSR.

Com a JAXRS, um recurso web é implementado como uma classe Recurso e as requisições sãotratadas por métodos da mesma. Uma classe Recurso é simplesmente um POJO contendo anotaçõesda JAXRS para indicar os mapeamentos e operações existentes.

Ciclo de vida e ambientePor padrão, uma nova instância da classe Recurso é criada para cada requisição àquele Recurso.Inicialmente o construtor é invocado, dependências necessárias são injetadas, e então o métodoadequado é executado. Após estas etapas, o objeto fica disponível para o coletor de lixo.

As classes Recurso são instanciadas pelo runtime JAXRS e devem possuir pelo menos um construtorpúblico. Um construtor público pode incluir parâmetros com uma das seguintes anotações: @Context,@HeaderParam, @CookieParam, @MatrixParam, @QueryParam e @PathParam. Estas anotaçõesrealizam injeção de dependências relativas a serviços REST, e são apresentadas na Tabela 3.

AnotaçãoDescrição

Page 6: Web Services REST (Java)

19/02/2015 Web Services REST

http://www.linhadecodigo.com.br/artigo/2059/webservicesrest.aspx 6/20

@Context

Injeta uma instância de recursos como UriInfo, HttpHeaders, ServletConfig,ServletContext, HttpServletRequest e HttpServletResponse. Outrosrecursos de Java EE podem ser opcionalmente oferecidos por umaimplementação desta JSR.

@HeaderParam Extrai o valor de um cabeçalho da requisição HTTP.

@CookieParam Extrai o valor de um cookie presente na requisição.

@MatrixParamExtrai o valor de parâmetros enviados no formato chave=valor dentro deum segmento da URI. Exemplo:/usuário/123/itens;categoria=eletronicos;limitePreco=1000

@QueryParam Extrai o valor de um parâmetro fornecido na query string da requisição.

@PathParam Extrai o valor de um parâmetro enviado dentro da URI.

Tabela 3. Anotações da JAXRS para injeção de dependênciasCom exceção do Context, estes parâmetros são enviados dentro de URIs, query strings, cabeçalhosHTTP e cookies. Sendo assim, sua representação na camada de transporte é como String. Entretanto,podemos colocar estas anotações sobre parâmetros que não são String, para já recebermos os dadosconvertidos em um formato mais adequado para nossa manipulação. Tipos de parâmetros que podemser marcados com estas anotações são:

Tipos primitivosClasses que possuam um construtor tendo uma única String como parâmetroClasses que possuam um método estático valueOf() recebendo uma String como parâmetro;List<T>, Set<T> ou SortedSet<T>, onde T satisfaz a condição 2 ou a 3.

A seguir um exemplo de uso destas anotações:

@GET@Path("usuarioId")public Response buscarUsuario(@PathParam("usuarioId") String usuarioId)

Usuario usuario = usuarioService.buscar(usuarioId);Response resposta = Response.ok(usuario).build();

return resposta;Este exemplo mostra como poderia ser um método de busca de usuário recebendo uma URI/usuario/usuarioId, como /usuario/123. O parâmetro usuarioId do método poderia ser int ouInteger, caso o ID do usuário fosse um número inteiro. A implementação da API faria a conversão doparâmetro enviado na URI para o tipo especificado no método.

Requisições aos métodos de RecursosUm método de Recurso é uma operação exposta como um serviço REST. Estes métodos ficam emuma classe Recurso e são anotados com o método HTTP associado à operação em questão. Oconjunto de anotações que define os métodos HTTP que podem ser utilizados nas operações é:@GET, @POST, @PUT, @DELETE, @HEAD e @OPTIONS.

Métodos de Recursos que serão expostos para os clientes devem ser públicos. Implementações daJSR devem alertar os desenvolvedores caso encontrem métodos nãopúblicos que sejam marcadoscom alguma destas anotações de método HTTP.

Os parâmetros dos métodos são convertidos da requisição de acordo com as anotações apresentadasna Tabela 3. Um método de Recurso pode ter no máximo um parâmetro nãoanotado. Este parâmetronãoanotado será obtido do corpo da requisição.

A obtenção de parâmetros do corpo da requisição só faz sentido quando estamos falando derequisições POST e PUT. Estes são os únicos métodos HTTP que possuem um corpo, e quase sempresão utilizados em operações de criação e atualização de Recursos, respectivamente. O trecho a seguirapresenta um exemplo de método que recebe requisições POST para cadastro de usuários.

Page 7: Web Services REST (Java)

19/02/2015 Web Services REST

http://www.linhadecodigo.com.br/artigo/2059/webservicesrest.aspx 7/20

@POSTpublic Response cadastrarUsuario(Usuario usuario)

usuario = usuarioService.cadastrar(usuario);try return Response.created(new URI(usuario.getCodUsuario())).build();

catch (URISyntaxException e) throw new RuntimeException(e);

Respostas dos métodos de RecursosAs respostas aos métodos de Recursos podem ser declaradas como void, Response ou qualqueroutra classe Java. Retornar void implica em enviar uma resposta com corpo vazio, o que é mapeadoem um status HTTP 204 (No Content). Este status é utilizado pela JSR para indicar que a requisiçãoteve sucesso, e a resposta não possui corpo.

Colocar uma classe Java como tipo de resposta fará com que o objeto retornado seja colocado nocorpo da resposta. Um objeto nulo enviado na resposta implicará em status HTTP 204 e um objetonãonulo implicará no status HTTP 200.

A classe Response pode ser colocada como tipo de retorno dos métodos caso desejemos ter maiscontrole sobre a resposta. Com esta forma de retorno, conseguimos especificar cabeçalhos, corpo,status, cookies e mais algumas informações da resposta enviada.

Até este momento não mencionamos nada a respeito do formato dos Recursos manipulados.Mostramos exemplos de busca e cadastro de usuários, mas ficou explícita nos exemplos apenas amanipulação de objetos Java. A questão dos formatos é muito importante e é coberta na seção“Manipulação de diferentes formatos”.

Tratamento de erros e exceçõesComo padrão, quando ocorre uma exceção durante uma chamada REST, o cliente recebe um statusHTTP 500 (Internal Server Error). Em muitas situações este status pode não ser satisfatório, pois nãofornece muita informação sobre o erro que ocorreu no servidor. Para resolver este problema a JSR311 permite que a resposta seja personalizada em caso de exceções. Podemos fazer este controle deduas formas.

A primeira forma é com uma exceção especial. Basta disparar uma unchecked exceptionjavax.ws.rs.WebApplicationException. Criando esta exceção podemos passar o status HTTP e umobjeto Response, permitindo total controle da resposta que será enviada para o usuário.

Porém, em uma aplicação grande é muito comum termos o lançamento de outras exceções emcamadas inferiores. Para esta situação a JSR311 permite que seja criada uma classe para mapear aresposta correspondente a cada exceção. Este mapeamento seria conhecido apenas pela camada deserviços REST.

A classe de mapeamento deve implementar a interface javax.ws.rs.ext.ExceptionMapper e seranotada com @Provider. A partir daí, quando a exceção especificada for disparada o controle vaipassar para o método toResponse() desta classe. Este método poderá construir a resposta de acordocom a exceção, que é passada como parâmetro.

Sobre a segunda forma de tratar exceções vale citar que ela ainda está sendo implementada na versão0.8 da especificação, e está sujeita a modificações até a finalização da JSR.

O trecho a seguir apresenta um exemplo de mapeamento de exceção para uma resposta com statusHTTP customizado.

@Providerpublic class ItemJaVendidoExceptionMapper implements ExceptionMapper public Response toResponse(ItemJaVendidoException e)

return Response.status(Response.Status.GONE).build();

Page 8: Web Services REST (Java)

19/02/2015 Web Services REST

http://www.linhadecodigo.com.br/artigo/2059/webservicesrest.aspx 8/20

Manipulação de diferentes formatosUma das capacidades mais interessantes que temos na JSR311 é a de tratar facilmente diferentesformatos nos nossos serviços. Somos capazes de receber e gerar dados em diferentes tipos deconteúdo, sem ônus para os desenvolvedores.

Os formatos XML e JSON já estão disponíveis no Jersey (implementação de referência da JSR). Alémdisso, a JSR permite que seja oferecido o suporte a qualquer formato, através de classes Provider.

Classes Provider são desenvolvidas para permitir a leitura e/ou escrita de determinados tipos deconteúdo (ContentTypes). Uma classe Provider implementa as interfaces MessageBodyReader eMessageBodyWriter para oferecer suporte ao tipo de conteúdo que se propõe. Poderíamos ter, porexemplo, um Provider que soubesse manipular recursos com formato mp3 em uma aplicaçãomultimídia.

Classes Recurso podem usar as anotações @ConsumeMime e @ProduceMime para declarar quaissão os tipos de conteúdo que elas geram e os tipos de conteúdo que elas aceitam receber,respectivamente. Caso nenhum tipo de conteúdo seja declarado, assumese que qualquer tipo deconteúdo (”*/*”) é aceito.

O trecho a seguir apresenta um exemplo de uso destas anotações na classe UsuarioResource. Nesteexemplo, declaramos que a classe aceita e gera conteúdo nos formatos text/xml e application/json.

@ConsumeMime( "text/xml", "application/json" )

@ProduceMime( "text/xml", "application/json" )public class UsuarioResource Neste exemplo, colocamos as anotações sobre a classe. Estas anotações também podem sercolocadas sobre métodos. Caso as anotações sejam colocadas sobre a classe e também sobre ummétodo, a anotação sobre o método é a que vale.

O trecho abaixo mostra um exemplo de anotações sobre a classe e sobre um método. Neste exemplo,declaramos que a classe aceita os tipos de conteúdo text/xml e application/json em todos os seusmétodos, com exceção do método buscarUsuario(). Neste método declaramos que produzimos apenasconteúdo em formato text/xml. O método atualizarUsuario() herda as declarações feitas na classe,portanto aceita conteúdo em text/xml e application/json.

@Path("usuario")@ConsumeMime( "text/xml", "application/json" )

@ProduceMime( "text/xml", "application/json" )public class UsuarioResource

@GET@Path("usuarioId")@ProduceMime("text/xml")public Response buscarUsuario(@PathParam("usuarioId") String usuarioId)

Usuario usuario = usuarioService.buscar(usuarioId);Response resposta = Response.ok(usuario).build();

return resposta;

@PUT@Path("usuarioId")public Response atualizarUsuario(Usuario usuario)

usuarioService.atualizar(usuario);return Response.ok().build();

É importante mencionar como funciona este tratamento dos tipos de conteúdo. Quando um cliente fazuma requisição HTTP, ele pode especificar o cabeçalho Accept. Este cabeçalho informa ao servidorquais são os tipos de conteúdo que o cliente aceita receber. Se o cliente não especificar estecabeçalho, o valor assumido do mesmo é “*/*”, o que indica que o cliente aceita qualquer tipo de

Page 9: Web Services REST (Java)

19/02/2015 Web Services REST

http://www.linhadecodigo.com.br/artigo/2059/webservicesrest.aspx 9/20

conteúdo.

Ao receber uma requisição HTTP, o runtime JAXRS irá comparar a lista de tipos enviados nocabeçalho Accept com a lista de tipos de conteúdo registrados para o método invocado. Nestacomparação, as seguintes regras serão aplicadas:

Caso exista apenas um tipo de conteúdo em comum entre as duas listas, este será o tipo deconteúdo enviado;Caso exista mais de um tipo de conteúdo em comum entre as listas, o conteúdo será enviado

no formato que aparecer primeiro na lista registrada no servidor. Se o método declarou geraçãode text/xml e application/json (nesta ordem) e o cliente aceita ambos os tipos, o clientereceberá text/xml;Se a lista de tipos de conteúdo oferecida pelo servidor não contiver nenhum dos tipos que o

cliente afirmou aceitar, o runtime JAXRS envia uma resposta de falha com status HTTP 415(Unsupported Media Type).

Com estes exemplos, mostramos a capacidade de gerar diferentes formatos em nossos serviços, semque seja necessário tratar isso explicitamente pela nossa aplicação. A declaração dos tipos deconteúdo através das anotações @ConsumeMime e @ProduceMime é suficiente para que o runtimeJAXRS faça o tratamento correto.

Uma última questão que precisamos abordar neste contexto é como indicar para a JAXRS como deveser feito o mapeamento de nossas classes em XMLs. As implementações da JSR são obrigadas asuportar o uso de JAXB (Java Architecture for XML Binding) na conversão de Java para XML e deXML para Java. O JAXB é um dos componentes do Java EE 5 e foi incluído também na versão 6 doJava SE. Ele é a forma padrão de mapeamento entre classes Java e documentos XML na JSR311.

Para utilizar o JAXB no mapeamento de nossas classes, a opção mais simples é utilizar a anotação@XmlRootElement sobre as mesmas. Ao fazer isso, o JAXB fará a conversão da classe e dos seusatributos em um documento XML cujo elemento root será o nome da classe (começando porminúscula). Os elementos filhos serão os atributos da classe, seguindo a nomenclatura da mesma.

Caso seja desejado, é possível especificar na anotação @XmlRootElement um nome de elementoXML diferente do nome da classe. Podemos também modificar os elementos XML dos atributos daclasse usando a anotação @XmlElement. O JAXB nos permite customizar bastante os mapeamentosrealizados, se assim quisermos. O trecho abaixo apresenta um exemplo no qual mapeamos a classeAvaliacao para um XML com elementos em inglês. Não entraremos em mais detalhes sobre o JAXBneste momento, pois isto fugiria do foco do artigo.

@XmlRootElement(name = "feedback")

public class Avaliacao XmlElement(name = "feedbackCode")

private String codAvaliacao;@XmlElement(name = "rater")

private Usuario avaliador;@XmlElement(name = "positive")

private boolean positiva;@XmlElement(name = "comment")

private String comentario;

Mapeamento de URIs e métodos HTTP em classes Recurso e seus métodosUma das principais vantagens no uso da JSR311/Jersey é eliminar do nosso desenvolvimento avalidação de requisições e o mapeamento das mesmas em classes e métodos que devem processálas. Isto implica em obter a URI e o método HTTP das solicitações e conferir se existe algum dosnossos serviços que saiba tratála. Além disso, antes de invocar os serviços em questão, precisamosextrair das URIs os parâmetros que tenham sido enviados nas mesmas.

A anotação @Path pode ser colocada em classes e métodos. Quando a colocamos sobre uma classe,

Page 10: Web Services REST (Java)

19/02/2015 Web Services REST

http://www.linhadecodigo.com.br/artigo/2059/webservicesrest.aspx 10/20

estamos associando a classe a um prefixo de URI. Esta anotação foi utilizada anteriormente no artigopara associar o prefixo /usuario da nossa aplicação à classe UsuarioResource.

Colocamos a anotação @Path sobre métodos para formar o caminho completo dos nossos serviços.Juntando os valores da anotação @Path sobre os métodos com o valor da anotação sobre a classe,temos a lista de URIs disponíveis na classe Recurso em questão.

A colocação das anotações @GET, @POST, @PUT, @DELETE, @HEAD e @OPTIONS complementao mapeamento de URIs. Com estas duas informações sobre cada método, conseguimos mapearprecisamente cada solicitação na classe e no método que devem tratála.

Mostraremos na próxima seção como fica o uso da JSR311 no desenvolvimento dos serviços deleilão.

Aplicando a JSR311 e o Jersey nos serviços de leilãoNesta seção mostraremos como usar o Jersey para implementar os serviços do processo de leilão.Devido às limitações de espaço, escolhemos apenas uma parte dos serviços, mas de forma que sejapossível ilustrar com clareza as diferenças.

A primeira etapa necessária é a configuração do Jersey no projeto. A distribuição binária estável maisrecente no momento da escrita deste artigo é a 0.7. Esta distribuição pode ser obtida no site do projeto.

Devemos mapear todos os prefixos de URIs dos nossos serviços para um Servlet do Jersey. O trechoabaixo mostra um web.xml configurado com este mapeamento. Na nossa aplicação, como todas asURIs são de serviços REST, mapeamos toda a aplicação (/*) para o Servlet do Jersey.

<?xml version="1.0" encoding="UTF8"?>

<webapp><servlet>

<servletname>Jersey Web Application</servletname><servletclass>com.sun.ws.rest.spi.container.servlet.ServletContainer</servletclass><initparam><paramname>com.sun.ws.rest.config.feature.Redirect</paramname><paramvalue>true</paramvalue>

</initparam>

<initparam><paramname>com.sun.ws.rest.config.feature.ImplicitViewables</paramname><paramvalue>true</paramvalue></initparam>

<loadonstartup>1</loadonstartup>

</servlet>

<servletmapping><servletname>Jersey Web Application</servletname><urlpattern>/*</urlpattern></servletmapping>

</webapp>Além da configuração do Servlet, precisamos adicionar algumas bibliotecas para utilizar o Jersey. Oconjunto mínimo de bibliotecas que devem ser colocadas na aplicação inclui o jersey.jar, jsr311api.jare asm.jar. Estas bibliotecas e mais algumas dependências estão presentes no diretório /lib dadistribuição binária do Jersey.

Se não estiver usando Java SE 6 ou Java EE 5, você também precisará adicionar o JAXB ao projeto.Utilizando um servidor de aplicações Java EE 5 e as bibliotecas presentes na distribuição binária doprojeto, você tem a garantia de ter todas as dependências necessárias.

Desenvolvimento dos serviços

Page 11: Web Services REST (Java)

19/02/2015 Web Services REST

http://www.linhadecodigo.com.br/artigo/2059/webservicesrest.aspx 11/20

Mostraremos agora como pode ser feita a implementação de alguns serviços do processo de leilãocom o uso do Jersey. Somente um subconjunto dos serviços será apresentado neste artigo, mas aimplementação completa pode ser vista no código fonte.

Começaremos pelos serviços correspondentes ao prefixo /usuario e depois falaremos também sobreos serviços do prefixo /avaliacao. A Tabela 4 lista os serviços que apresentaremos neste artigo.

URI Método Formato Efeito

/usuario POST Usuario Cadastra um usuário.

/usuario/id

GET Usuario Busca um usuário.

PUT Usuario Atualiza um usuário.

/usuario/id/avaliacoes GETColeção deavaliações

Busca as avaliações recebidas porum usuário.

/usuario/id/itens

GETColeção de

itensBusca os itens anunciados por umdeterminado usuário.

POST Item Usuário coloca novo item à venda.

/avaliacao/id GET Avaliação Busca uma determinada avaliação.

/avaliacao/de/id/para/id POST AvaliaçãoRealização da avaliação de umusuário sobre outro.

A listagem abaixo apresenta a classe UsuarioResource. Esta é uma das classes Recurso da nossaaplicação e nela estão todos os serviços do prefixo /usuario. A classe foi anotada com@Path(”usuario”), o que faz a associação da mesma com o prefixo citado. Além disso, a classepossui as anotações @ConsumeMime e @ProduceMime, que neste caso declaram que os serviçosda mesma são capazes de consumir e gerar conteúdo nos formatos text/xml e application/json.

@Path("usuario")@ConsumeMime( "text/xml", "application/json" )

@ProduceMime( "text/xml", "application/json" )public class UsuarioResource

private ItemService itemService;private UsuarioService usuarioService;private AvaliacaoService avaliacaoService;

public UsuarioResource()

this.itemService = ServiceFactory.getItemService();this.usuarioService = ServiceFactory.getUsuarioService();

this.avaliacaoService = ServiceFactory.getAvaliacaoService();

@GET@Path("usuarioId")

public Response buscarUsuario(@PathParam("usuarioId") String usuarioId) Usuario usuario = usuarioService.buscar(usuarioId);

if(usuario == null)

Page 12: Web Services REST (Java)

19/02/2015 Web Services REST

http://www.linhadecodigo.com.br/artigo/2059/webservicesrest.aspx 12/20

return Response.status(HttpServletResponse.SC_NOT_FOUND).build();

Response resposta = Response.ok(usuario).build();return resposta;

@POSTpublic Response cadastrarUsuario(Usuario usuario) usuario = usuarioService.cadastrar(usuario);

try return Response.created(new URI(usuario.getCodUsuario())).build();

catch (URISyntaxException e) throw new RuntimeException(e);

@PUT@Path("usuarioId")public Response atualizarUsuario(Usuario usuario)

usuarioService.atualizar(usuario);return Response.ok().build();

@POST@Path("usuarioId/itens")public Response cadastrarItem(@Context UriInfo uriInfo, @PathParam("usuarioId") String usuarioId, Item item) throws URISyntaxException

Usuario usuario = new Usuario(usuarioId);item = itemService.cadastrar(item, usuario);URI uriItem = new URI(uriInfo.getBaseUri() + "item/" + item.getCodItem());

return Response.created(uriItem).build();

@GET@Path("usuarioId/itens")

public Response buscarItensDoUsuario(@PathParam("usuarioId") String usuarioId) // Verifica se o usuário existe

if (this.usuarioService.buscar(usuarioId) == null)

return Response.status(Status.NOT_FOUND).build();

List itens = itemService.buscarPorVendedor(new Usuario(usuarioId));

return Response.ok(new ItensUsuario(itens)).build();

@GET@Path("usuarioId/avaliacoes")public AvaliacoesUsuario buscarAvaliacoesDoUsuario(@PathParam("usuarioId")String usuarioId)

Usuario usuario = new Usuario(usuarioId);

Page 13: Web Services REST (Java)

19/02/2015 Web Services REST

http://www.linhadecodigo.com.br/artigo/2059/webservicesrest.aspx 13/20

List avaliacoes = avaliacaoService.buscarPorUsuario(usuario);

return new AvaliacoesUsuario(avaliacoes);

O primeiro serviço é o de busca de usuário. Este método foi anotado com @Path(”usuarioId”). Ocasamento da anotação sobre o método com a anotação sobre a classe especifica que este métodoresponde a requisições para a URI /usuario/usuarioId. Como o método também foi anotado com@GET, sabemos que as solicitações HTTP GET para /usuario/usuarioId serão tratadas por estemétodo. Importante reparar no uso da anotação @PathParam para injetar no parâmetro usuarioId ovalor que veio na URI.

Na resposta a esta solicitação, retornamos o status HTTP 200 (OK) e os dados do usuário no corpo daresposta. Caso o usuário não tenha sido encontrado, retornamos status 404 (Not Found). A listagemabaixo mostra a classe Usuario, que é manipulada por alguns serviços na classe UsuarioResource.Por simplicidade mostramos apenas a declaração da classe com os atributos.

@XmlRootElementpublic class Usuario

private String codUsuario;private String nome;private String login;private String email;

private Item[] items;private Oferta[] ofertas;private Avaliacao[] avaliacoes;

O segundo serviço presente em UsuarioResource é o de cadastro de usuário. Como não colocamosnenhuma anotação @Path sobre este método, ele está associado à URI da classe (/usuario). Ométodo foi anotado com @POST, então ele responde às solicitações POST na URI citada. O parâmetrocontendo os dados do usuário não recebeu nenhuma anotação, o que significa que ele é obtido docorpo da solicitação. Como o método de cadastro de usuário não tem as anotações @ConsumeMimee @ProduceMime, ele herda as declarações feitas sobre a classe. Sendo assim, podemos cadastrarusuários usando text/xml ou application/json. Na resposta à criação do usuário nós enviamos ostatus HTTP 201 (Created), colocando no header Location a URI do novo usuário.

O método de atualização de usuário recebe solicitações PUT em /usuario/usuarioId. Os dados dousuário também são consumidos do corpo da solicitação, e as operações com sucesso resultam noenvio do status HTTP 200.

No método de cadastrar itens, usamos a anotação @Path para associar o serviço à URI/usuario/usuarioId/itens. Usamos a anotação @PathParam para extrair da URI o ID do usuárioenvolvido. Usamos também a anotação @Context para injetar a classe UriInfo, que nos forneceinformações sobre a URI de acesso aos serviços. No final, usamos a UriInfo para colocar no headerLocation o caminho absoluto de acesso ao item recémcriado. A listagem abaixo mostra a classe Item,manipulada neste serviço.

@XmlRootElementpublic class Item private String codItem;private String nome;

private String descricao;private BigDecimal valorInicial;private boolean novo;private boolean vendido;

No método de buscar itens do usuário temos o primeiro serviço que manipula coleções. Este métodotrata de solicitações GET à URI /usuario/usuarioId/itens. Para retornar a lista de itens do usuário foicriada a classe ItensUsuario, que simplesmente contém a lista. A listagem a seguir apresenta adeclaração desta classe.

Page 14: Web Services REST (Java)

19/02/2015 Web Services REST

http://www.linhadecodigo.com.br/artigo/2059/webservicesrest.aspx 14/20

@XmlRootElementpublic class ItensUsuario

private List item;public ItensUsuario() public ItensUsuario(List itens) this.item = itens;

O método de buscar avaliações do usuário é estruturalmente semelhante ao de buscar itens. Foi criadaa classe AvaliacoesUsuario para retornar a lista de avaliações. Como esta é muito semelhante àItensUsuario, ela será omitida. Para implementar os serviços do prefixo /avaliacao foi criada a classeAvaliacaoResource. Esta classe pode ser vista na listagem a seguir. Temos a anotação @Pathregistrando a URI desejada e também as anotações @ConsumeMime e @ProduceMime declarandoque manipulamos text/xml e application/json.

@Path("avaliacao")@ConsumeMime( "text/xml", "application/json" )

@ProduceMime( "text/xml", "application/json" )public class AvaliacaoResource

private AvaliacaoService avaliacaoService;public AvaliacaoResource() this.avaliacaoService = ServiceFactory.getAvaliacaoService();

@GET@Path("avaliacaoId")public Response buscarAvaliacao(@PathParam("avaliacaoId") String avaliacaoId)

Avaliacao avaliacao = avaliacaoService.buscar(avaliacaoId);if(avaliacao == null)

return Response.status(HttpServletResponse.SC_NOT_FOUND).build();return Response.ok(avaliacao).build();

@POST@Path("de/avaliador/para/avaliado")public Response avaliarUsuario(@Context UriInfo uriInfo, @PathParam("avaliador") String avaliador,@PathParam("avaliado") String avaliado, Avaliacao avaliacao) throws URISyntaxException

Usuario usuarioAvaliado = new Usuario(avaliado);avaliacao = avaliacaoService.cadastrar(avaliacao, usuarioAvaliado);URI uri = new URI(uriInfo.getBaseUri() + "avaliacao/" + avaliacao.getCodAvaliacao());

return Response.created(uri).build();

O primeiro serviço desta classe é o de busca de avaliação, que é muito semelhante ao serviço debusca de usuário que vimos anteriormente. Este serviço ficou mapeado em /avaliacao/avaliacaoId,recebendo solicitações GET.

O serviço de avaliar usuário é mais interessante. Extraímos dois parâmetros da URI e consumimos umrecurso do corpo da solicitação. A URI /avaliacao/de/avaliador/para/avaliado é um bom exemploda liberdade que temos na definição das URIs. Podemos moldálas para aumentar a clareza dasoperações. Isto facilita a aproximação dos serviços com o nosso domínio da aplicação.

Page 15: Web Services REST (Java)

19/02/2015 Web Services REST

http://www.linhadecodigo.com.br/artigo/2059/webservicesrest.aspx 15/20

Criação de clientes Java para os serviços RESTExpusemos com bom nível de detalhe a implementação de serviços REST do lado do servidor. Parapermitir uma visão completa da comunicação, é muito importante falar também de clientes RESTful.

Uma vez que já temos o protocolo estabelecido, o papel do cliente é manipular as solicitações erespostas no formato acordado com o servidor. Para exemplificar como pode ser feito isso do lado docliente, apresentamos na listagem abaixo a classe OfertaTestREST, que realiza uma solicitação paracadastro de uma oferta sobre um item. O código deste teste foi feito para facilitar a ilustração do queestá sendo feito. Este é o motivo de imprimir os cabeçalhos e corpo tanto da requisição como daresposta HTTP.

public class OfertaTestREST extends TestCase

public void testCadastro() throws HttpException, IOException// Criamos o usuário

Usuario usuario = new Usuario();usuario.setNome("Usuario Artigo");usuario.setEmail("[email protected]");usuario.setLogin("artigo" + System.currentTimeMillis());UsuarioService usuarioService = ServiceFactory.getUsuarioService();usuario = usuarioService.cadastrar(usuario);

// Criamos o itemItem item = new Item();item.setDescricao("Item teste Artigo " + System.currentTimeMillis());item.setNome("Iphone");item.setNovo(true);item.setValorInicial(new BigDecimal(0));item.setVendido(false);ItemService itemService = ServiceFactory.getItemService();item = itemService.cadastrar(item, usuario);

// E agora a criação da Oferta de maneira RESTFulOferta oferta = new Oferta();oferta.setDataModificacao(new Date());oferta.setItem(item);oferta.setOfertante(usuario);oferta.setValor(new BigDecimal(111.22).setScale(2, RoundingMode.HALF_UP));

// Montando requisição com o commonshttpclientHttpClient client = new HttpClient();PostMethod method = new PostMethod("http://localhost:8080/item/" + item.getCodItem() + "/ofertas");

// Geração de XMLs com o XStreamXStream xstream = new XStream();xstream.alias("oferta", Oferta.class);xstream.alias("ofertante", Usuario.class);xstream.alias("item", Item.class);

String ofertaXml = xstream.toXML(oferta);System.out.println(ofertaXml);

// Definindo corpo da requisiçãoStringRequestEntity requestEntity = new StringRequestEntity(ofertaXml, "text/xml", "UTF8");method.setRequestEntity(requestEntity);

Page 16: Web Services REST (Java)

19/02/2015 Web Services REST

http://www.linhadecodigo.com.br/artigo/2059/webservicesrest.aspx 16/20

// Here it goes...int statusCode = client.executeMethod(method);

// Status HTTP deve ser 201 Created

assertEquals(HttpServletResponse.SC_CREATED, statusCode);

System.out.println("\n#### REQUISIÇÃO ####\n");

System.out.println(method.getName() + " " + method.getPath());Header[] headersRequest = method.getRequestHeaders();

for(Header header : headersRequest)System.out.println(header.getName() + " : " + header.getValue());

method.getRequestEntity().writeRequest(System.out);System.out.println("\n\n#### RESPOSTA ####\n");

System.out.println(method.getStatusLine().getHttpVersion() + " " + method.getStatusLine().getStatusCode());

Header[] headersResponse = method.getResponseHeaders();for(Header header : headersResponse)

System.out.println(header.getName() + " : " + header.getValue());

System.out.println(method.getResponseBodyAsString());

O formato da requisição HTTP gerada por esta classe pode ser visto na primeira listagem abaixo. Nalistagem seguinte pode ser conferido o formato da resposta HTTP a esta solicitação. A terceira listagemdesta sequência mostra o formato da resposta à busca de ofertas de um determinado item.

#### REQUISIÇÃO ####POST /item/13c017ba7c0144aa9a0bb815a9ea298f/ofertasUserAgent : Jakarta CommonsHttpClient/3.0.1Host : localhost:8080ContentLength : 596ContentType : text/xml; charset=UTF8<oferta> <valor>111.22</valor> <dataModificacao>20080928 10:36:54.642 BRT</dataModificacao>

<item> <codItem>13c017ba7c0144aa9a0bb815a9ea298f</codItem> <nome>Iphone</nome> <descricao>Item teste Tech Talk 1222609014628</descricao>

<valorInicial>0</valorInicial>

<novo>true</novo> <vendido>false</vendido> </item>

<ofertante> <codUsuario>fc6104adb9a54b2d9085a186083b9c2d</codUsuario> <nome>Usuario Tech Talk</nome>

Page 17: Web Services REST (Java)

19/02/2015 Web Services REST

http://www.linhadecodigo.com.br/artigo/2059/webservicesrest.aspx 17/20

<login>techtalk1222609014475</login>

<email>[email protected]</email> </ofertante> <vencedora>false</vencedora></oferta>#### RESPOSTA ####

HTTP/1.1 201Server : ApacheCoyote/1.1Location : http://localhost:8080/item/13c017ba7c0144aa9a0bb815a9ea298f/ofertasContentLength : 0Date : Sun, 28 Sep 2008 13:36:55 GMTA implementação das solicitações HTTP em Java pode ser feita com uso da biblioteca commonshttpclient. Esta API permite que montemos requisições HTTP e recebamos suas respostascorrespondentes, da mesma forma que ocorreria com um browser simples. Não existe a capacidade deexecutar código javascript e também não existem equivalentes para os plugins dos browserscompletos. Mesmo sem estes recursos, o commonshttpclient nos dá o poder de fazer praticamentequalquer operação padrão HTTP do lado cliente. Isto torna esta biblioteca um componente defundamental importância para implementações RESTful feitas em Java.

Clientes Ajax/JSONQuando falamos em web services a primeira idéia sobre o formato para troca das informações é oXML. Porém, outros formatos para troca de dados existem e podem atender melhor a alguns casosparticulares.

Um destes formatos é o JSON. Ele tem se difundido bastante, especialmente como uma alternativa aoXML em AJAX, pois é um formato nativamente suportado por qualquer interpretador javascript. Outromotivo é que é um formato mais “enxuto”, gerando documentos menores e mais fáceis consumir. Porestas vantagens, tem sido comum o uso de JSON para criar clientes AJAX de serviços REST.

Na listagem abaixo apresentamos um exemplo de função javascript que busca itens de um usuárionum serviço REST e apresenta os mesmos em uma tabela. Mostramos apenas os trechos maisrelevantes. O leitor pode obter o código completo dos exemplos de clientes ajax no site da revista. Alistagem seguinte apresenta a definição de uma função que faz uma requisição HTTP GET assíncronaa um serviço REST.

<script type="text/javascript">

function mostrarItens() // Faz a chamada restvar url = "/usuario/" + document.getElementById("cod_usuario").value + "/itens";

var tabela = document.getElementById("itens");var response = RESTFul.get(url);

if (response.status != 200) tabela.innerHTML = "<b>Usuário não encontrado!</b>";

return;

var itensUsuario = response.getObject();var stringitens = "<table border="1">";stringitens += "<thead><td>codigo</td><td>descrição</td><td>nome</td><td>novo</td>"

+"<td>valor inicial</td><td>vendido</td></thead>";for (i in itensUsuario.itensUsuario.item)

var item = itensUsuario.itensUsuario.item[i];stringitens += "<tr><td>// requisição Ajax para HTTP GETget: function (url, request)

Page 18: Web Services REST (Java)

19/02/2015 Web Services REST

http://www.linhadecodigo.com.br/artigo/2059/webservicesrest.aspx 18/20

// cria um XmlHttpRequestxmlhttp = getXTR();// constrói um request defaultif (!request) request = new RESTFul.Request();

xmlhttp.open("GET",url,false); // requisição GET assíncronaxmlhttp.setRequestHeader("Accept","application/json");xmlhttp.send(null); // requisição sem corpo

while (xmlhttp.readyState != 4);var response =new RESTFul.Response(xmlhttp.status, xmlhttp.statusText, xmlhttp.getAllResponseHeaders(), xmlhttp.responseText);

return response;

Web Application Description Language (WADL)Há muita discussão a respeito de interfaces de descrição de serviços REST. Há quem julgue que elasnão são necessárias. Outros acham interessante ter um “equivalente” do WSDL para REST.

Consideramos que é conveniente oferecer uma interface simples de consulta dos serviços disponíveis,mas sem tantos detalhes como o WSDL. Uma das opções disponíveis para isso é o WADL. O WADLinforma quais são as URIs disponíveis, os métodos permitidos em cada uma delas, e os parâmetros deentrada e saída dos serviços.

O Jersey gera automaticamente um WADL dos nossos serviços a partir de nossas classes Recurso.Consideramos este documento bom o suficiente para não valer a pena gerar algo semelhante de formacustomizada. Mais detalhes sobre os serviços podem ser colocados numa Wiki ou página semelhante.A geração do WADL é uma funcionalidade específica do Jersey, e não está presente na JSR311.

Para acessar o WADL correspondente aos nossos recursos, devemos fazer uma solicitação HTTP GETà URI /application.wadl, na raiz da nossa aplicação. Isto é conveniente por permitir a fácil visualizaçãocom um browser. Veja o documento WADL dos serviços do processo de leilão.

Suporte de ferramentasUm dos pontos positivos dos web services WS* é que já existe um amplo conjunto de ferramentaspara facilitar o trabalho com esta linha de serviços. Geradores de clientes e esqueletos de serviçoestão disponíveis para várias plataformas e linguagens.

Os web services REST tiveram que esperar muito mais tempo para terem as primeiras ferramentas dedesenvolvimento. Não devemos ver isso como um ponto negativo. Se existem muitos produtos paramelhorar o trabalho com WS* é porque as tecnologias envolvidas exigem isso.

Os serviços REST são essencialmente mais simples e concentram seus detalhes principais em tornode HTTP. Como as tecnologias utilizadas com REST já são muito maduras e conhecidas, indiretamentejá havia um ótimo suporte a este desenvolvimento.

Recentemente o NetBeans introduziu plugins focados em serviços REST, e estes contribuem com umganho de produtividade no começo do desenvolvimento. Somos capazes de gerar classes Recurso apartir de entidades JPA e também gerar clientes Java e Javascript para nossos serviços. Estasfuncionalidades ajudam na rápida criação de protótipos, e oferecem um bom ponto de partida naimplementação. Detalhes sobre o suporte do NetBeans ficam fora do escopo deste artigo, masrecomendamos que os leitores avaliem os benefícios que este IDE traz.

ConclusãoO objetivo deste artigo foi partir de um exemplo rico o suficiente de arquitetura orientada a serviços eentão fazer a modelagem e desenvolvimento dos mesmos com uso de uma abordagem RESTful.Através do exemplo do leilão do Mercado Livre, fomos capazes de percorrer todas as etapas

Page 19: Web Services REST (Java)

19/02/2015 Web Services REST

http://www.linhadecodigo.com.br/artigo/2059/webservicesrest.aspx 19/20

envolvidas na implementação de web services REST. Entre estas etapas podemos destacar aidentificação dos recursos, mapeamento de URIs, definição do protocolo de comunicação e formas demapeamento de Java para XML e XML para Java.

Foi possível ilustrar bem como o bom uso dos recursos do HTTP podem ajudar na definição de umprotocolo de comunicação conciso e claro. Elementos já conhecidos como os status e métodos HTTP,URIs e ContentTypes passam a ser utilizados para comunicações bem mais diversas do que atransferência simples de HTML.

Com o amadurecimento das implementações REST, estamos caminhando na direção de soluçõespoderosas e interoperáveis. Até alguns anos atrás, a adoção de web services representava uma trocade performance por interoperabilidade. Piorar a performance na comunicação com a mesmaplataforma e linguagem para ser capaz de falar com qualquer outro serviço.

Isto felizmente está deixando de ser verdade. Estamos conquistando poder suficiente para ter aomesmo tempo alta performance e interoperabilidade.

A JSR311 e o Jersey trazem benefícios interessantes, e não nos tiram o poder do REST. A introduçãodestes componentes simplifica o desenvolvimento. Além disso, ganhamos funcionalidades que seriammuito trabalhosas de implementar de forma customizada. A capacidade de manipular múltiplosformatos e a geração do WADL são bons exemplos disso.

Esperamos que este artigo tenha contribuído com novas idéias para os leitores no desenvolvimento deserviços REST. Esta linha de serviços vem amadurecendo progressivamente e já se apresenta comouma opção poderosa para integração entre aplicações.

Pretendo publicar vários outros artigos na área de web services, integração e tecnologias relacionadas,então se você gostou deste artigo, acompanhe sempre as novidades por aqui

Bruno Luiz Pereira da Silva » Visite o site do autor: http://brunopereira.org/.

Engenheiro eletrônico e de computação de 26 anos que se frustrou com aeletrônica e se apaixonou por software. Trabalha com software desde 2003 (sem

contar o período acadêmico) e com Java desde o começo de 2004. Se interessa bastante pordiversas áreas distintas, como linguagens de programação, open source, sistemas operacionais,processo de desenvolvimento, computação distribuída, SOA e Java em geral.

Trabalha há 2 anos e meio na Concrete Solutions, atuando na Globo.com (mais precisamentena área do ISP) desde minha chegada à empresa. Atualmente é também colunista da JavaMagazine, com foco principal em Java EE e Web Services em geral.

Leia tambémConhecendo a interface Map do JavaJava

Trabalhando com a Interface Set no JavaJava

Classes Wrappers em JavaJava

ComboBoxModel em JavaJava

Reduzindo a Mutabilidade em JavaJava

0 6Like

Estamos aqui:

49 11 0 32

Page 20: Web Services REST (Java)

19/02/2015 Web Services REST

http://www.linhadecodigo.com.br/artigo/2059/webservicesrest.aspx 20/20

Linha de Código faz parte do grupo Web03 Política de privacidade e de uso | Anuncie | Cadastrese | Fale conosco

Linha de Código

12.256 pessoas curtiram Linha de Código.

Plugin social do Facebook

Curtir

© 2015 Linha de Código. Todos os direitos reservados