Blog

Criando e consumindo WebServices REST em Java


Assim como explicado no artigo "Criando e consumindo WebServices SOAP em Java" é muito comum que cada vez mais analistas optem por utilizar uma arquitetura distribuída e busquem tornar seus projetos prontos para operarem em multiplataformas. Evidentemente, existem muitas práticas necessárias para atingir este objetivo e, portanto, não se trata apenas de uma prática ou outra, mas sim o conjunto delas. Neste artigo apenas será abordado uma das tecnologias disponíveis para isso.

Para tornar mais fácil a compreensão da tecnologia, foi utilizado um exemplo de uma consulta de endereço por CEP com apenas um método com um retorno fixo simples. 


package com.joaofelipe.cep;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Endereco {

    public String estado;
    public String cidade;
    public String bairro;
}


Nota-se no código a seguir, que foi criada uma interface que possui apenas um método, "consultar". Este método apresenta a anotação "@Get", indicando que o método será acessível diretamente via GET. A anotação "@Path" define a rota a qual este método estará escutando e, portanto, não deverão existir rotas coincidentes. A notação "@Produces(MediaType.APPLICATION_JSON)" indica a forma a qual os dados serão retornados para o cliente, neste caso conteúdo em formato Json. A notação "@Consumes(MediaType.APPLICATION_JSON)" define como os dados serão aceitos quando vindos do cliente, neste caso conteúdo em formato Json.

A classe também possui uma anotação "@Path" para definir a rota referente a ela. As demais anotações também poderiam ser anotadas diretamente na classe, o que faria com que os métodos assumissem este mesmo comportamento, exceto se eles também tivessem a anotação com uma informação diferente.


package com.joaofelipe.cep;

import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

@Path("/cep")
public class CepService {

    @GET
    @Path("/consultar/{param1}")
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.APPLICATION_JSON)
    public Endereco consultar(@PathParam("param1") int cep) {

        Endereco endereco = new Endereco();
endereco.estado = "BA"; endereco.cidade = "Salvador"; endereco.bairro = "Pituba"; return endereco; } }


Para rodar o serviço (servidor) foi utilizado o Jersey e o Grizzly, conforme exemplo a seguir:


package com.joaofelipe.cep;

import java.util.HashMap;
import java.util.Map;

import com.sun.grizzly.http.SelectorThread;
import com.sun.jersey.api.container.grizzly.GrizzlyWebContainerFactory;

public class CepServicePublisher {

    public static void main(String[] args) {        
        final String baseUri = "http://localhost:7080/";
        final Map initParams = new HashMap();

        // Register the package that contains your javax.ws.rs-annotated beans here
        initParams.put("com.sun.jersey.config.property.packages","com.joaofelipe.cep");

        System.out.println("Starting grizzly...");
        try {
            SelectorThread threadSelector = GrizzlyWebContainerFactory.create(baseUri, initParams);
            System.out.println(String.format("Jersey started with WADL " + "available at %sapplication.wadl.", baseUri));
        }
        catch(Exception e) {
            e.printStackTrace();
        }
    }
}


A biblioteca Jersey pode ser baixada via maven ou diretamente pelo site:

<!-- https://mvnrepository.com/artifact/com.sun.jersey/jersey-bundle -->
<dependency>
    <groupId>com.sun.jersey</groupId>
    <artifactId>jersey-bundle</artifactId>
    <version>1.19.2</version>
</dependency>


A biblioteca Grizzly pode ser baixada via maven ou diretamente pelo site:

<!-- https://mvnrepository.com/artifact/com.sun.grizzly/grizzly-servlet-webserver -->
<dependency>
    <groupId>com.sun.grizzly</groupId>
    <artifactId>grizzly-servlet-webserver</artifactId>
    <version>1.9.64</version>
</dependency>

Para consumir o WebService REST é possível acessar diretamente o servidor via URL, como no exemplo a seguir:


http://localhost:7080/cep/consultar/41810215


Ainda assim, é possível consumir o serviço diretamente em outro projeto, por exemplo, utilizando a biblioteca JAX-RS, podendo ser realizado da seguinte forma:


package com.joaofelipe.cep;

import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.WebTarget;

public class CepClient {

    public static void main(String[] args) {

        Endereco endereco = consultar(41810215);

        System.out.println("Estado: " + endereco.estado);
        System.out.println("Cidade: " + endereco.cidade);
        System.out.println("Bairro: " + endereco.bairro);
    }

    public static Endereco consultar(int cep) {

        Client client = ClientBuilder.newClient();

	WebTarget target = client.target("http://localhost:7080/cep/consultar/" + cep);

	Endereco endereco = target.request().get(Endereco.class);

        return endereco;
    }
}


A biblioteca JAX-RS pode ser baixada via maven ou diretamente pelo site:

<!-- https://mvnrepository.com/artifact/javax.ws.rs/javax.ws.rs-api -->
<dependency>
    <groupid>javax.ws.rs</groupid>
    <artifactid>javax.ws.rs-api</artifactid>
    <version>2.0</version>
</dependency>



No fim seu projeto deve ficar divido de forma semelhante a apresentada acima. Importante observar que neste exemplo o projeto "rest-common" é utilizado pelos demais projetos "rest-server" e "rest-client".

REST Java WebService