SlideShare uma empresa Scribd logo
1 de 52
Desenvolvendo aplicações
web com GWT


Geraldo Augusto Massahud Rodrigues dos
Santos
Roteiro


   Introdução
   Características
   Definições
   Hello World
     – Configuração e funcionamento básicos
   uiBinder
   MVP
     – Passive View
     – Supervising Controller
   Comunicação com servidor
     – RPC
   Conclusão



                                              2
Introdução


 O que é o GWT?
  – Framework para desenvolvimento de
    aplicações ricas para internet (RIA) que
    traduz código java em código javascript.

 A pronúncia é gwit




                                               3
Introdução


 Compilação              [IE]
                          .js



 Módulo                              [Firefox]
                                     .js
             Compilador
.java          GWT

                                      [Chrome]
                                      .js



                          [Safari]
                          .js




                                                 4
Introdução

GWT                     Página inicial




                    Html       Módulo completo.js




Clássico                Página inicial




                             Html




                                                    5
Introdução

GWT



                          { x:1}


                    JSON(apenas dados)




Clássico




                           Html




                                         6
Introdução

GWT

                        Execução de
                        processamento
                        de apresentação
                        apenas no
                        navegador




Clássico




                             Html




                                          7
Características


 Processamento de apresentação é todo realizado no
  cliente
   – menor uso de recursos do servidor
      • Escalabilidade
   – menor tráfego de rede
      • após o carregamento inicial apenas dados trafegam, pois a
        lógica de exibição e as telas já estão todas no cliente.




                                                                    8
Características


 Codificação em Java
   – Orientação a objetos
   – Padrões de desenho
   – Anotações
   – IDE Java
      •   Refatoração
      •   Auto completar
      •   Templates de código
      •   Debug
   – Testes de unidade executam em Java




                                          9
Características


 Compilador javascript
   – Alta performance
   – Múltiplos navegadores
   – Ofuscado
   – Permite utilizar javascript no código java via JSNI




                                                           10
Características


 E as desvantagens?
   – Tamanho do javascript inicial pode ser grande
   – Classes utilizadas no lado cliente devem ser ser
     traduzíveis para javascript
      • Bibliotecas de terceiros
      • Entidades de persistência
          – DTOs: lógica duplicada

   – Indexação
      • Aplicação é criada dinamicamente em javascript, portanto
        indexadores não a visualizam diretamente. Um trabalho
        extra deve ser realizado com intuito de deixá-la indexável.
        https://developers.google.com/webmasters/ajax-
        crawling/docs/html-snapshot
   – Código JSNI não é fácil de manter
                                                                      11
Definições


 Módulo
   – Unidade do gwt
   – Definido em xml
   – Um módulo pode importar outros módulos
   – O módulo determina quais são as pastas que serão compiladas
     pelo compilador GWT
 EntryPoint
   – Classes que tem o método onModuleLoad executado quando
     um módulo é carregado
   – Um módulo pode possuir vários EntryPoints
   – Todos EntryPoints de cada módulo importado são executados
 Página HTML hospedeira
   – Página que possui a importação do javascript de um módulo


                                                                   12
Definições


 Organização de pacotes
  – O GWT normalmente tem uma organização
    padronizada de pacotes, possuindo 3 sub-pacotes
    dentro do pacote do módulo.
      • client: classes que são utilizadas apenas no cliente, todas
        são transformadas em javascript e o código do servidor não
        deve normalmente utilizá-las.
      • server: classes exclusivas para utilização pelo servidor, o
        compilador GWT nem as compila para javascript, portanto
        nunca devem ser utilizadas no cliente.
      • shared: classes que podem ser utilizadas tanto no servidor
        quanto no cliente, normalmente são enums e classes
        utilitárias utilizadas em ambos os ambientes.



                                                                      13
Hello World


 Módulo (HelloWorld.gwt.xml)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE module PUBLIC "-//Google Inc.//DTD Google Web Toolkit
   2.4.0//EN" "http://google-web-
   toolkit.googlecode.com/svn/tags/2.4.0/distro-source/core/src/gwt-
   module.dtd">
<module>
  <inherits name="com.google.gwt.user.User" />
  <source path="client" />
  <source path=“shared" />
  <entry-point class="com.massahud.helloworld.client.HelloWorld" />
</module>




                                                                       14
Hello World


 EntryPoint
  (com.massahud.helloworld.client.HelloWorld)
package com.massahud.helloworld.client;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;

public class HelloWorld implements EntryPoint {

    @Override
    public void onModuleLoad() {
      Label labelHello = new Label("Hello world");
      RootPanel.get().add(labelHello);
    }

}
                                                     15
Hello World


 HTML Hospedeiro (helloworld.html)
<!doctype html>
<html>
  <head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    <title>helloworld</title>
    <script type="text/javascript" language="javascript"
   src="com.massahud.helloworld.HelloWorld/com.massahud.helloworld.Hello
   World.nocache.js">
   </script>
  </head>
  <body>
  </body>
</html>




                                                                           16
Hello World




              17
Hello World




              18
Hello World



 Renomeando o módulo
<module rename-to=“HelloWorld">
  ...
</module>

<!doctype html>
<html>
  ...
    <script type="text/javascript" language="javascript”
      src=“HelloWorld/HelloWorld.nocache.js”></script>
  ...
</html>




                                                           19
Hello World




              20
uiBinder


 O que é?
  – Framework que permite trabalhar com HTML
    e CSS para definir a estrutura das telas.
 Componentes
  – HTML com a estrutura das telas, permite
    tanto tags HTML quanto tags de
    componentes GWT, inclusive componentes
    customizados.
  – Classe java de mesmo nome, com vinculação
    automática de campos e eventos através de
    anotações
                                                21
 Vantagens
  – Visualizar a estrutura da página em HTML é
    mais fácil do que lendo um código que a cria.
  – Para modificar a aparência da tela é
    necessário apenas modificar o HTML, a
    lógica continua intacta na classe java
  – Reuso: é fácil criar uma tela e inseri-la dentro
    de outra




                                                       22
uiBinder


