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:
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:
É 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:
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:
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.
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: listar() { catalogo = new ArrayList<>();
/*
* Este metodo obtem uma colecao de Equipamentos e envia para uma tela de listagem.
*/
@Get("/listar")
public List
List
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: listar() { catalogo = new ArrayList<>();
/*
* Este metodo obtem uma colecao de Localidades e envia para uma tela de listagem.
*/
@Get("/listar")
public List
List
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!!
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.
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.
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.
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.
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.
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.
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.
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
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
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.
Então Jonas,
Adicionou o componente que te falei?
Ele resolve esse problema.
Nobre amigo Botelho, o link está sem o
/
vejaQuando é 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.
Oi Jonas,
Vou te perguntar denovo: você adicionou o componente que te falei?
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.
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" })
Olá consegui fazer a questão do url com slug automatico, agora que me pegou foi paginação sem ajax com vraptor.
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.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.
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. (:
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.
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.
Olá Washington! Você tem o script de criação do banco de dados movy, utilizado no exemplo da revista javamagazine?
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.
Quando é que vai sair a parte 4 no Java Magazine ?
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.
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!
Obrigado pelas dicas, já tinha criado Dynamic Project, seguirei suas instruções...
Oi Adilson,
Pega o exemplo [1] do projeto que esta funcionando.
[1] https://github.com/wbotelhos/movy-parte-1/blob/master/WebContent/WEB-INF/web.xml
repetindo a tag o site menor que FILTER maior que...
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!
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. (: