• Nenhum resultado encontrado

Aula 25: Web Services (III)

N/A
N/A
Protected

Academic year: 2021

Share "Aula 25: Web Services (III)"

Copied!
39
0
0

Texto

(1)

Aula 25: Web Services (III)

Diego Passos

Universidade Federal Fluminense

(2)

Última Aula

A API JAX-WS.

I Como escrever Big Web Services.

I Montagem e disponibilizaçao.

I Geração dos artefatos.

I Como escrever um cliente. I Mapeamento de tipos de dados.

(3)

Aula de Hoje

RESTful Web Services: I Visão geral.

I A API JAX-RS.

I Como escrever RESTful Web Services.

I Tipos de anotações utilizadas.

I Provedores de Entidades.

I Recebendo parâmetros.

(4)

RESTful Web Services: Visão Geral

Até agora, discutimos um tipo específico de Web Services: os Big Web Services.

I Padrão do W3C.

I Baseado em SOAP, XML.

I Relativamente complexos.

Uma alternativa em voga atualmente são os RESTful Web Services. I Baseados no padrão arquitetural REST (Representational State Transfer ).

I Abstração da arquitetura da Web.

I O padrão REST determina uma série de restrições na iteração entre os componentes do sistema.

(5)

RESTful Web Services: Visão Geral (II)

Exemplos de restrições impostas pelo padrão REST: I Modelo cliente-servidor.

I Comunicação stateless.

I Respostas podem ser cacheadas.

I Interface uniformizada dos serviços.

F Uso de URIs (identificam funcionalidades e recursos).

F Mensagens auto-descritivas (contém toda a informação necessária para entendê-las; não sendo necessário estado).

(6)

RESTful Web Services: Visão Geral (III)

Em termos práticos, a diferença entre Big Web Services e RESTful Web Services está na padronização.

Os Big Web Services são padronizados e por isso demandam a geração de inúmeros artefatos.

I Como o arquivo WSDL, por exemplo.

O conceito de RESTful Web Service é bem mais flexível.

I Qualquer serviço ofertado pela Web que esteja de acordo com as restrições arquiteturais REST.

Esta liberdade faz com que seja mais fácil desenvolver um Web Service do tipo REST. I Por outro lado, é difícil elaborar uma API genérica, especialmente do lado do cliente.

(7)

RESTful Web Services: JAX-RS

O J2EE inclui uma API para auxiliar na criação de RESTful Web Services.

I JAX-RS.

I Análoga à JAX-WS.

Utiliza bastante o conceito de anotações.

I Desenvolvedor anota classes e métodos definindo recursos e ações que podem ser executadas.

As anotações do JAX-WS são de tempo de execução.

I São interpretadas por um servidor de aplicação para gerar as classes auxiliares necessárias para implantar o Web Service.

(8)

JAX-RS: Anotações

Há um grande número de anotações na API. Alguns exemplos:

@Path:

I Identifica a URL para a qual a classe será mapeada.

I O atributo especificado para esta anotação será usado como o sufixo da URI.

F Considerando o endereço base do servidor.

@GET:

I Um método anotado com esta anotação processará requisições HTTP do tipo GET. I Há anotações para outros métodos como @POST, @PUT, @DELETE, @HEAD.

(9)

JAX-RS: Anotações (II)

@Produces:

I Define o tipo MIME da resposta gerada pelo serviço.

I e.g., “plain/text”, “application/json”.

@Consumes:

I Define o tipo MIME da entrada provida pelo cliente.

(10)

JAX-RS: Exemplo de Código

importjavax.ws.rs.GET; importjavax.ws.rs.Produces; importjavax.ws.rs.Path;

// The Java class will be hosted at the URI path "/helloworld" @Path("/helloworld")

public classHelloWorldResource{

// The Java method will process HTTP GET requests @GET

// The Java method will produce content identified by the MIME Media // type "text/plain"

@Produces("text/plain")

publicStringgetClichedMessage() { // Return some cliched textual content return"Hello World";

} }

Web Service servido na URL (relativa) /helloworld.

Requisições HTTP do tipo GET resultam em chamadas ao método getClinchedMessage().

(11)

JAX-RS: Exemplo de Código (II)

E se precisarmos receber conteúdo do usuário?

@POST

@Consumes("text/plain")

publicvoidpostClichedMessage(String message) { // Store the message

}

(12)

JAX-RS: A Anotação @Path e Templates

Vimos um uso bastante simplificado da anotação @Path.

I Ela recebia como atributo uma String especificando uma URL estática (/helloworld). Esta anotação, no entanto, é bem mais poderosa.

Ela permite que especifiquemos templates.

Estes templates podem ser usados, por exemplo, para usarmos parte de uma URL como uma variável/parâmetro.

(13)

JAX-RS: A Anotação @Path e Templates (II)

Considere o seguinte exemplo:

I Queremos criar um Web Service para consultar informações sobre usuários de um sistema.

I O Web Service será mapeado para a URL /users/.

I O cliente deve especificar o nome do usuário (do qual quer obter informações).

I Uma opção seria colocar o nome do usuário no corpo da requisição.

I Ao invés disso, podemos usar uma solução baseada em templates:

@Path("/users/{username}") public classUserResource {

@GET

@Produces("text/xml")

publicStringgetUser(@PathParam("username")String userName) { ...

} }

A sintaxe {username} cria uma variável username.

Se o cliente acessa a URL /users/diego esta variável terá o valor diego. Esta variável pode ser acessada pelos métodos.

(14)

JAX-RS: A Anotação @Path e Templates (III)

É possível ainda especificar o formato das variáveis através de expressões regulares. Suponha no exemplo anterior que nomes de usuário só podem ser compostos por letras e números.

Podemos restringir isso com a seguinte declaração:

@Path("/users/{username: [a-zA-Z][a-zA-Z0-9]*}") public classUserResource {

@GET

@Produces("text/xml")

publicStringgetUser(@PathParam("username")String userName) { ...

} }

Se tentamos acessar a URL /users/diego3, o acesso é bem sucedido. Se tentamos acessar a URL /users/diego_passos, recebemos um erro 404.

(15)

JAX-RS: A Anotação @Path e Templates (IV)

Também podemos definir um template com mais de uma variável. Exemplo: queremos nome e sobrenome do usuário.

@Path("/users/{nome}/{sobrenome}") public classUserResource {

@GET

@Produces("text/plain")

publicStringgetUser(@PathParam("nome")String nome,@PathParam("sobrenome")String sobrenome) { return"Nome completo: "nome+" "+sobrenome;

} }

(16)

JAX-RS: A Anotação @Path e Templates (V)

Algumas outras observações:

I Uma mesma variável pode ser especificada múltiplas vezes em uma anotação @Path. F Exemplo: @Path("/users/{nome}/{nome}").

F Neste caso, só serão aceitas requisições a URLs cujos dois últimos componentes sejam iguais.

I Variáveis podem ser vazias. Exemplo:

F @Path("/users/{nome}/home").

F Cliente acessa URL /users//home.

F Variável nome ganha o valor “” (String vazia).

I Note ainda que a anotação @Path pode ser usada para métodos específicos. F Aquele método será mapeado para aquela URL.

(17)

JAX-RS: Anotações Designadoras de Métodos de Requisição

São anotações utilizadas para associar um método HTTP a um método da classe. Vimos exemplos de uso de duas: @GET e @POST.

São também suportadas: I @PUT: incluir um recurso. I @DELETE: remover um recurso. I @HEAD: informações sobre um recurso.

Os métodos HTTP HEAD e OPTIONS são suportados por padrão, mesmo se não implementados explicitamente.

I Implementação padrão do HEAD retorna o mesmo que a implementação do GET, sem o conteúdo.

(18)

JAX-RS: Anotações Designadoras de Métodos de Requisição (II)

A implementação do OPTIONS é mais interessante.

Ela retorna (como esperado) o conjunto de requisições que são suportadas. Mas também retorna um documento WADL:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <applicationxmlns="http://wadl.dev.java.net/2009/02">

<docxmlns:jersey="http://jersey.java.net/"jersey:generatedBy="Jersey: 2.10.4 2014-08-08 15:09:00"/> <grammars/>

<resourcesbase="http://172.16.10.75:8080/WebService2/services/"> <resourcepath="BasicPost">

<methodid="postClinchedMessage"name="POST"> <request>