HelloWorld.ui.xml
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
xmlns:g="urn:import:com.google.gwt.user.client.ui">
  <ui:style>

  </ui:style>
  <g:HTMLPanel>
    <g:FlowPanel>
      <g:TextBox ui:field="txtBoxEntrada"/>
      <g:Button ui:field="buttonOk" text="Ok"/>
    </g:FlowPanel>
    <g:Label ui:field="labelHello"/>
  </g:HTMLPanel>
</ui:UiBinder>




                                                                         23
uiBinder

HelloWorldView.java
public class HelloWorldView extends Composite {

    @UiField
    protected TextBox txtBoxEntrada;

    @UiField
    protected Button buttonOk;

    @UiField
    protected Label labelHello;

  private static PainelControlesUiBinder uiBinder =
GWT.create(PainelControlesUiBinder.class);

  interface PainelControlesUiBinder extends UiBinder<Widget,
HelloWorldView> { }

    public HelloWorldView() {
      initWidget(uiBinder.createAndBindUi(this));
    }

    @UiHandler("buttonOk")
    public void onButtonOkClick(ClickEvent event) { ... }
}
                                                               24
uiBinder




           25
Model-View-Presenter


 Padrão de arquitetura de UI
 Criado para aumentar a testabilidade
  – No padrão MVC a View trabalha diretamente
    com o Modelo, podendo possuir lógica de
    negócio ou guardar o estado atual da
    execução. Isso torna difícil o teste de
    unidade, pois normalmente as telas só
    conseguem ser testadas com emulação de
    execução em testes de integração.



                                                26
Model-View-Presenter


 Separa a lógica e a manutenção de estado da View
   – View apenas repassa para o controle, que nesse
     caso é chamado de Presenter, os eventos gerados
     pelo usuário,
   – Presenter possui toda a lógica e o estado da
     apresentação, sendo ele o responsável, inclusive, por
     atualizar os dados dos widgets da View.
      • Mesmo podendo existir lógica de exibição na View, os testes
        de unidade podem ser realizados apenas no Presenter, pois
        o risco de problemas de negócio na View é baixo.




                                                                      27
Model-View-Presenter


 Foi subdividido em 2011 por Martin Fowler
   – Passive-View
     • View completamente passiva, não conhece as
       classes do modelo, se limita a repassar as
       modificações do usuário ao presenter e esperar
       que ele diga o que ela deve exibir.
  – Supervising Controller
     • View pode fazer data binding simples com o
       modelo, de forma a facilitar a implementação.
       Apesar dela poder editar o modelo, a edição é tão
       simples que o risco de não testá-la com testes de
       unidade continua mínimo

                                                           28
Model-View-Presenter


Passive View                                      Supervising Controller
View:                                             View:
@UiHandler("buttonOk")                            @UiHandler("buttonOk")
public void onButtonOkClick(ClickEvent event) {   public void onButtonOkClick(ClickEvent event) {
  presenter.onEntradaModificada                     hello.setQuem(txtBoxEntrada.getText());
    (txtBoxEntrada.getText());                      presenter.onHelloEditado(hello);
}                                                 }

public void setEntrada(String texto) {            public void setEntrada(String texto) {
  txtBoxEntrada.setText(texto);                     txtBoxEntrada.setText(texto);
}                                                 }

public void setSaida(String texto) {              public void setHello(Hello hello) {
  labelSaida.setText(texto);                        this.hello = hello;
}                                                   labelSaida.setText(hello.getValor());
                                                  }
Presenter:
@Override                                         Presenter:
public void onHelloEditado(String texto) {        @Override
  Hello hello = new Hello(texto);                 public void onHelloEditado(Hello hello) {
  if (isValido(hello)) {                            if (isValido(hello)) {
    this.hello = hello;                               this.hello = hello;
    view.setSaida(hello.getValor());                  view.setHello(new Hello(hello));
  }                                                 }
  view.setEntrada("");                              view.setEntrada("");
}                                                 }




                                                                                               29
Model-View-Presenter


 Qual utilizar?
  – Depende
      • Se os dados exibidos da View e repassados para
        o presenter pelo método de evento forem poucos,
        usar Passive View garante que os testes de
        unidade tenham cobertura maior de lógica.
      • Se a entidade possuir muitos campos, o método
        de evento do Passive View pode ficar com uma
        assinatura muito grande, gerando a necessidade
        de algum TO. Portanto pode valer a pena utilizar a
        própria entidade, o que nos leva ao Supervising
        Controller

                                                             30
Model-View-Presenter


 Maneiras de implementar
  – View sem gets
      • Todas os valores são passados ao presenter como
        parâmetros do método do evento acionado.
      • Pode gerar mais código repetitivo
      • Garante que o desenvolvedor que fez o presenter não irá
        usar a view para guardar estado.
   – View com gets dos valores
      • Método do evento acionado não precisa de parâmetros.
      • O desenvolvedor do presenter pode utilizar a view
        inequivocadamente para guardar o estado atual, o que
        impossibilita o teste de unidade do presenter.
   – O que importa é que siga a ideia de separar a lógica
     e a manutenção de estado da view para os testes.
                                                                  31
Model-View-Presenter

public class HelloWorldView extends Composite {

 public interface Presenter {
   void onEntradaEditada(String entrada);
 }

 @UiField
 protected TextBox txtBoxEntrada;

 @UiField
 protected Button buttonOk;

 @UiField
 protected Label labelHello;

 private Presenter presenter;

  private static PainelControlesUiBinder uiBinder =
GWT.create(PainelControlesUiBinder.class);

 interface PainelControlesUiBinder extends UiBinder<Widget, HelloWorldView> { }

 public HelloWorldView() {
   initWidget(uiBinder.createAndBindUi(this));
 }

                                                                                  32
Model-View-Presenter

    public void setPresenter(Presenter presenter) {
      this.presenter = presenter;
    }
    @UiHandler("buttonOk")
    public void onButtonOkClick(ClickEvent event) {
      fireEntradaEditada();
    }

    @UiHandler("txtBoxEntrada")
    public void onEnterPressionado(KeyDownEvent event) {
      if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER) {
        event.preventDefault();
        fireEntradaEditada();
      }
    }

    private void fireEntradaEditada() {
      presenter.onEntradaEditada(txtBoxEntrada.getText());
    }

    public void setSaida(String texto) {
      labelHello.setText(texto);
    }
    public void setEntrada(String texto) {
      txtBoxEntrada.setText(texto);
    }
}                                                             33
Model-View-Presenter

