SD 2018-Q2 - Prática
Prática Aula 03 - Uma Breve Introdução a REST em Java

Segundo Quadrimestre de 2018
Professor: Emilio Francesquini
E-mail: e.francesquini@ufabc.edu.br

Índice



Referências

O código abaixo implementa um simples servidor de contatos baseado em REST. Os exemplos são adaptados de um apanhado de diversos locais, incluindo:


Downloads


Código

Email


Download do .java:

Email.java

package sd;

public class Email {

    private String tipo;
    private String endereco;

    public Email() {}

    public Email(String tipo, String endereco) {
        this.tipo = tipo;
        this.endereco = endereco;
    }

    public String getTipo() {
        return tipo;
    }

    public void setTipo(String tipo) {
        this.tipo = tipo;
    }

    public String getEndereco() {
        return endereco;
    }

    public void setEndereco(String endereco) {
        this.endereco = endereco;
    }

    public String toString() {
        StringBuilder email = new StringBuilder();
        email.append("{ ");
        email.append(getTipo() + ":" + getEndereco());
        email.append(" }");

        return email.toString();
    }
}

Telefone

Download do .java:

Telefone.java

package sd;

public class Telefone {

    private String tipo;
    private String numero;

    public Telefone() {}

    public Telefone(String tipo, String numero) {
        this.tipo = tipo;
        this.numero = numero;
    }

    public String getTipo() {
        return tipo;
    }

    public void setTipo(String tipo) {
        this.tipo = tipo;
    }

    public String getNumero() {
        return numero;
    }

    public void setNumero(String numero) {
        this.numero = numero;
    }

    @Override
    public String toString() {
        StringBuilder phone = new StringBuilder();
        phone.append("{ ");
        phone.append(getTipo() + ":" + getNumero());
        phone.append(" }");

        return phone.toString();
    }



}

Contato

Download do .java:

Contato.java

package sd;

import java.util.Arrays;
import java.util.ArrayList;
import java.util.List;

public class Contato {

    private int id;
    private String nome;
    private List<Telefone> telefones = new ArrayList<Telefone>();
    private List<Email> emails = new ArrayList<Email>();

    public int getId() {
        return id;
    }

    public String getNome() {
        return nome;
    }

    public List<Telefone> getTelefones() {
        return telefones;
    }

    public List<Email> getEmails() {
        return emails;
    }

    public void setId(int id) {
        this.id = id ;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }

    public void setTelefones(List<Telefone> telefones) {
        this.telefones = telefones;
    }

    public void setEmails(List<Email> emails) {
        this.emails = emails;
    }

    @Override
    public boolean equals(Object obj) {
        return (obj instanceof Contato) &&
            ((Contato)obj).getId() == this.getId();
    }

    @Override
    public int hashCode() {
        return getId();
    }

    @Override
    public String toString() {
        StringBuilder contact = new StringBuilder();
        contact.append("{ ");
        contact.append(getId());
        contact.append(", ");
        contact.append(getNome());
        contact.append(", ");
        contact.append(Arrays.toString(getEmails().toArray()));
        contact.append(", ");
        contact.append(Arrays.toString(getTelefones().toArray()));
        contact.append(" }");

        return contact.toString();
    }


}

ServicoContatos

Download do .java:

ServicoContatos.java

package sd;

import java.util.ArrayList;
import java.util.List;
import java.util.HashMap;
import java.util.Map;

import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.GenericEntity;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

@Path("contatos")
public class ServicoContatos {

    private static Map<Integer, Contato> contatos = new HashMap<Integer, Contato>();
    private static int proximoId = 1;

    private void criaContato(String nome, String emailTipo, String email, String telTipo, String tel) {
        int id = proximoId++;
        Contato contato = new Contato();
        contato.setId(id);
        contato.setNome(nome);
        contato.getEmails().add(new Email(emailTipo, email));
        contato.getTelefones().add(new Telefone(telTipo, tel));
        contatos.put(id, contato);
    }

    public ServicoContatos() {

        if (contatos.isEmpty()) {

            criaContato("E. Francesquini",
                        "Profissional", "e.francesquini@ufbac.edu.br",
                        "Comercial", "9876 5432");
            criaContato("F. Ferreira ",
                        "Profissional", "fernando.teubl@ufabc.edu.br",
                        "Residencial", "1234 5678");
        }
    }

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String listPlain() {
        System.out.println("listPlain");
        StringBuffer ret = new StringBuffer();
        for (Contato contato :contatos.values()) {
            ret.append(contato);
            ret.append("\n");
        }
        return ret.toString();
    }

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public List<Contato> listJson() {
        System.out.println("listJson");
        return new ArrayList(contatos.values());
    }

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    @Path("/{id}")
    public Contato getContato(@PathParam("id") int id) {
        System.out.println("getContato");
        Contato ret = contatos.get(id);
        if (ret == null)
            throw new WebApplicationException(404);
        return ret;
    }

