Olá amiguinhos.
Vou mostrar um simples exemplo de como fazer um cadastro no GWT utilizando Hibernate. Eu achei muito trabalhoso pelo fato de não poder utilizar os recursos do Java 5. Mas em breve teremos a possibilidade de utilizar o Java 5 no GWT.
Primeiro, vamos fazer uma interface bem tosca, só com os campos necessários para nosso teste. Detalhe, esse esquema também funciona com o MyGWT, basta mudar os componentes. Vou evitar falar sobre a configuração do Hibernate, eu utilizo xml ainda, então não vou entrar em tantos detalhes.
Crie o projeto do GWT e crie uma classe chamada Principal, como segue abaixo:
package org.cadastrogwt.client;
public class Principal implements EntryPoint {
public void onModuleLoad() {
// Cria o formulario para cadastro
final FormPanel form = new FormPanel();
final VerticalPanel p = new VerticalPanel();
form.setWidget(p);
final Label lbNome = new Label("Nome");
p.add(lbNome);
final TextBox txtNome = new TextBox();
txtNome.setName("txtNome");
p.add(txtNome);
final Label lbCidade = new Label("Cidade");
p.add(lbCidade);
final TextBox txtCidade = new TextBox();
txtCidade.setName("txtCidade");
p.add(txtCidade);
// Cria um botao e define um evento para ele
Button btCadastrar = new Button("Cadastrar");
p.add(btCadastrar);
RootPanel.get().add(form);
}
}
Lembrando que eu não estou me preocupando muito com a aparência, e essa vai ficar muito feia hehe. Após isso, temos que criar as interfaces que vão controlar os dados e trabalhar RPC e a classe de "entidade". Devido ao problema do código do GWT ser compatível com o Java 1.4, vamos ter que duplicar essa classe de entidade no lado do server, com suas devidas annotations. Criamos então a classe Cadastro:
package org.cadastrogwt.client;
import com.google.gwt.user.client.rpc.IsSerializable;
public class Cadastro implements IsSerializable {
private String nome;
private String cidade;
private String estado;
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
public String getCidade() {
return cidade;
}
public void setCidade(String cidade) {
this.cidade = cidade;
}
public String getEstado() {
return estado;
}
public void setEstado(String estado) {
this.estado = estado;
}
}
Depois criamos duas interfaces, uma para o método que retornará alguma coisa do servidor e outra que enviará alguma coisa para o servidor. Simples não? Criamos a interface CadastroService:
package org.cadastrogwt.client;
import com.google.gwt.user.client.rpc.RemoteService;
public interface CadastroService extends RemoteService {
public String cadastrar(Cadastro c);
}
E a interface CadastroServiceAsync:
package org.cadastrogwt.client;
import com.google.gwt.user.client.rpc.AsyncCallback;
public interface CadastroServiceAsync {
public void cadastrar(Cadastro c, AsyncCallback callback);
}
Um detalhe muito importante e que é regra no GWT, apanhei muito no começo pra descobrir isso hehe. Essas duas interfaces, precisam obrigatóriamente conter Service e ServiceAsync nos nomes delas. Então crie um padrão, por exemplo, eu quero trabalhar com a classe Cidadao com o RPC, então eu vou criar as interfaces CidadaoService e CidadaoServiceAsync.
Bom, está quase pronto, agora precisamos criar um pacote no mesmo nível dos pacotes org.cadastrogwt.client e org.cadastrogwt.public. Crie um pacote chamado org.cadastrogwt.server. Tudo que ficar neste pacote é livre pra usar qualquer recurso do Java, Hibernate, Struts, tudo mesmo, pois ele será executado no servidor e não no cliente. Então criamos uma classe chamada CadastroServiceImpl (Mesma regra das interfaces também):
package org.cadastrogwt.server;
import org.cadastrogwt.client.Cadastro;
import org.cadastrogwt.client.CadastroService;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;
public class CadastroServiceImpl extends RemoteServiceServlet
implements CadastroService {
private static final long serialVersionUID = 1L;
public String cadastrar(Cadastro c) {
// Valores definidos pelo cliente
String nome = c.getNome();
String cidade = c.getCidade();
String estado = c.getEstado();
String retorno = null;
// Hibernate
CadastroServerDao cdao = new CadastroServerDao();
cdao.insert(nome, cidade, estado);
retorno = "Cadastro efetuado com sucesso!!!";
return retorno;
}
}
Esta classe pega tudo que foi setado na classe Cadastro e passa para o Dao. Se pudesse usar annotations, eu poderia pegar o objeto c e já mandar para o Dao, mas vamos aguardar a versão 1.5 :)
Bom, agora para dar certo, vamos criar uma classe igual a classe Cadastro, mas mapeando-a. Criamos a classe CadastroServer:
package org.cadastrogwt.server;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "cadastro")
public class CadastroServer {
@Id
@Column(name = "id_cadastro")
private int id;
@Column(length = 100)
private String nome;
@Column(length = 50)
private String cidade;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
public String getCidade() {
return cidade;
}
public void setCidade(String cidade) {
this.cidade = cidade;
}
}
Beleza, agora é só criar o Dao. Criamos a classe CadastroServerDao:
package org.cadastrogwt.server;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.cfg.Configuration;
public class CadastroServerDao {
private Session session;
private Transaction tx;
public CadastroServerDao() {
Configuration cfg = new AnnotationConfiguration();
cfg.configure("/org/cadastrogwt/server/hibernate.cfg.xml");
SessionFactory sf = cfg.buildSessionFactory();
session = sf.openSession();
tx = session.beginTransaction();
}
public void insert(String nome, String cidade, String estado) {
CadastroServer cad = new CadastroServer();
cad.setCidade(cidade);
cad.setEstado(estado);
cad.setNome(nome);
session.save(cad);
tx.commit();
session.close();
}
}
Fica a critério de cada um como usar o Configuration. Pronto, a parte do server está pronta. Agora vamos voltar para a parte do client novamente, para preparar a classe Principal para trabalhar com o AsyncCallback que faz a mesma coisa que o Ajax. Modifique a classe Principal para que fique com a mesma aparência que esta:
package org.cadastrogwt.client;
import *****;
public class Principal implements EntryPoint, AsyncCallback {
private CadastroServiceAsync service;
private void asyncCadastro(Cadastro c) {
this.service.cadastrar(c, this);
}
public void onModuleLoad() {
// Inicia a sincronizacao com o servlet
service = (CadastroServiceAsync)
GWT.create(CadastroService.class);
ServiceDefTarget target = (ServiceDefTarget) service;
target.setServiceEntryPoint(GWT.getModuleBaseURL() +
"cadastro");
// Cria o formulario para cadastro
final FormPanel form = new FormPanel();
final VerticalPanel p = new VerticalPanel();
form.setWidget(p);
final Label lbNome = new Label("Nome");
p.add(lbNome);
final TextBox txtNome = new TextBox();
txtNome.setName("txtNome");
p.add(txtNome);
final Label lbCidade = new Label("Cidade");
p.add(lbCidade);
final TextBox txtCidade = new TextBox();
txtCidade.setName("txtCidade");
p.add(txtCidade);
// Cria um botao e define um evento para ele
Button btCadastrar = new Button("Cadastrar",
new ClickListener() {
public void onClick(Widget sender) {
Cadastro cad = new Cadastro();
cad.setCidade(txtCidade.getText());
cad.setNome(txtNome.getText());
asyncCadastro(cad);
}
});
p.add(btCadastrar);
RootPanel.get().add(form);
}
public void onFailure(Throwable caught) {
// Joga uma mensagem de erro caso ocorra
Window.alert(caught.getMessage());
}
public void onSuccess(Object result) {
// Retorna a resposta do servidor
Window.alert(result.toString());
}
}
Pronto, agora antes de testar, é necessário criar uma linha no xml do projeto GWT, que seria Principal.gwt.xml. Adicione depois da tag entry-point:
<servlet path="/cadastro"
class="org.cadastrogwt.server.CadastroServiceImpl" />
Pronto, rode o projeto e tente fazer um cadastro e depois olhe no banco de dados se foi corretamente. Eu não vou explicar como faz a listagem, porque seria legal se desse pra retornar do servidor um ArrayList
Enjoy...
2 comentários:
Ola Anderson, muito boa a sua iniciativa, é difícil encontrar material sobre Gwt em português.Também acho burocratico trabalhar com Hibernate e Gwt.Em relação ao seu problema em retornar um ArrayList do servidor, o problema reside no fato de que os objetos que estarão em um ArrayList precisam implementar a Interface IsSerializable do Gwt.Isso complica um pouco mais nossa vida.Estou atrás de uma solução que facilite esse trabalho.Quando tiver com algo concreto, entro em contato.Abraços!
Olá Heitor, pois é... é complicado mesmo, mas ainda bem que o GWT 1.5 está um pouco mais facil pra mexer com o Hibernate. Vou preparar um tutorial com o GWT 1.5 e fazer as comparações. Abraços.
Postar um comentário