public class HelloWorldPresenter implements HelloWorldView.Presenter {

    private HelloWorldView view;

    public HelloWorldPresenter(HelloWorldView view) {
      this.view = view;
      view.setPresenter(this);
      view.setEntrada("");
      view.setSaida("Hello World");
    }

    @Override
    public void onEntradaEditada(String entrada) {
      view.setEntrada("");
      if (!entrada.isEmpty()) {
        view.setSaida("Hello " + entrada);
      }
    }

}




                                                                         34
Model-View-Presenter

public class HelloWorld implements EntryPoint {
  /**
   * Método executado ao carregar o módulo.
   */
  @Override
  public void onModuleLoad() {
    HelloWorldView view = new HelloWorldView();
    HelloWorldPresenter presenter = new HelloWorldPresenter(view);
    RootPanel.get().add(view);
  }

}




                                                                     35
Comunicação com servidor


 Assíncrona
  – Envia requisição ao servidor e espera
    resposta, mantendo interface respondendo a
    entradas do usuário, podendo inclusive
    enviar/enfileirar outras requisições.
  – Não garante que a ordem de chegada das
    respostas das requisições seja a mesma
    ordem das requisições.




                                                 36
Comunicação com servidor


 Funcionamento geral para chamadas assíncronas
   – Prepara-se o método que será chamado, passando
     os parâmetros que serão utilizados.
   – Um objeto callback é passado para receber a
     resposta da requisição quando ela é disparada. Esta
     resposta é recebida a partir de métodos do callback,
     que são:
      • onSuccess: nenhum erro ocorreu na requisição e ela
        retornou, tem como parâmetro o tipo de retorno da chamada
        executada.
      • onFailure: quando alguma falha ocorre na requisição. Tem
        como parâmetro um objeto que especifica o erro.



                                                                    37
Comunicação com servidor




                           38
Comunicação com servidor


 Um ponto importante
   – Toda a lógica e estrutura inicial das telas já estão no
     lado cliente ao carregar o módulo, porém sem
     nenhum dado.
   – Se uma tela que fica visível depende de dados do
     servidor para sua inicialização ela deveria ser exibida
     desabilitada até que os dados necessários cheguem.




                                                               39
Comunicação com servidor

Inicialização do GWT exibindo tela que precisa de dados do servidor


                            JSF




                                                                      40
Comunicação com servidor

        Comparando com JSF




                             41
Comunicação com servidor


 Possibilidades
   – Remote Procedure Call (RPC)
       • É a mais simples e que será mostrada nesta apresentação.
         Um único método é chamado por vez.
   – RequestFactory
       • Uma chamada de procedimento remoto mais robusta, que
         dá um tratamento mais completo a entidades, produz DTOs
         automaticamente, permite que várias chamadas a
         procedimentos sejam unidos em uma única requisição.
   – JsonP
       • Chamada que obteém resposta Json with Padding. Por ser
         uma resposta javascript normalmente utiliza JSNI.
       • É a única forma de fazer requisições para outro domínio.


                                                                    42
Comunicação com o servidor

 Criando um serviço de Remote Procedure Call
   – O RPC executa procedimentos definidos em classes
     chamadas de services.
      • No cliente deve-se definir a interface do service, que terá os
        métodos poderão ser chamados via RPC, esta interface
        deve estender a interface RemoteService.
      • No servidor é feita a implementação da interface definida no
        cliente, essa implementação deve estender a classe abstrata
        RemoteServiceServlet. Esta classe é também um servlet
        java.
      • Na aplicação web deve-se declarar a classe de
        implementação do service como um servlet no web.xml.




                                                                         43
Comunicação com o servidor


HelloService.java
package com.massahud.helloworld.client.rpc;
@RemoteServiceRelativePath("hello")
public interface HelloService extends RemoteService{
  public String hello(String quem);
}

HelloServiceImpl.java
package com.massahud.helloworld.server.rpc;
public class HelloServiceImpl extends RemoteServiceServlet implements HelloService {
  @Override
  public String dizHello(String quem) {
    return "Hello " + quem;
  }
}

web.xml
<servlet>
  <servlet-name>hello</servlet-name>
  <servlet-class>com.massahud.helloworld.server.rpc.HelloServiceImpl</servlet-class>
</servlet>
<servlet-mapping>
  <servlet-name>hello</servlet-name>
  <url-pattern>/HelloWorld/hello</url-pattern>
</servlet-mapping>
                                                                                       44
Comunicação com o servidor


 Chamando o serviço do RPC
   – O cliente precisa do callback como parâmetro dos
     métodos para chamá-los de forma assíncrona.
      • Uma nova interface deve ser criada no cliente, com o
        mesmo nome da interface do service mas adicionada do
        sufixo Async.
      • Cada método da interface do service existente deve ser
        duplicado na interface Async, porém com o parâmetro
        AsyncCallback<TipoDeRetornoDoMetodo> adicionado ao
        fim da lista de parâmetros.
      • Crie uma instância da interface através do GWT.Create()
      • Chame o método RPC passando como último parâmetro o
        callback assíncrono que será chamado no retorno.



                                                                  45
Comunicação com o servidor


HelloServiceAsync.java
package com.massahud.helloworld.client.rpc;

public interface HelloServiceAsync {

    void dizHello(String quem, AsyncCallback<String> callback);

}




                                                                  46
Comunicação com o servidor

HelloWorldPresenter.java
public class HelloWorldPresenter implements HelloWorldView.Presenter {

    private HelloServiceAsync service;
    private HelloWorldView view;

    public HelloWorldPresenter(HelloWorldView view) {
      this.view = view;
      view.setPresenter(this);
      view.setEntrada("");
      view.setSaida("Hello World");
      service = GWT.create(HelloService.class);
    }

    @Override
    public void onEntradaEditada(String entrada) {
      view.setEntrada("");
      if (!entrada.isEmpty()) {
        service.dizHello(entrada, new AsyncCallback<String>() {
          @Override
          public void onSuccess(String result) {
            onHelloDito(result);
          }
          @Override
          public void onFailure(Throwable caught) {
            onFalhaAoDizerHello(caught);
          }
        });
      }
    }
}
                                                                         47
