GET, POST, PUT e DELETE

Nesse exemplo vamos criar um web service REST que permite consultar, inserir, alterar e remover (CRUD) palestras. Para deixar o exemplo mais real, vamos implementar desde o banco de dados até o web service REST.

Criando o Web Service REST

Para começar vamos criar a sequência e tabela no banco de dados, nesse exemplo estou utilizando Oracle, mas se preferir é só adaptar essa parte de persistência para o banco de dados que você for usar.

Script

CREATE SEQUENCE palestra_seq INCREMENT BY 1 START WITH 1 NOCACHE NOCYCLE;

CREATE TABLE palestra (
    id NUMBER(8) NOT NULL,
    titulo VARCHAR2(200) NOT NULL,
    descricao VARCHAR2(1000) NOT NULL,
    palestrante VARCHAR2(200) NOT NULL,
    PRIMARY KEY (id)
)

Crie uma aplicação web chamada PalestraWSREST no NetBeans, essa aplicações posteriormente será publicada no servidor de aplicações web Glassfish.

Dentro da aplicação vamos criar a entidade Palestra:

package evento.modelo;

import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;

@Entity
@NamedQueries({
    @NamedQuery(name = "Palestra.consultarTodos",
            query = "SELECT p FROM Palestra p ORDER BY p.titulo")
})
@SequenceGenerator(name = "palestra_seq", sequenceName = "palestra_seq", 
  allocationSize = 1, initialValue = 1)
public class Palestra implements Serializable {
    private static final long serialVersionUID = -2806694270931063283L;

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE,
      generator = "palestra_seq")
    private Long id;
    private String titulo;
    private String descricao;
    private String palestrante;

    public Long getId() {
        return id;
    }

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

    public String getTitulo() {
        return titulo;
    }

    public void setTitulo(String titulo) {
        this.titulo = titulo;
    }

    public String getDescricao() {
        return descricao;
    }

    public void setDescricao(String descricao) {
        this.descricao = descricao;
    }

    public String getPalestrante() {
        return palestrante;
    }

    public void setPalestrante(String palestrante) {
        this.palestrante = palestrante;
    }
}

Na entidade Palestra, declarei uma consulta nomeada chamada "Palestra.consultarTodos" que será usada para consultar todas as palestras cadastradas.

Agora vamos criar o DAO para salvar, alterar, remover, consultar palestra por id e consultar todas palestras.

package evento.dao;

import evento.modelo.Palestra;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.Query;

public class PalestraDAO {
    private EntityManager em;

    public PalestraDAO(EntityManager em) {
        this.em = em;
    }

    public Palestra salvar(Palestra p) throws Exception {
        if(p.getId() == null) {
            em.persist(p);
        } else {
            if(!em.contains(p)) {
                if(em.find(Palestra.class, p.getId()) == null) {
                    throw new Exception("Erro ao atualizar a palestra!");
                }
            }
            p = em.merge(p);
        }

        return p;
    }

    public void remover(Long id) {
        Palestra p = em.find(Palestra.class, id);
        em.remove(p);
    }

    public Palestra consultarPorId(Long id) {
        return em.find(Palestra.class, id);
    }

    public List<Palestra> consultarTodos() {
        Query q = em.createNamedQuery("Palestra.consultarTodos");
        return q.getResultList();
    }
}

No Glassfish, crie um pool de conexões com o banco de dados, nesse exemplo eu criei um recurso JDBC chamado jdbc/palestras.

Com o pool criado e funcionando, cria a unidade de persistência. Note que o nome da unidade é name="PalestraPU" se preferir pode criar com outro nome, mas lembre de usar o nome que você criar no EJB.

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence 
    http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
  <persistence-unit name="PalestraPU" transaction-type="JTA">
    <jta-data-source>jdbc/palestras</jta-data-source>
    <exclude-unlisted-classes>false</exclude-unlisted-classes>
    <properties/>
  </persistence-unit>
</persistence>

Agora vamos criar a interface remota do EJB:

package evento.ejb;

import evento.modelo.Palestra;
import java.util.List;
import javax.ejb.Remote;

@Remote
public interface PalestraRemote {
    public Palestra salvar(Palestra p) throws Exception;
    public void remover(Long id);
    public Palestra consultarPorId(Long id);
    public List<Palestra> consultarTodos();
}