<representationmediaType="text/plain"/> </request>

<response>

<representationmediaType="text/plain"/> </response>

</method> </resource> </resources> </application>

(19)

JAX-RS: Anotações Designadoras de Métodos de Requisição (III)

O WALD é um formato de documento utilizado para descrever aplicações Web em geral. I Hoje, o exemplo mais comum de uso é com os RESTful Web Services.

Provê informação sobre as operações oferecidas. I Parâmetros esperados.

I Formato da entrada.

I Formato da resposta.

(20)

JAX-RS: Anotações Designadoras de Métodos de Requisição (IV)

Não há uma assinatura definida para os métodos de requisição.

I Eles podem receber inúmeros parâmetros (e.g., extraídos do template da anotação @Path). I Eles podem ter vários tipos de retorno diferentes.

Mas há algumas restrições:

I O tipo de retorno deve ser void, um tipo básico de Java, ou um

javax.ws.rs.core.Response.

(21)

JAX-RS: Incluindo Metadados nas Respostas

Isso é feito com as classes Response e ResponseBuilder. Exemplo de funcionalidades:

I Definição de cookies.

I Definição de headers.

I Definição de código de status. I Definição do media type.

Exemplo de código:

@Path("/users/{nome}/{sobrenome}") public classUserResource {

@GET

@Produces("text/plain")

publicResponsegetUser(@PathParam("nome")String nome,@PathParam("sobrenome") { returnResponse.status(404).entity("User not found").build();

} }

(22)

JAX-RS: Provedores de Entidades

Suponha que desejemos escrever um Web Service que adiciona um usuário a uma base de dados.

Usuários têm as seguintes propriedades: I Nome completo.

I Apelido.

I Data de nascimento.

I CPF.

I Senha.

Temos uma classe User com esta representação.

O Web Service recebe estes dados no corpo de uma requisição POST. Como obter, a partir da requisição, um objeto do tipo User?

(23)

JAX-RS: Provedores de Entidades (II)

Primeira abordagem: receber o corpo da requisição como texto e fazer o parse. Código resultante:

@POST

@Consumes("text/plain") @Produces("text/plain")

publicStringpostClichedMessage(String message) { User u=newUser();

// Parse da mensagem e preenchimento do objeto. ...

// Adição do usuário à base. ...

// Envio da resposta ao usuário. ...

}

Há muita coisa sendo feita neste método.

Note também que a assinatura do método é enganosa:

I Implicitamente, o método espera que o corpo da mensagem seja um User. I Ou melhor, sua representação em texto.

(24)

JAX-RS: Provedores de Entidades (III)

Podemos implementar isso de outra forma: usando um provedor de entidade. Exemplo de código:

@Provider

@Consumes("text/user")

public classUserUnmarshaller implementsMessageBodyReader{ @Override

publicbooleanisReadable(Class aClass,Type type,Annotation[]annotations,MediaType mediaType) { return true;

} @Override

publicObjectreadFrom(Class aClass,Type type,Annotation[]annotations,MediaType mediaType,

MultivaluedMap multivaluedMap,InputStream inputStream)throwsIOException,WebApplicationException{ User result =null;

try{

// Parse da mensagem (lida do inputStream). // Resultado deve ser colocado no objeto result. // ... }catch(Exception e) { e.printStackTrace(); } returnresult; } }

(25)

JAX-RS: Provedores de Entidades (IV)

A classe do slide anterior implementa um decodificador para o tipo de mídia text/user. I Fictício, criado para este exemplo.

Tendo a classe UserUnmarshaller carregada, podemos usar este tipo de mídia para tornar transparente o parse dos dados:

@POST

@Consumes("text/user") @Produces("text/plain")

publicStringpostClichedMessage(User u) {

// Já recebemos automaticamente uma instância de User preenchida com os dados da requisição. // Basta fazer a inserção no banco.

...

// Envio da resposta ao usuário. ...

(26)

JAX-RS: Provedores de Entidades (V)

Podemos fazer também o processo inverso. I Na resposta, enviamos um User.

I Ou melhor, sua representação textual.

Novamente, ao invés de fazer o próprio método, escrevemos um provedor de entidade. Neste caso, no entanto, como se trata de uma resposta, o provedor precisa fazer a operação contrária.

(27)

JAX-RS: Provedores de Entidades (VI)

Para tipos mais comuns, a JAX-RS já provê provedores de entidades padrão. Estes provedores mapeiam tipos comuns do Java a tipos de mídia comuns. Por exemplo:

I byte[] ↔ */*.

I String ↔ text/*.

I File ↔ */*.

I MultivaluedMap<String,String> ↔ application/x-www-form-urlencoded. Para usá-los, basta definir o método com os tipos de parâmetro/retorno adequados aos tipos de mídia.

(28)

JAX-RS: Anotação @Produces

Como visto nos exemplos anteriores, esta anotação declara o tipo de conteúdo que é produzido por um dado método.

A anotação também pode ser usada na declaração da classe.

I Neste caso, todos os métodos podem produzir o tipo especificado de conteúdo.

I Se um método específico declara a anotação, esta se sobrepõe à anotação da classe.

Note que a anotação define os tipos de dados que podem ser gerados pelos métodos. I Por isso, a anotação pode conter mais de um tipo.

(29)

JAX-RS: Anotação @Produces

Quando um cliente envia uma requisição, ele pode especificar um conjunto de formatos aceitáveis.

Neste caso, o JAX-RS procura entre todos os métodos que atendem àquele tipo de requisição o que se encaixa melhor ao que o cliente requisitou.

I Se nenhum método se encaixa, servidor retorna um erro 406.

Exemplo:

@Path("/myResource") @Produces("text/plain") public classSomeResource {

@GET

publicStringdoGetAsPlainText() { ...

} @GET

@Produces("text/html") publicStringdoGetAsHtml() {

... } }

(30)

JAX-RS: Anotação @Consumes

Também já vista em exemplos anteriores.

Equivalente à @Produces para dados de entrada. Segue as mesmas convenções da anotação @Produces:

I Pode ser aplicada a uma classe inteira.

I Pode receber mais de uma especificação de formato de dados.

I JAX-RS utiliza para identificar qual o método (mais) adequado para tratar uma requisição.

De forma similar à anotação @Produces, se nenhum método declara consumir um dado formato, é retornado um erro 415.

(31)

JAX-RS: Recebendo Parâmetros

Vimos anteriormente um exemplo de obtenção de parâmetros através da URL. I Definimos um template usando a anotação @Path.

I Declaramos parâmetros de métodos usando a anotação @PathParam.

Mas existem muitas maneiras de um cliente codificar seus parâmetros em uma requisição HTTP: I Query. I Form. I Cookies. I Headers. I Matrix.

(32)

JAX-RS: Query Parameters

São parâmetros passados em uma URL explicitamente.

I Exemplo: http://servidor/webservice/user?username=diego&action=remove Podemos acessar estes parâmetros com a anotação @QueryParam.

I Podemos ainda definir valores padrão com a anotação @DefaultValue. F Usados em caso de omissão.

@Path("smooth") @GET

publicResponsesmooth(

@DefaultValue("2")@QueryParam("step")intstep, @DefaultValue("true")@QueryParam("min-m")booleanhasMin, @DefaultValue("true")@QueryParam("max-m")booleanhasMax, @DefaultValue("true")@QueryParam("last-m")booleanhasLast, @DefaultValue("blue")@QueryParam("min-color")ColorParam minColor, @DefaultValue("green")@QueryParam("max-color")ColorParam maxColor, @DefaultValue("red")@QueryParam("last-color")ColorParam lastColor ) { ... }

(33)

JAX-RS: Query Parameters

Há restrições em relação aos tipos dos parâmetros. Só se pode usar tipos com as seguintes características:

I Tipos primitivos, exceto char.

I Classes correspondentes a tipos primitivos, exceto Character.

I Qualquer classe com construtor que recebe um único argumento do tipo String.

I Qualquer classe com um método estático valueOf(String).

I List<T>, Set<T>, SortedSet<T>, onde T cai em um dos casos anteriores. F Usado para atributos multi-valorados.

Caso não seja possível mapear o valor presente na URL para o tipo do parâmetro, é gerado um erro 400.

(34)

JAX-RS: Outros Tipos de Parâmetros

Há suporte para as seguintes outras anotações relacionadas a parâmetros: I @CookieParam: associa um parâmetro a um cookie enviado pelo cliente.

I @HeaderParam: associa um parâmetro a um header da requisição.

I @FormParam: associa um parâmetro a um campo de formulário enviado pelo cliente.

I @MatrixParam: associa um parâmetro ao matrix parameter correspondente.

F Matrix parameters são similares aos query parameters.

F Mas permitem diferenciar parâmetros por nível da URL.

F Exemplo: http://servidor/webservice/categoria;nome=frutas/objetos;nome=abacaxi

I Em todos os casos, a correspondência é feita pelo nome.

F Nome do parâmetro declarado no método deve bater com o nome do cookie/header/...

Note que, no caso do @FormParam, o tipo de conteúdo deve ser application/x-www-form-urlencoded.

(35)

JAX-RS: A Anotação @Context

Anotação especial que pode ser usada em certos parâmetros de um método. Permite obter “informações contextuais”.

I Referências a objetos específicos que contem informações sobre a requisição.

Exemplo:

I Objeto UriInfo: permite obtenção de informações sobre a URL. I Objeto HttpHeaders: permite acesso mais direto aos headers.

(36)

JAX-RS: A Anotação @Context (II)

Exemplo de código:

@GET

publicStringget(@ContextUriInfo ui,@ContextHttpHeaders hh) { MultivaluedMap<String,String>queryParams=ui.getQueryParameters(); MultivaluedMap<String,String>pathParams=ui.getPathParameters(); MultivaluedMap<String,String>headerParams=hh.getRequestHeaders(); Map<String,Cookie>pathParams=hh.getCookies();

...

returnui.getAbsolutePath().toString(); }

(37)

JAX-RS vs. Servlets

De certa forma, a JAX-RS é bem parecida com os Servlets HTTP. I Ambos permitem criar aplicações Web.

I Escrevemos uma classe que é mapeada para uma ou mais URLs.

I Métodos específicos nesta classe são chamados pelo container quando tipos específicos de requisição são recebidas.

I Podemos manipular parâmetros, cookies, headers... Qual a diferença, então?

(38)

JAX-RS vs. Servlets (II)

A resposta é não.

Servlets são componentes capazes de tratar requisições (tipicamente HTTP) em um nível bastante baixo.

I É possível manipular todos os aspectos das requisições e respostas, desde que obedecidas as

regras do protocolo HTTP.

I Podemos, por exemplo, criar um Web Service RESTful.

A JAX-RS é uma API especificamente dedicada a criação de serviços RESTful. I Temos controle sobre muita coisa, mas dentro das limitações arquiteturais REST.

I Por exemplo, não podemos (ou não deveríamos) guardar estado interno sobre os clientes através de sessões.

Em suma:

I É mais fácil implementarmos serviços RESTful com a JAX-RS.

(39)

Referências

Conteúdo e exemplos baseados em: I Tutorial da Oracle sobre Web Services.

Referências

Documentos relacionados

Diversidade sexual na escola: currículo e prática pedagógica / Alexandre Bortolini ; orientadora: Vera Maria Candau.. Candau,

Atente-se aos exercícios explicativos de cada conteúdo desenvolvido nas aulas on-line, bem como as atividades semanais e/ou quinzenais do caderno!!..

 Iguatemi São Paulo: As Receitas de Aluguéis cresceram 8,5% principalmente por um Aluguel Mínimo maior, devido a.. reajuste

• O aluno que não for aprovado na prova final, deverá fazer a recuperação final com conteúdo relacionado à matéria do 2º semestre, onde todas as

Os valores de energia de ativação se apresentaram superiores para as amostras com incorporação da fibra de sisal, enquanto que a incorporação da fibra de vidro demonstrou

Ocorre adequada transposição de um segmento do texto para a voz passiva, mantendo-se a coerência da frase original, em:.. (A) Dois indivíduos (...) estão enraivecidos //

a) velocidade da chuva em relação ao solo; b) velocidade da chuva em relação ao carro. A haste encontra-se ini- cialmente em repouso, com o seu comprimento ao longo da

Para isso em quatro experimentos foram avaliadas: as características fisiológicas de cultivares de mandioca após a aplicação do mesotrione; a interferência do