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:
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;
}
}