Comunicação com o servidor


 Pontos a considerar
   – Tentar limitar o corpo dos callbacks a uma única
     chamada de evento do seu presenter
      • Facilita o teste do comportamento ao receber o retorno do
        servidor
      • Provê reuso, com a funcionalidade podendo ser chamado
        diretamente, não precisando ser executado um RPC.
   – Apesar do exemplo estar criando uma classe
     anônima interna, é interessante criar uma classe não
     anônima para o callback
      • Provê reuso
      • Permite testes do callback



                                                                    48
Conclusão


 Maior escalabilidade:
  – Executa lógica no cliente.
  – Após carregar o módulo troca apenas dados com o
    servidor.
  – Não mantém no servidor o estado da apresentação.
  – Servidor passa a ser um provedor de serviços.
 Maior usabilidade
  – Interface responde ao usuário mesmo durante
    execução de ações no servidor.
  – Troca mais rápida de telas, pois elas já estão pré-
    carregadas


                                                          49
Conclusão


 Maiores facilidades (para RIA)
  – Manter código java é normalmente mais fácil que
    código javascript.
  – Permite testes de unidade do cliente em java, que
    executam muito mais rápido que em javascript.
  – Acesso a toda a gama de funcionalidades que um
    IDE java provê.
 Outro paradigma de comunicação
  – Pode ser uma barreira para quem está acostumado
    com comunicação síncrona.




                                                        50
Conclusão


 Funcionalidades importantes ou interessantes não vistas
   – Controle de histórico e fluxo de execução
        • Place
        • Activity
   –   Eventos
   –   RequestFactory
   –   JsonP
   –   Cell widgets
   –   Editors
   –   Bean Validation (JSR303)
   –   JSNI
   –   GWTTestCase
   –   Layout Panels
   –   Suporte HTML5

                                                            51
Perguntas




            52

Mais conteúdo relacionado

Mais procurados

Minicurso Java Server Faces
Minicurso Java Server FacesMinicurso Java Server Faces
Minicurso Java Server Faces
João Longo
 
IBM Web Content Management - Melhores práticas
IBM Web Content Management - Melhores práticasIBM Web Content Management - Melhores práticas
IBM Web Content Management - Melhores práticas
rodrigoareis
 
JSF e outras tecnologias Java Web - IMES.java
JSF e outras tecnologias Java Web - IMES.javaJSF e outras tecnologias Java Web - IMES.java
JSF e outras tecnologias Java Web - IMES.java
Eduardo Bregaida
 
Java Web - MVC básico com JSP e Servlets
Java Web - MVC básico com JSP e ServletsJava Web - MVC básico com JSP e Servlets
Java Web - MVC básico com JSP e Servlets
Eduardo Mendes
 

Mais procurados (20)

Aula parte 1 de JSF 2.2
Aula parte 1 de JSF 2.2Aula parte 1 de JSF 2.2
Aula parte 1 de JSF 2.2
 
Minicurso Java Server Faces
Minicurso Java Server FacesMinicurso Java Server Faces
Minicurso Java Server Faces
 
IBM Web Content Management - Melhores práticas
IBM Web Content Management - Melhores práticasIBM Web Content Management - Melhores práticas
IBM Web Content Management - Melhores práticas
 
Aula parte 2 de JSF 2.2
Aula parte 2 de JSF 2.2Aula parte 2 de JSF 2.2
Aula parte 2 de JSF 2.2
 
Java web
Java webJava web
Java web
 
Curso de ReactJS
Curso de ReactJSCurso de ReactJS
Curso de ReactJS
 
Java 8 - A Evolução da Linguagem
Java 8 - A Evolução da LinguagemJava 8 - A Evolução da Linguagem
Java 8 - A Evolução da Linguagem
 
Framework struts2v2.5
Framework struts2v2.5Framework struts2v2.5
Framework struts2v2.5
 
JSF e outras tecnologias Java Web - IMES.java
JSF e outras tecnologias Java Web - IMES.javaJSF e outras tecnologias Java Web - IMES.java
JSF e outras tecnologias Java Web - IMES.java
 
Interfaces ricas JSF
Interfaces ricas JSF Interfaces ricas JSF
Interfaces ricas JSF
 
Framework web 3 - JSF + Spring boot
Framework web 3 - JSF + Spring bootFramework web 3 - JSF + Spring boot
Framework web 3 - JSF + Spring boot
 
Grails
GrailsGrails
Grails
 
Gwt
GwtGwt
Gwt
 
Curso de Grails
Curso de GrailsCurso de Grails
Curso de Grails
 
Java Web - MVC básico com JSP e Servlets
Java Web - MVC básico com JSP e ServletsJava Web - MVC básico com JSP e Servlets
Java Web - MVC básico com JSP e Servlets
 
JSF & REST
JSF & RESTJSF & REST
JSF & REST
 
Framework web 02 - 2016
Framework web 02 - 2016Framework web 02 - 2016
Framework web 02 - 2016
 
Java Web, o Tutorial
Java Web, o TutorialJava Web, o Tutorial
Java Web, o Tutorial
 
Spring Security e Spring Boot Aula - 2018
Spring Security e Spring Boot Aula - 2018Spring Security e Spring Boot Aula - 2018
Spring Security e Spring Boot Aula - 2018
 
Avaliacao jsf utfpr
Avaliacao jsf utfprAvaliacao jsf utfpr
Avaliacao jsf utfpr
 

Destaque (9)

Apresentação Equipa Informática
Apresentação Equipa InformáticaApresentação Equipa Informática
Apresentação Equipa Informática
 
Unidades de medida de dados
Unidades de medida de dadosUnidades de medida de dados
Unidades de medida de dados
 
Qualidade na gestao dos serviços
Qualidade na gestao dos serviçosQualidade na gestao dos serviços
Qualidade na gestao dos serviços
 
Unidades de medida do sistema binário dos computadores
Unidades de medida do sistema binário dos computadoresUnidades de medida do sistema binário dos computadores
Unidades de medida do sistema binário dos computadores
 
Aula 5 - Modelo de Entidade e Relacionamento - MER
Aula 5 - Modelo de Entidade e Relacionamento - MER Aula 5 - Modelo de Entidade e Relacionamento - MER
Aula 5 - Modelo de Entidade e Relacionamento - MER
 
