Programador ajudante e aprendiz da comunidade open source.

VRaptor 3 - Por que desenvolvimento web em Java deve ser simples! (Java Magazine)

Desde o mês de Maio venho escrevendo uma sério de artigos para a Java Magazine sobre o framework VRaptor 3. E para que os mesmos não ficassem totalmente soltos resolvi encaixá-lo em uma série que se dividiria em 4 partes. Assim poderia criar uma lógica linear do aprendizado do leitor, junto com a contrução de uma aplicação exemplo, buscando capturar os pontos mais importantes durante o desenvolvimento de um sistema.

A primeira edição foi a Java Magazine 93:


Java Magazine 93

Esta edição presentada o VRaptor 3 e suas características, abordando cada um de seus conceitos e mostrando o porquê dele estar fazendo sucesso. Nesta mesma edição foi ensinado como criar os primeiros CRUDs e trabalhar com persistência de dados utilizando a JPA.

A segunda edição foi a Java Magazine 94:


Java Magazine 94

É mostrado como deixar seu sistema menos acoplado programando voltado a interface e como deixar seu código mais flexível e reaproveitável utilizando classes genéricas. Também é apresentado a renderização de páginas utilizando templates e introduziado o jQuery UI para melhorar o visual do sistema.

A terceira edição foi a Java Magazine 96:


Java Magazine 96

Esta edição mostra como implementar um download e upload de arquivos. Além de lhe ensinar como deixar o sistema mais seguro com implementação de um controle de login junto com um controle de permissão no qual cada um dos usuários tem seu próprio perfil.

A quarta e última edição foi a Java Magazine 98:


Java Magazine 98

Esta edição ensina como manipular e serializar dados no formato JSON. Em seguida é mostrado como criar uma listagem de dados ajax possuindo paginação e consulta com a ajuda do plugin jQuery Gridy. Também é ensinado como internacionalizar o sistema para diversos idiomas e como utilizar os validadores de dados do VRaptor para deixar o sistema mais íntegro.

Espero que os leitores gostem desta série de artigos. E para aqueles que perderam alguma edição impressa, ainda poderá adquirir o artigo online no site da DevMedia.

Link dos projetos:

Movy - Parte 1
Movy - Parte 2
Movy - Parte 3
Movy - Parte 4

  1. Sergio Murilo 3 Mar 2013 22:17

    Ola Botelho!!!

    sou autodidata em VRaptor e tanto o seu Blog quanto seus artigos na Java Magazine (que coleciono) estão de parabéns (tanto pela didatica quanto pelo conteudo!!). Eles me ajudaram muito a clarear aquelas pequenas duvidas que atrazam horas de programação!! Muito Obrigado!!

    queria saber de você, como posso otimizar a construção de um sistema pelo seguinte fato: fiz um sistema onde percebi que todas as classes Controller são muito parecidas. Por exemplo, veja meu metodo listar da EquipamentoController e da LocalidadeController:

    a) Classe EquipamentoController:
    /*
    * Este metodo obtem uma colecao de Equipamentos e envia para uma tela de listagem.
    */
    @Get("/listar")
    public List listar() {
    List catalogo = new ArrayList<>();
    Logger.getLogger("EquipamentoController").info("Preparando uma colecao de Equipamentos para apresentar... ");
    try {
    catalogo = daoFactory.getDao(Equipamento.class).listar("Equipamento.findAll");
    Logger.getLogger("EquipamentoController").info("Retornou uma colecao com " + catalogo.size() + " Equipamentos.");
    } catch (Exception e) {
    result.include("errorMessage", "Falha na captura da Lista dos Equipamentos cadastrados: " + e.getMessage());
    Logger.getLogger("EquipamentoController").info("Falha na captura da Lista dos Equipamentos cadastrados: " + e.getMessage());
    }
    Logger.getLogger("EquipamentoController").info("Encaminhando View ao usuario.");
    return catalogo;
    }

    b) Classe LocalidadeController:
    /*
    * Este metodo obtem uma colecao de Localidades e envia para uma tela de listagem.
    */
    @Get("/listar")
    public List listar() {
    List catalogo = new ArrayList<>();
    Logger.getLogger("LocalidadeController").info("Preparando uma colecao de Localidades para apresentar... ");
    try {
    catalogo = daoFactory.getDao(Localidade.class).listar("Localidade.findAll");
    Logger.getLogger("LocalidadeController").info("Retornou uma colecao com " + catalogo.size() + " Localidades.");
    } catch (Exception e) {
    result.include("errorMessage", "Falha na captura da Lista das Localidades cadastradas: " + e.getMessage());
    Logger.getLogger("LocalidadeController").info("Falha na captura da Lista das Localidades cadastradas: " + e.getMessage());
    }
    Logger.getLogger("LocalidadeController").info("Encaminhando View ao usuario.");
    return catalogo;
    }

    pouca coisa muda nos metodos!! e nos outros (cadastrar, salvar, deletar) também.. Cada classe controller que crio possuem os mesmos metodos (claro, uma ou outra tem um a mais!!)..Existe alguma forma de se otimizar isto e evitar o copiar e colar de metodos? A solução seria Generics (o que ainda não estudei!!)?

    desculpe se a pergunta é basica... mas como autodidata... sozinho algumas soluções nos escapam!!!

    E mais uma vez obrigado!! seu trabalho está ótimo!!

  2. jonas 2 Abr 2012 14:05

    Botelho - estava lendo o seguinte comentário seu no artigo.
    Até este ponto do nosso projeto, viemos acessando essas camadas diretamente, já que a aplicação ainda não está voltada à interface, ou seja, as camadas de negócios são injetadas diretamente nos controllers, mantendo certo grau de acoplamento. Quando o sistema está voltado à interface, as injeções das camadas de negócios são substituídas por suas respectivas interfaces.
    Nesse padrão todas as classes de negócio são interfaceada?
    Não seria interessante colocar interface simplesmente onde fosse realmente necessário, onde eu fosse ganhar polimorfismo que me ajudasse na manutenção do sistema, me dando flexibilidade e escalabilidade.
    Por exemplo: quando você cria a interface FilmeRepository, essa interface é algo muito especifico de Filme, dificilmente teria outra classe que assinaria um contrato com essa interface, logo não vejo você ganhando um polimorfismo para justificar essa interface, já que apenas a classe filme terá um contrato com ela.
    Dessa forma gostaria de um exemplo que me mostre esse desacoplamento ao deixar de injetar as classes de negocio e injetar sua respectiva interface.
    No mais, parabéns pelo material tem me ajudado muito.

    1. Washington Botelho autor 2 Abr 2012 14:25

      Oi Jonas,

      Sim, todas as camadas de negócios, nada de colocar a mão na massa, só mande.
      Realmente é bem específico, mas ainda assim não devemos trabalhar com o objeto da implementação diretamente, mas sim sua interface.
      A interface se faz necessária não só para o polimorfismo diretamente, mas também para o contrato, para alguns frameworks de teste, exposição de um web service e afins.
      Se você pensar somente no polimorfismo, dificilmente irá utilizar o padrão Repository.
      É sempre bom trabalhar com o genérico e ficar despreocupado.

      1. jonas 3 Abr 2012 11:43

        Botelho,
        Sua explicação foi resumida, mas bem clara
        Realmente se a gente for usar interface só para ganhar polimorfismo, usaremos muito pouco nos nossos sistemas, mas pesando da forma que você falou de não colocar a mão na maça e deixando tudo o mais genérico possível realmente faz sentido.
        Só uma coisa, a classe de persistência genérica que você criou ela não é muito indica não né ?
        Imagine que eu nunca queira apagar um filme no meu sistema? Já imaginou chegar um programador desavisado e chamar esse método.

        1. Washington Botelho autor 4 Abr 2012 15:09

          Oi Jonas,

          Sim, tem gente que não gosta por nem sempre usar tudo.
          Ai você decidi entre repetir mais ou ter um método na herança não usado.
          Quanto a chamar a esse método, assim como qualquer coisa na programação, você deve saber o que esta fazendo.

          1. jonas 13 Abr 2012 12:29

            Nobre companheiro Botelho,
            Quero fazer duas perguntas
            Primeira: hoje nos seus sistemas comerciais que você produz o que você tá utilizando para fazer paginação ? você tá usando Jquery mesmo ? Igual você apresentou no artigo ? ou você usa alguma tag lib ?
            Segunda: pelo quer podemos transformar nossas classes em Java para JSON, vamos ao exemplo.
            Tenho a classe.

            Class filme {
                String Nome
                Date dataLancamento
                Genero gênero
            
                //get set
            }
            
            Class Genero {
                nome
            
                // get set
            }
            

            Vamos imaginar que eu queira fazer a paginação usando o Jquery como você fez, gostaria de apresentar o filme na minha paginação, mas além do campos nome e dataLancamento queria que ele apresentasse o campo nome da classe gênero, ele consegue fazer isso ?
            De já obrigado pela sua atenção.

            1. Washington Botelho autor 25 Abr 2012 11:34

              Oi Jonas,

              Utilizo o jQuery Gridy.

              É possível sim. No VRaptor quando você usa o método .recursive() todos os atributos são serializados, inclusive os relacionamentos.
              O idéial é você criar um modelo seco (DTO) com todos os atributos que você quer serializar.

  3. jonas 28 Mar 2012 06:31

    Tento executar o sistema, mas tenho um problema no momento de cadastrar um filme - quando clico em salvar ele executa o link http://localhost:8080/movy-parte-4/filme/
    daí ele não não encontra o url -
    HTTP Status 404 - /movy-parte-4/filme/
    Não sei como, mas ele inclui uma / no final do nome filme

    1. Washington Botelho autor 30 Mar 2012 08:34

      Oi Jonas,

      Verifica a URI que você esta chamando se existe esta barra no final, pois isto se torna outra URI.
      Para resolver isso adicione o seguinte componente na sua aplicação: http://vraptor.caelum.com.br/cookbook/aceitando-urls-com-ou-sem-barra-no-final

      1. jonas 30 Mar 2012 08:41

        Olha Botelho, de fata o url é sem o barro

        Poré no momento que é executado ele insere o filme, porém no momento de redirecionar, ele redireciona para
        /movy-parte-4/filme/

        daí o erro

        O erro ocorre depois que ele tenta redirecionar, tipo inclusive ele exeuta o método salvar, mas no momento de redirecionar para exibir ele fica com o problema.

        1. Washington Botelho autor 30 Mar 2012 08:50

          Então Jonas,

          Adicionou o componente que te falei?
          Ele resolve esse problema.

          1. jonas 30 Mar 2012 11:16

            Nobre amigo Botelho, o link está sem o / veja

            Quando é submetido o método salva é acionado o filme é inserido, mas no momento que ele chama a função exibir e ela faz o redirecionamento para o arquivo exibir.jsp é que acontece o problema.

            Outra coisa, esse projeto foi importado, não fiz nenhuma outra alteração, o restante tá funcionando normalmente, mas essa parte ai não.

            O erro ocorre depois que ele tenta redirecionar, tipo inclusive ele executa o método salvar, mas no momento de redirecionar para exibir ele fica com o problema.

            1. Washington Botelho autor 2 Abr 2012 14:17

              Oi Jonas,

              Vou te perguntar denovo: você adicionou o componente que te falei?

  4. Charles Almeida 1 Jan 2012 21:44

    Olá Washington,
    gostei muito desta serie de artigos.
    Meus Parabéns

    Sou novo no java com vraptor e gostaria de ver como fazer o exemplo aplicar (site) url amigavel com famosos slugs.

    Ex: http://www.site.com.br/trabalhos-web/loja-dois-institucional/

    Abraço.

    1. Washington Botelho autor 4 Jan 2012 10:51

      Oi Charles,

      Como no VRaptor você pode escolher o nome da sua URI, basta digitar um nome que faça sentido com o conteúdo da página.
      Se você preferir pode até colocar mais de uma URI para um mesmo método: @Get({ "/inicio", "home" })

      1. Charles Almeida 5 Jan 2012 16:54

        Olá consegui fazer a questão do url com slug automatico, agora que me pegou foi paginação sem ajax com vraptor.

        1. Washington Botelho autor 7 Jan 2012 14:10

          Oi Charles,

          Sem ajax fica até mais fácil, basta criar uma URI que receberá todos os dados como número da página e valor a ser consultado.
          No retorno, em vez de serializar a lista, você irá incluí-la no result e na tela você irá iterá-la usando o `` da JSTL para montar a lista.

          1. Charles Almeida 7 Jan 2012 22:02

            Olá Washington,
            Consegui mostrar o valor total de registros.
            Também consegui entender como funciona o Vraptor e fazer maior parte que do que pretendia com essas implementações que você demonstrou nas revistas.
            acompanhei a serie de artigos gostei bastante.

            Gostei muito do Grid.

            Obrigado.

            1. Washington Botelho autor 15 Jan 2012 14:04

              Oi Charles,

              Muito bom, fico feliz que tenha gostado.
              Agora é só acompanhar o blog que todo mês posto um artigo sobre o VRaptor ou relacionado.

              Abraço. (:

          2. Charles Almeida 7 Jan 2012 20:29

            Olá Washington,
            Consegui fazer a paginação mais ainda falta eu pegar o valor total de registros para passar para view, observei na sua implementação de ajax que você inclui o total no json mas como posso incluir ele na lista normal ou passar ele na chamada e mostrar na view.
            *Observei que você usa wrapper no json para setar o total no lista.

            1. Washington Botelho autor 15 Jan 2012 14:02

              Oi Charle,

              É isso mesmo, precisamos criar um classe wrapper para colocar a lista e também o total.
              Sem essa classe teríamos de fazar duas chamadas ajax para obter os dados necessários.

  5. Pollyanna 14 Dez 2011 07:19

    Olá Washington! Você tem o script de criação do banco de dados movy, utilizado no exemplo da revista javamagazine?

    1. Washington Botelho autor 18 Dez 2011 01:21

      Oi Pollyanna,

      O Hibernate já cria as tabelas pra você quando você acessa a aplicação.
      Você só precisa de criar o schema "movy".
      Mas se você precisar mesmo assim, me fala em qual parte do artigo você parou que te envio por e-mail.

  6. Adriano 30 Nov 2011 14:35

    Quando é que vai sair a parte 4 no Java Magazine ?

    1. Washington Botelho autor 4 Dez 2011 11:48

      Oi Adriano,

      Não tenho essa informação, pois não tem data certa, depende deles.
      Mas creio que agora em Dezembro deva sair para não ficar muito dispersos os artigos.

  7. Adilson Benevides 26 Out 2011 07:04

    Caro Washington,
    Devido problemas no hardware tive que reinstalar o Eclipse e NetBeans, então começei ontem do zero o projeto movy, configurei o vraptor no web.xml mas, na tag o eclipse aponta um erro, tem idéia do que seja? vou dar uma olhada nos seus fontes pra ver se fiz correto...valeu...seu Blog é 10 hein? parabéns!

  8. Adilson Benevides 21 Out 2011 05:41

    Obrigado pelas dicas, já tinha criado Dynamic Project, seguirei suas instruções...

      1. Adilson Benevides 26 Out 2011 07:09

        repetindo a tag o site menor que FILTER maior que...

  9. Adilson Benevides 20 Out 2011 12:44

    Caro Washington,
    Tenho lido seu excelente artigo sobre o VRAPTOR 3 e tive umas dúvidas na hora de começar a implementar...pode lançar uma luz?

    Uso o Eclipse 3.7 e não entendo onde devo criar uma index.jsp...vc tb falou de controller mas, onde na IDE crio o INDEXCONTROLLER,

    Quando falo "onde" me refiro qual o caminho na IDE...
    Fui usuário do Visual Studio e to a pouco tempo tentando me acostumar com o Eclipse...

    Abraços e Obrigado!

    1. Washington Botelho autor 20 Out 2011 16:39

      Oi Adilson,

      Primeiramente você deve criar o projeto escolhendo New -> Dyanamic Project.
      Tudo no Eclipse é criado clicando com o botão direito em cima da pasta src ou WebContent, escolhendo o menu new e então o tipo de arquivo que você quer.
      Se o arquivo que você quiser já não estiver no menu é só escolher a opção Other e pesquisar pelo tipo que deseja.

      Qualquer coisa se tiver dúvida quanto o caminho dos arquivos é só dar uma conferida nos projetos disponibilizados no final do artigo. (:

Em resposta:
(cancelar)
Formate seu código utilizando Markdown.