    @GET
    @Path("/busca/{nome}")
    @Produces(MediaType.APPLICATION_JSON)
    public List<Contato> findByName(@PathParam("nome") String nome) {
        System.out.println("findByName");
        String lcNome = nome.toLowerCase();
        List<Contato> ret = new ArrayList<Contato>();
        for (Contato contato : contatos.values()) {
            if (contato.getNome() != null
                && contato.getNome().toLowerCase().contains(lcNome)) {
                ret.add(contato);
            }
        }
        return ret;
    }

    @POST
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public Contato add(Contato contato) {
        System.out.println("add");
        if (contato.getNome() == null || contato.getNome().trim().equals("")) {
            throw new WebApplicationException(Response
                                              .status(Response.Status.BAD_REQUEST)
                                              .entity("Nome é obrigatorio").build());
        }
        contato.setId(proximoId++);
        contatos.put(contato.getId(), contato);
        return contato;
    }

    @PUT
    @Path("/{id}")
    @Consumes(MediaType.APPLICATION_JSON)
    public Response update(@PathParam("id") int id, Contato contato) {
        System.out.println("update");
        if (id != contato.getId()) {
            throw new WebApplicationException(Response
                                              .status(Response.Status.BAD_REQUEST)
                                              .entity("O id do contato deve ser igual ao id utilizado").build());
        }
        contatos.put(id, contato);
        return Response.ok().build();
    }

    @DELETE
    public Response delete(@QueryParam("id") int id) {
        System.out.println("delete");
        Contato cont = contatos.get(id);
        if (cont == null) {
            System.out.println("Não achou");
            throw new WebApplicationException(404);
        }

        contatos.remove(id);
        return Response.ok().build();
    }

}

Main

Download do .java:

Main.java

package sd;

import org.glassfish.grizzly.http.server.HttpServer;
import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory;
import org.glassfish.jersey.server.ResourceConfig;

import java.io.IOException;
import java.net.URI;

/**
 * Main class.
 *
 */
public class Main {
    // Base URI the Grizzly HTTP server will listen on
    public static final String BASE_URI = "http://localhost:8080/";

    /**
     * Starts Grizzly HTTP server exposing JAX-RS resources defined in this application.
     * @return Grizzly HTTP server.
     */
    public static HttpServer startServer() {
        // create a resource config that scans for JAX-RS resources and providers
        // in sd package
        final ResourceConfig rc = new ResourceConfig().packages("sd");

        // create and start a new instance of grizzly http server
        // exposing the Jersey application at BASE_URI
        return GrizzlyHttpServerFactory.createHttpServer(URI.create(BASE_URI), rc);
    }

    /**
     * Main method.
     * @param args
     * @throws IOException
     */
    public static void main(String[] args) throws IOException {
        final HttpServer server = startServer();
        System.out.println(String.format("Jersey app started with WADL available at "
                + "%sapplication.wadl\nHit enter to stop it...", BASE_URI));
        System.in.read();
        server.stop();
    }
}

ContatosTest

Download do .java: -ContatosTest.java

ContatosTest.java

package sd;

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

import org.glassfish.grizzly.http.server.HttpServer;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.assertEquals;

public class ContatosTest {

    private HttpServer server;
    private WebTarget target;

    @Before
    public void setUp() throws Exception {
        // start the server
        server = Main.startServer();
        // create the client
        Client c = ClientBuilder.newClient();

        // uncomment the following line if you want to enable
        // support for JSON in the client (you also have to uncomment
        // dependency on jersey-media-json module in pom.xml and Main.startServer())
        // --
        // c.configuration().enable(new org.glassfish.jersey.media.json.JsonJaxbFeature());

        target = c.target(Main.BASE_URI);
    }

    @After
    public void tearDown() throws Exception {
        server.stop();
    }


    @Test
    public void testGetIt() {
        String responseMsg = target.path("contatos").request().get(String.class);
        String expected = "{ 1, E. Francesquini, [{ Profissional:e.francesquini@ufbac.edu.br }], [{ Comercial:9876 5432 }] }\n" +
            "{ 2, F. Ferreira , [{ Profissional:fernando.teubl@ufabc.edu.br }], [{ Residencial:1234 5678 }] }\n";
        assertEquals(expected, responseMsg);
    }
}

ClienteRest - Versão na Unha

Download do .java:

ClientREST.java

import java.net.*;
import java.io.*;

public class ClienteREST {
  public static void main(String[] args) throws Exception {
    URL url = new URL("http://localhost:8080/contatos");
    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
    conn.setRequestMethod("GET");
    conn.setRequestProperty("Accept", "application/json");
    if (conn.getResponseCode() != 200) {
      throw new RuntimeException("Failed : HTTP error code : "
        + conn.getResponseCode());
    }
    BufferedReader br = new BufferedReader(new InputStreamReader(
      (conn.getInputStream())));
    String output;
    System.out.println("Output from Server .... \n");
    while ((output = br.readLine()) != null) {
      System.out.println(output);
    }
    conn.disconnect();
  }
}

Autor: Emilio Francesquini

Created: 2018-07-25 Wed 14:13