Comunicação de dados - Módulo 1
Comunicação de dados - Módulo 1Comunicação de dados - Módulo 1
Comunicação de dados - Módulo 1
 
JavaFX: A nova biblioteca gráfica da plataforma Java
JavaFX: A nova biblioteca gráfica da plataforma JavaJavaFX: A nova biblioteca gráfica da plataforma Java
JavaFX: A nova biblioteca gráfica da plataforma Java
 
A INFLUÊNCIA DA AMIZADE
 A INFLUÊNCIA DA AMIZADE A INFLUÊNCIA DA AMIZADE
A INFLUÊNCIA DA AMIZADE
 
Bases De Dados
Bases De DadosBases De Dados
Bases De Dados
 

Semelhante a Desenvolvendo aplicações web com GWT

Minicurso de JavaScript (Portuguese)
Minicurso de JavaScript (Portuguese)Minicurso de JavaScript (Portuguese)
Minicurso de JavaScript (Portuguese)
Bruno Grange
 

Semelhante a Desenvolvendo aplicações web com GWT (20)

Gwt parte 01
Gwt   parte 01Gwt   parte 01
Gwt parte 01
 
Mc56 gwt
Mc56 gwtMc56 gwt
Mc56 gwt
 
JSF 2.0 e ScrumToys
JSF 2.0 e ScrumToysJSF 2.0 e ScrumToys
JSF 2.0 e ScrumToys
 
Google Web Toolkit
Google Web ToolkitGoogle Web Toolkit
Google Web Toolkit
 
JSF 2.0 e ScrumToys
JSF 2.0 e ScrumToysJSF 2.0 e ScrumToys
JSF 2.0 e ScrumToys
 
Minicurso de JavaScript (Portuguese)
Minicurso de JavaScript (Portuguese)Minicurso de JavaScript (Portuguese)
Minicurso de JavaScript (Portuguese)
 
TDC2015 Porto Alegre - Interfaces ricas com Rails e React.JS
TDC2015  Porto Alegre - Interfaces ricas com Rails e React.JSTDC2015  Porto Alegre - Interfaces ricas com Rails e React.JS
TDC2015 Porto Alegre - Interfaces ricas com Rails e React.JS
 
Apache Wicket derruba o padrão JSF
Apache Wicket derruba o padrão JSFApache Wicket derruba o padrão JSF
Apache Wicket derruba o padrão JSF
 
GWT - de iniciante a especialista
GWT - de iniciante a especialistaGWT - de iniciante a especialista
GWT - de iniciante a especialista
 
Desenvolvimento baseado em componentes com JSF
Desenvolvimento baseado em componentes com JSFDesenvolvimento baseado em componentes com JSF
Desenvolvimento baseado em componentes com JSF
 
GWT - RIA baseada em AJAX
GWT - RIA baseada em AJAXGWT - RIA baseada em AJAX
GWT - RIA baseada em AJAX
 
Desenvolvimento RIA com GWT e Spring
Desenvolvimento RIA com GWT e SpringDesenvolvimento RIA com GWT e Spring
Desenvolvimento RIA com GWT e Spring
 
JSF 2.0: Uma Evolução nas Interfaces Web com Java
JSF 2.0: Uma Evolução nas Interfaces Web com JavaJSF 2.0: Uma Evolução nas Interfaces Web com Java
JSF 2.0: Uma Evolução nas Interfaces Web com Java
 
Nodejs justdigital
Nodejs justdigitalNodejs justdigital
Nodejs justdigital
 
Curso jsf
Curso jsfCurso jsf
Curso jsf
 
Mini curso JBC
Mini curso JBCMini curso JBC
Mini curso JBC
 
Java Seminar
Java SeminarJava Seminar
Java Seminar
 
Padrões de Projeto J2EE para Aplicações Web
Padrões de Projeto J2EE para Aplicações WebPadrões de Projeto J2EE para Aplicações Web
Padrões de Projeto J2EE para Aplicações Web
 
Apresentacão Android Components - Programando em camadas
Apresentacão Android Components - Programando em camadasApresentacão Android Components - Programando em camadas
Apresentacão Android Components - Programando em camadas
 
Como criar módulos para magento 2
Como criar módulos para magento 2Como criar módulos para magento 2
Como criar módulos para magento 2
 

Mais de Synergia - Engenharia de Software e Sistemas

Mais de Synergia - Engenharia de Software e Sistemas (13)

Testes ágeis: saindo da zona de conforto
Testes ágeis: saindo da zona de confortoTestes ágeis: saindo da zona de conforto
Testes ágeis: saindo da zona de conforto
 
Teste de Aceitação: problemas, desafios e abordagens
Teste de Aceitação: problemas, desafios e abordagensTeste de Aceitação: problemas, desafios e abordagens
Teste de Aceitação: problemas, desafios e abordagens
 
Por que contratar projetos ágeis?
Por que contratar projetos ágeis?Por que contratar projetos ágeis?
Por que contratar projetos ágeis?
 
Estimativas em projetos de software
Estimativas em projetos de softwareEstimativas em projetos de software
Estimativas em projetos de software
 
Inspeções em desenvolvimento de software
Inspeções em desenvolvimento de softwareInspeções em desenvolvimento de software
Inspeções em desenvolvimento de software
 
Como os testes irão se modificar com o advento das metodologias ágeis
Como os testes irão se modificar com o advento das metodologias ágeisComo os testes irão se modificar com o advento das metodologias ágeis
Como os testes irão se modificar com o advento das metodologias ágeis
 
Gestão de Processos de Negócio (BPM)
Gestão de Processos de Negócio (BPM)Gestão de Processos de Negócio (BPM)
Gestão de Processos de Negócio (BPM)
 
Controle estatístico de processos
Controle estatístico de processosControle estatístico de processos
Controle estatístico de processos
 
O retorno do investimento no projeto adequado de interfaces de usuário
O retorno do investimento no projeto adequado de interfaces de usuárioO retorno do investimento no projeto adequado de interfaces de usuário
O retorno do investimento no projeto adequado de interfaces de usuário
 
Gerenciamento de projetos usando corrente crítica
Gerenciamento de projetos usando corrente críticaGerenciamento de projetos usando corrente crítica
Gerenciamento de projetos usando corrente crítica
 