E também a sua implementação:

package evento.ejb;

import evento.dao.PalestraDAO;
import evento.modelo.Palestra;
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

@Stateless
public class PalestraBean implements PalestraRemote {
    @PersistenceContext(unitName = "PalestraPU")
    private EntityManager em;

    @Override
    public Palestra salvar(Palestra p) throws Exception {
        PalestraDAO dao = new PalestraDAO(em);
        return dao.salvar(p);
    }

    @Override
    public void remover(Long id) {
        PalestraDAO dao = new PalestraDAO(em);
        dao.remover(id);
    }

    @Override
    public Palestra consultarPorId(Long id) {
        PalestraDAO dao = new PalestraDAO(em);
        return dao.consultarPorId(id);
    }

    @Override
    public List<Palestra> consultarTodos() {
        PalestraDAO dao = new PalestraDAO(em);
        return dao.consultarTodos();
    }   
}

Na aplicação crie um novo Web Service REST com o nome PalestraResource.

package evento.ws;

import com.google.gson.Gson;
import evento.ejb.PalestraRemote;
import evento.modelo.Palestra;
import javax.ejb.EJB;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.UriInfo;
import javax.ws.rs.Produces;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PUT;
import javax.ws.rs.PathParam;

/**
 * REST Web Service
 */
@Path("palestra")
public class PalestraResource {
    private Gson gson = new Gson();

    @EJB
    private PalestraRemote ejb;

    public PalestraResource() {
    }

    @GET
    @Produces("application/json")
    public String getPalestras() {
        return gson.toJson(ejb.consultarTodos());
    }

    @Path("{id}")
    @GET
    @Produces("application/json")
    public String getPalestra(@PathParam("id") String palestraId) {
        return gson.toJson(ejb.consultarPorId(Long.valueOf(palestraId)));
    }

    @POST
    @Produces("application/json")
    @Consumes("application/json")
    public String salvarPalestra(String palestra) {
        try {
            Palestra p = gson.fromJson(palestra, Palestra.class);
            return gson.toJson(ejb.salvar(p));
        } catch (Exception e) {
            return null;
        }
    }

    @DELETE
    @Path("/{id}")
    public void removerPalestra(final @PathParam("id") String id) {
        ejb.remover(Long.valueOf(id));
    }

    @PUT
    @Consumes("application/json")
    public void putPalestra(String palestra) {
        salvarPalestra(palestra);
    }
}

Nesse Web Service REST estou usando o GSon para fazer as conversões de Java para JSON. Nela estamos disponibilizando a consulta de todas as palestras e consulta da palestra pelo seu ID, permitimos salvar, alterar e remover uma palestra.

Note como cada método HTTP está sendo usado com um proposito.

Método HTTP Uso
GET Obter algum ou alguns recursos, nesse caso para consultar todas palestras e consultar uma palestra por id
POST Inserir uma nova palestra.
PUT Atualizar uma palestra.
DELETE Remover uma palestra.

Altere também a anotação ApplicationPath da classe ApplicationConfig só para facilitar o nome de acesso aos recursos, nesse exemplo alterei para "recursos":

package evento.ws;

import java.util.Set;
import javax.ws.rs.core.Application;

@javax.ws.rs.ApplicationPath("recursos")
public class ApplicationConfig extends Application {

    @Override
    public Set<Class<?>> getClasses() {
        Set<Class<?>> resources = new java.util.HashSet<>();
        addRestResourceClasses(resources);
        return resources;
    }

    /**
     * Do not modify addRestResourceClasses() method.
     * It is automatically populated with
     * all resources defined in the project.
     * If required, comment out calling this method in getClasses().
     */
    private void addRestResourceClasses(Set<Class<?>> resources) {
        resources.add(evento.ws.PalestraResource.class);
    }
}

Pronto, a implementação do web service REST está criada, agora falta implementar o cliente desse serviço.

Consumindo um Web Service REST

Vamos criar uma nova aplicação web para consumir o web service REST que criamos.

Nessa aplicação web vamos criar um modelo para representar a Palestra:

package evento.modelo;

public class Palestra {
    private Long id;
    private String titulo;
    private String descricao;
    private String palestrante;

    public Long getId() {
        return id;
    }

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

    public String getTitulo() {
        return titulo;
    }