Aplicações Web Ricas e Acessíveis
Aplicações Web Ricas e AcessíveisAplicações Web Ricas e Acessíveis
Aplicações Web Ricas e Acessíveis
 
Testes de segurança em aplicações web
Testes de segurança em aplicações webTestes de segurança em aplicações web
Testes de segurança em aplicações web
 
Introdução a gerenciamento de projetos e PMBoK®
Introdução a gerenciamento de projetos e PMBoK®Introdução a gerenciamento de projetos e PMBoK®
Introdução a gerenciamento de projetos e PMBoK®
 

Desenvolvendo aplicações web com GWT

  • 1. Desenvolvendo aplicações web com GWT Geraldo Augusto Massahud Rodrigues dos Santos
  • 2. Roteiro  Introdução  Características  Definições  Hello World – Configuração e funcionamento básicos  uiBinder  MVP – Passive View – Supervising Controller  Comunicação com servidor – RPC  Conclusão 2
  • 3. Introdução  O que é o GWT? – Framework para desenvolvimento de aplicações ricas para internet (RIA) que traduz código java em código javascript.  A pronúncia é gwit 3
  • 4. Introdução  Compilação [IE] .js Módulo [Firefox] .js Compilador .java GWT [Chrome] .js [Safari] .js 4
  • 5. Introdução GWT Página inicial Html Módulo completo.js Clássico Página inicial Html 5
  • 6. Introdução GWT { x:1} JSON(apenas dados) Clássico Html 6
  • 7. Introdução GWT Execução de processamento de apresentação apenas no navegador Clássico Html 7
  • 8. Características  Processamento de apresentação é todo realizado no cliente – menor uso de recursos do servidor • Escalabilidade – menor tráfego de rede • após o carregamento inicial apenas dados trafegam, pois a lógica de exibição e as telas já estão todas no cliente. 8
  • 9. Características  Codificação em Java – Orientação a objetos – Padrões de desenho – Anotações – IDE Java • Refatoração • Auto completar • Templates de código • Debug – Testes de unidade executam em Java 9
  • 10. Características  Compilador javascript – Alta performance – Múltiplos navegadores – Ofuscado – Permite utilizar javascript no código java via JSNI 10
  • 11. Características  E as desvantagens? – Tamanho do javascript inicial pode ser grande – Classes utilizadas no lado cliente devem ser ser traduzíveis para javascript • Bibliotecas de terceiros • Entidades de persistência – DTOs: lógica duplicada – Indexação • Aplicação é criada dinamicamente em javascript, portanto indexadores não a visualizam diretamente. Um trabalho extra deve ser realizado com intuito de deixá-la indexável. https://developers.google.com/webmasters/ajax- crawling/docs/html-snapshot – Código JSNI não é fácil de manter 11
  • 12. Definições  Módulo – Unidade do gwt – Definido em xml – Um módulo pode importar outros módulos – O módulo determina quais são as pastas que serão compiladas pelo compilador GWT  EntryPoint – Classes que tem o método onModuleLoad executado quando um módulo é carregado – Um módulo pode possuir vários EntryPoints – Todos EntryPoints de cada módulo importado são executados  Página HTML hospedeira – Página que possui a importação do javascript de um módulo 12
  • 13. Definições  Organização de pacotes – O GWT normalmente tem uma organização padronizada de pacotes, possuindo 3 sub-pacotes dentro do pacote do módulo. • client: classes que são utilizadas apenas no cliente, todas são transformadas em javascript e o código do servidor não deve normalmente utilizá-las. • server: classes exclusivas para utilização pelo servidor, o compilador GWT nem as compila para javascript, portanto nunca devem ser utilizadas no cliente. • shared: classes que podem ser utilizadas tanto no servidor quanto no cliente, normalmente são enums e classes utilitárias utilizadas em ambos os ambientes. 13
  • 14. Hello World  Módulo (HelloWorld.gwt.xml) <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE module PUBLIC "-//Google Inc.//DTD Google Web Toolkit 2.4.0//EN" "http://google-web- toolkit.googlecode.com/svn/tags/2.4.0/distro-source/core/src/gwt- module.dtd"> <module> <inherits name="com.google.gwt.user.User" /> <source path="client" /> <source path=“shared" /> <entry-point class="com.massahud.helloworld.client.HelloWorld" /> </module> 14
  • 15. Hello World  EntryPoint (com.massahud.helloworld.client.HelloWorld) package com.massahud.helloworld.client; import com.google.gwt.core.client.EntryPoint; import com.google.gwt.user.client.ui.Label; import com.google.gwt.user.client.ui.RootPanel; public class HelloWorld implements EntryPoint { @Override public void onModuleLoad() { Label labelHello = new Label("Hello world"); RootPanel.get().add(labelHello); } } 15
  • 16. Hello World  HTML Hospedeiro (helloworld.html) <!doctype html> <html> <head> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <title>helloworld</title> <script type="text/javascript" language="javascript" src="com.massahud.helloworld.HelloWorld/com.massahud.helloworld.Hello World.nocache.js"> </script> </head> <body> </body> </html> 16
  • 19. Hello World  Renomeando o módulo <module rename-to=“HelloWorld"> ... </module> <!doctype html> <html> ... <script type="text/javascript" language="javascript” src=“HelloWorld/HelloWorld.nocache.js”></script> ... </html> 19
  • 21. uiBinder  O que é? – Framework que permite trabalhar com HTML e CSS para definir a estrutura das telas.  Componentes – HTML com a estrutura das telas, permite tanto tags HTML quanto tags de componentes GWT, inclusive componentes customizados. – Classe java de mesmo nome, com vinculação automática de campos e eventos através de anotações 21
  • 22.  Vantagens – Visualizar a estrutura da página em HTML é mais fácil do que lendo um código que a cria. – Para modificar a aparência da tela é necessário apenas modificar o HTML, a lógica continua intacta na classe java – Reuso: é fácil criar uma tela e inseri-la dentro de outra 22
  • 23. uiBinder HelloWorld.ui.xml <!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent"> <ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder" xmlns:g="urn:import:com.google.gwt.user.client.ui"> <ui:style> </ui:style> <g:HTMLPanel> <g:FlowPanel> <g:TextBox ui:field="txtBoxEntrada"/> <g:Button ui:field="buttonOk" text="Ok"/> </g:FlowPanel> <g:Label ui:field="labelHello"/> </g:HTMLPanel> </ui:UiBinder> 23
  • 24. uiBinder HelloWorldView.java public class HelloWorldView extends Composite { @UiField protected TextBox txtBoxEntrada; @UiField protected Button buttonOk; @UiField protected Label labelHello; private static PainelControlesUiBinder uiBinder = GWT.create(PainelControlesUiBinder.class); interface PainelControlesUiBinder extends UiBinder<Widget, HelloWorldView> { } public HelloWorldView() { initWidget(uiBinder.createAndBindUi(this)); } @UiHandler("buttonOk") public void onButtonOkClick(ClickEvent event) { ... } } 24
  • 25. uiBinder 25
  • 26. Model-View-Presenter  Padrão de arquitetura de UI  Criado para aumentar a testabilidade – No padrão MVC a View trabalha diretamente com o Modelo, podendo possuir lógica de negócio ou guardar o estado atual da execução. Isso torna difícil o teste de unidade, pois normalmente as telas só conseguem ser testadas com emulação de execução em testes de integração. 26
  • 27. Model-View-Presenter  Separa a lógica e a manutenção de estado da View – View apenas repassa para o controle, que nesse caso é chamado de Presenter, os eventos gerados pelo usuário, – Presenter possui toda a lógica e o estado da apresentação, sendo ele o responsável, inclusive, por atualizar os dados dos widgets da View. • Mesmo podendo existir lógica de exibição na View, os testes de unidade podem ser realizados apenas no Presenter, pois o risco de problemas de negócio na View é baixo. 27
  • 28. Model-View-Presenter  Foi subdividido em 2011 por Martin Fowler – Passive-View • View completamente passiva, não conhece as classes do modelo, se limita a repassar as modificações do usuário ao presenter e esperar que ele diga o que ela deve exibir. – Supervising Controller • View pode fazer data binding simples com o modelo, de forma a facilitar a implementação. Apesar dela poder editar o modelo, a edição é tão simples que o risco de não testá-la com testes de unidade continua mínimo 28
  • 29. Model-View-Presenter Passive View Supervising Controller View: View: @UiHandler("buttonOk") @UiHandler("buttonOk") public void onButtonOkClick(ClickEvent event) { public void onButtonOkClick(ClickEvent event) { presenter.onEntradaModificada hello.setQuem(txtBoxEntrada.getText()); (txtBoxEntrada.getText()); presenter.onHelloEditado(hello); } } public void setEntrada(String texto) { public void setEntrada(String texto) { txtBoxEntrada.setText(texto); txtBoxEntrada.setText(texto); } } public void setSaida(String texto) { public void setHello(Hello hello) { labelSaida.setText(texto); this.hello = hello; } labelSaida.setText(hello.getValor()); } Presenter: @Override Presenter: public void onHelloEditado(String texto) { @Override Hello hello = new Hello(texto); public void onHelloEditado(Hello hello) { if (isValido(hello)) { if (isValido(hello)) { this.hello = hello; this.hello = hello; view.setSaida(hello.getValor()); view.setHello(new Hello(hello)); } } view.setEntrada(""); view.setEntrada(""); } } 29
  • 30. Model-View-Presenter  Qual utilizar? – Depende • Se os dados exibidos da View e repassados para o presenter pelo método de evento forem poucos, usar Passive View garante que os testes de unidade tenham cobertura maior de lógica. • Se a entidade possuir muitos campos, o método de evento do Passive View pode ficar com uma assinatura muito grande, gerando a necessidade de algum TO. Portanto pode valer a pena utilizar a própria entidade, o que nos leva ao Supervising Controller 30
  • 31. Model-View-Presenter  Maneiras de implementar – View sem gets • Todas os valores são passados ao presenter como parâmetros do método do evento acionado. • Pode gerar mais código repetitivo • Garante que o desenvolvedor que fez o presenter não irá usar a view para guardar estado. – View com gets dos valores • Método do evento acionado não precisa de parâmetros. • O desenvolvedor do presenter pode utilizar a view inequivocadamente para guardar o estado atual, o que impossibilita o teste de unidade do presenter. – O que importa é que siga a ideia de separar a lógica e a manutenção de estado da view para os testes. 31
  • 32. Model-View-Presenter public class HelloWorldView extends Composite { public interface Presenter { void onEntradaEditada(String entrada); } @UiField protected TextBox txtBoxEntrada; @UiField protected Button buttonOk; @UiField protected Label labelHello; private Presenter presenter; private static PainelControlesUiBinder uiBinder = GWT.create(PainelControlesUiBinder.class); interface PainelControlesUiBinder extends UiBinder<Widget, HelloWorldView> { } public HelloWorldView() { initWidget(uiBinder.createAndBindUi(this)); } 32
  • 33. Model-View-Presenter public void setPresenter(Presenter presenter) { this.presenter = presenter; } @UiHandler("buttonOk") public void onButtonOkClick(ClickEvent event) { fireEntradaEditada(); } @UiHandler("txtBoxEntrada") public void onEnterPressionado(KeyDownEvent event) { if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER) { event.preventDefault(); fireEntradaEditada(); } } private void fireEntradaEditada() { presenter.onEntradaEditada(txtBoxEntrada.getText()); } public void setSaida(String texto) { labelHello.setText(texto); } public void setEntrada(String texto) { txtBoxEntrada.setText(texto); } } 33
  • 34. Model-View-Presenter public class HelloWorldPresenter implements HelloWorldView.Presenter { private HelloWorldView view; public HelloWorldPresenter(HelloWorldView view) { this.view = view; view.setPresenter(this); view.setEntrada(""); view.setSaida("Hello World"); } @Override public void onEntradaEditada(String entrada) { view.setEntrada(""); if (!entrada.isEmpty()) { view.setSaida("Hello " + entrada); } } } 34
  • 35. Model-View-Presenter public class HelloWorld implements EntryPoint { /** * Método executado ao carregar o módulo. */ @Override public void onModuleLoad() { HelloWorldView view = new HelloWorldView(); HelloWorldPresenter presenter = new HelloWorldPresenter(view); RootPanel.get().add(view); } } 35
  • 36. Comunicação com servidor  Assíncrona – Envia requisição ao servidor e espera resposta, mantendo interface respondendo a entradas do usuário, podendo inclusive enviar/enfileirar outras requisições. – Não garante que a ordem de chegada das respostas das requisições seja a mesma ordem das requisições. 36
  • 37. Comunicação com servidor  Funcionamento geral para chamadas assíncronas – Prepara-se o método que será chamado, passando os parâmetros que serão utilizados. – Um objeto callback é passado para receber a resposta da requisição quando ela é disparada. Esta resposta é recebida a partir de métodos do callback, que são: • onSuccess: nenhum erro ocorreu na requisição e ela retornou, tem como parâmetro o tipo de retorno da chamada executada. • onFailure: quando alguma falha ocorre na requisição. Tem como parâmetro um objeto que especifica o erro. 37
  • 39. Comunicação com servidor  Um ponto importante – Toda a lógica e estrutura inicial das telas já estão no lado cliente ao carregar o módulo, porém sem nenhum dado. – Se uma tela que fica visível depende de dados do servidor para sua inicialização ela deveria ser exibida desabilitada até que os dados necessários cheguem. 39
  • 40. Comunicação com servidor Inicialização do GWT exibindo tela que precisa de dados do servidor JSF 40
  • 41. Comunicação com servidor Comparando com JSF 41
  • 42. Comunicação com servidor  Possibilidades – Remote Procedure Call (RPC) • É a mais simples e que será mostrada nesta apresentação. Um único método é chamado por vez. – RequestFactory • Uma chamada de procedimento remoto mais robusta, que dá um tratamento mais completo a entidades, produz DTOs automaticamente, permite que várias chamadas a procedimentos sejam unidos em uma única requisição. – JsonP • Chamada que obteém resposta Json with Padding. Por ser uma resposta javascript normalmente utiliza JSNI. • É a única forma de fazer requisições para outro domínio. 42
  • 43. Comunicação com o servidor  Criando um serviço de Remote Procedure Call – O RPC executa procedimentos definidos em classes chamadas de services. • No cliente deve-se definir a interface do service, que terá os métodos poderão ser chamados via RPC, esta interface deve estender a interface RemoteService. • No servidor é feita a implementação da interface definida no cliente, essa implementação deve estender a classe abstrata RemoteServiceServlet. Esta classe é também um servlet java. • Na aplicação web deve-se declarar a classe de implementação do service como um servlet no web.xml. 43
  • 44. Comunicação com o servidor HelloService.java package com.massahud.helloworld.client.rpc; @RemoteServiceRelativePath("hello") public interface HelloService extends RemoteService{ public String hello(String quem); } HelloServiceImpl.java package com.massahud.helloworld.server.rpc; public class HelloServiceImpl extends RemoteServiceServlet implements HelloService { @Override public String dizHello(String quem) { return "Hello " + quem; } } web.xml <servlet> <servlet-name>hello</servlet-name> <servlet-class>com.massahud.helloworld.server.rpc.HelloServiceImpl</servlet-class> </servlet> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/HelloWorld/hello</url-pattern> </servlet-mapping> 44
  • 45. Comunicação com o servidor  Chamando o serviço do RPC – O cliente precisa do callback como parâmetro dos métodos para chamá-los de forma assíncrona. • Uma nova interface deve ser criada no cliente, com o mesmo nome da interface do service mas adicionada do sufixo Async. • Cada método da interface do service existente deve ser duplicado na interface Async, porém com o parâmetro AsyncCallback<TipoDeRetornoDoMetodo> adicionado ao fim da lista de parâmetros. • Crie uma instância da interface através do GWT.Create() • Chame o método RPC passando como último parâmetro o callback assíncrono que será chamado no retorno. 45
  • 46. Comunicação com o servidor HelloServiceAsync.java package com.massahud.helloworld.client.rpc; public interface HelloServiceAsync { void dizHello(String quem, AsyncCallback<String> callback); } 46
  • 47. Comunicação com o servidor HelloWorldPresenter.java public class HelloWorldPresenter implements HelloWorldView.Presenter { private HelloServiceAsync service; private HelloWorldView view; public HelloWorldPresenter(HelloWorldView view) { this.view = view; view.setPresenter(this); view.setEntrada(""); view.setSaida("Hello World"); service = GWT.create(HelloService.class); } @Override public void onEntradaEditada(String entrada) { view.setEntrada(""); if (!entrada.isEmpty()) { service.dizHello(entrada, new AsyncCallback<String>() { @Override public void onSuccess(String result) { onHelloDito(result); } @Override public void onFailure(Throwable caught) { onFalhaAoDizerHello(caught); } }); } } } 47
  • 48. Comunicação com o servidor  Pontos a considerar – Tentar limitar o corpo dos callbacks a uma única chamada de evento do seu presenter • Facilita o teste do comportamento ao receber o retorno do servidor • Provê reuso, com a funcionalidade podendo ser chamado diretamente, não precisando ser executado um RPC. – Apesar do exemplo estar criando uma classe anônima interna, é interessante criar uma classe não anônima para o callback • Provê reuso • Permite testes do callback 48
  • 49. Conclusão  Maior escalabilidade: – Executa lógica no cliente. – Após carregar o módulo troca apenas dados com o servidor. – Não mantém no servidor o estado da apresentação. – Servidor passa a ser um provedor de serviços.  Maior usabilidade – Interface responde ao usuário mesmo durante execução de ações no servidor. – Troca mais rápida de telas, pois elas já estão pré- carregadas 49
  • 50. Conclusão  Maiores facilidades (para RIA) – Manter código java é normalmente mais fácil que código javascript. – Permite testes de unidade do cliente em java, que executam muito mais rápido que em javascript. – Acesso a toda a gama de funcionalidades que um IDE java provê.  Outro paradigma de comunicação – Pode ser uma barreira para quem está acostumado com comunicação síncrona. 50
  • 51. Conclusão  Funcionalidades importantes ou interessantes não vistas – Controle de histórico e fluxo de execução • Place • Activity – Eventos – RequestFactory – JsonP – Cell widgets – Editors – Bean Validation (JSR303) – JSNI – GWTTestCase – Layout Panels – Suporte HTML5 51
  • 52. Perguntas 52