    public void setTitulo(String titulo) {
        this.titulo = titulo;
    }

    public String getDescricao() {
        return descricao;
    }

    public void setDescricao(String descricao) {
        this.descricao = descricao;
    }

    public String getPalestrante() {
        return palestrante;
    }

    public void setPalestrante(String palestrante) {
        this.palestrante = palestrante;
    }
}

Vamos criar uma tela simples usando JSF para fazer o CRUD da palestra e mostrar todas as palestras cadastradas como mostrado na figura a seguir:

Gerenciamento de palestras

O código da página index.xhtml fica assim:

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
  xmlns:h="http://xmlns.jcp.org/jsf/html"
  xmlns:f="http://xmlns.jcp.org/jsf/core">
  <h:head>
    <title>Palestras</title>
  </h:head>
  <h:body>
    <div style="text-align: center; width: 100%">
      <h1>Palestras</h1>
    </div>
    <h:form id="formulario">
      <h:panelGrid id="dados" columns="2" width="100%">
        <h:outputText value="Título: "/>
        <h:inputText value="#{palestraMB.palestra.titulo}" style="width: 100%"/>
        <h:outputText value="Descrição: "/>
        <h:inputTextarea value="#{palestraMB.palestra.descricao}" 
          cols="40" rows="5" style="width: 100%"/>
        <h:outputText value="Palestrante: "/>
        <h:inputText value="#{palestraMB.palestra.palestrante}" 
          style="width: 100%"/>
        <h:commandButton value="Salvar" action="#{palestraMB.salvar}"/>
      </h:panelGrid>
      <h:panelGroup id="groupPalestras">
        <h:dataTable id="palestras" value="#{palestraMB.palestras}" 
          var="p" width="100%">
          <h:column>
            <h2><h:outputText value="#{p.titulo}"/></h2>
            <i><b><h:outputText value="#{p.palestrante}"/></b></i><br/>
            <h:outputText value="#{p.descricao}"/><br/>
            <h:commandButton value="Editar" action="#{palestraMB.editar(p)}">
              <f:ajax render=":formulario:dados"/>
            </h:commandButton>
            <h:commandButton value="Remover" action="#{palestraMB.remover(p)}">
              <f:ajax render=":formulario:groupPalestras"/>
            </h:commandButton>
          </h:column>
        </h:dataTable>
      </h:panelGroup>
    </h:form>
  </h:body>
</html>

No ManagedBean, estamos fazendo as chamadas para web service REST

package evento.mb;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import evento.modelo.Palestra;
import java.util.ArrayList;
import java.util.List;
import javax.faces.bean.ManagedBean;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.WebResource;
import javax.faces.bean.SessionScoped;

@ManagedBean
@SessionScoped
public class PalestraMB {
    private Palestra palestra = new Palestra();
    private List<Palestra> palestras = new ArrayList();
    private Client c = Client.create();
    private Gson gson = new Gson();

    public PalestraMB() {
        recarregar();
    }

    public void recarregar() {
        WebResource wr = c.resource(
          "http://localhost:8080/PalestraWSREST/recursos/palestra");
        String json = wr.get(String.class);
        palestras = gson.fromJson(json, new TypeToken<List<Palestra>>() {}.getType());
    }

    public String salvar() {
        WebResource wr = c.resource(
          "http://localhost:8080/PalestraWSREST/recursos/palestra");
        if(palestra.getId() == null) {
            wr.type("application/json").accept("application/json")
              .post(gson.toJson(palestra));
        } else {
            wr.type("application/json").accept("application/json")
              .put(gson.toJson(palestra));
        }
        palestra = new Palestra();
        recarregar();
        return "index";
    }

    public void remover(Palestra p) {
        WebResource wr = c.resource(
          "http://localhost:8080/PalestraWSREST/recursos/palestra/"+p.getId());
        wr.delete();
        recarregar();
    }

    public void editar(Palestra p) {
        this.palestra = p;
    }

    public Palestra getPalestra() {
        return palestra;
    }

    public void setPalestra(Palestra palestra) {
        this.palestra = palestra;
    }

    public List<Palestra> getPalestras() {
        return palestras;
    }

    public void setPalestras(List<Palestra> palestras) {
        this.palestras = palestras;
    }
}

results matching ""

    No results matching ""