29 de dezembro de 2011

Tutorial VRaptor 3

Bom, meu último post desse ano, vou falar do incrível framework brasileiro o VRaptor.
É outro framework MVC que vale a pena aprender e escrever sobre é o VRaptor, é um framework MVC muito poderoso, teve seu início na época do Struts 1.x, como solução a burôcracia que o Struts trazia, é mantido pela Caelum, grátis e open source e se diferencia pela facilidade na curva de aprendizado e por trabalhar com convenções a configurações, ou seja, adeus um monte de XML, para quem viu o último post de Spring, verá que VRaptor é tão simples de utilizá-lo quanto o próprio Spring MVC.
Outra vantagem é documentação nas opções Português e Inglês, a Caelum também fornece uma apostila completa de forma grátis para download e caso a empresa queira investir há o curso de VRaptor FJ 28 e o curso VRaptor online.
Fiz o curso online e recomendo.

Vamos ver um exemplo que montei em VRaptor, o código está disponível para download.

Aconselho antes a ler sobre Patterns como DAO, Repository, MVC, TO, PO, VO, DTO.

Criei um pequeno CRUD sem acesso ao banco apenas para mostrar a simplicidade do framework, basta pegar o código e rodar no seu Eclipse ou IDE favorita.

Tentei manter no estilo do post sobre Spring para quem estiver acompanhando validar o quão semelhante e mais simples o VRaptor é.

Passo 1:

Crie um projeto Web (ou importe o código).

Passo 2:

Criei a estrutura de pacotes:


Passo 3:

Vamos criar os Beans que ficaram no pacote domain:

public class Livro {

    private Long id;
    private String titulo;
    private String loja;
    private BigDecimal preco;
    private String autor;
   
    public Livro(Long id, String titulo, String loja, BigDecimal preco, String autor){
        this.id = id;
        this.titulo = titulo;
        this.loja = loja;
        this.preco = preco;
        this.autor = autor;
    }
   
    public Livro() {
    }

   //getters and setters
  
}

Passo 4:

Assim como no Spring é utilizado no VRaptor algumas anotações para o framework saber o que vamos querer e criar seus mapeamentos assim não necessitamos de XMLs.
No DAO utilizaremos as anotações:
@Component - VRaptor mapeará as classes como componentes (instâncias das classes que executarão tarefas)
@RequestScoped - Os componentes ficam em escopos específicos, podemos mapeá-los como @RequestScoped (o componente é o mesmo durante uma instância), @SessionScoped (Componente é o mesmo durante uma http session), @ApplicationScoped (Singleton, apenas 1 por aplicação), @PrototypeScoped (Componente sempre instanciado quando requisitado), maiores informações aqui.

Comparativo:No Spring utilizávamos a anotação @Repository.

LivroDao

@Component
@RequestScoped
public class LivroDao implements LivroDaoI {

private final static List livros = new ArrayList();
   
    static {
        populaProdutosIniciais();
    }
   
    public void salva(Livro livro) {
        livro.setId(livros.size() +1l);
        livros.add(livro);
    }

    public List listaTodos() {
        return Collections.unmodifiableList(livros);
    }

    public void remove(Livro livro) {
        Iterator it = livros.iterator();
        while(it.hasNext()) {
            Livro existente = it.next();
            if(existente.getId().equals(livro.getId())) {
                it.remove();
                break;
            }
        }
    }

    private static void populaProdutosIniciais() {
        livros.add(new Livro(1l, "Introdução À Arquitetura e Design de Software - Uma Visão Sobre a Plataforma Java", "Saraiva", new BigDecimal(73.00), "Sergio Lopes, Paulo Silveira, Guilherme Silveira"));
        livros.add(new Livro(2l, "iWOZ - a Verdadeira História da Apple Segundo Seu Cofundador", "Saraiva", new BigDecimal(49.90), "Steve Wozniak, Gina Smith"));
        livros.add(new Livro(3l, "Steve Jobs - A Biografia", "Livraria Cultura", new BigDecimal(49.90), "Walter Isaacson"));
        livros.add(new Livro(4l, "Use a cabeça! Padrões de Projetos", "Livraria Cultura", new BigDecimal(142.89), "Eric Freeman, Elisabeth Freeman"));
    }

    public Livro buscaPorId(Long id) {
        for(Livro livro : livros) {
            if(livro.getId().equals(id)){
                return livro;
            }
        }
        return null;
    }

}

É boa prática sempre criar interfaces então criei a LivroDaoI

public interface LivroDaoI {

    public void salva(Livro livro);

    public List listaTodos();

    public void remove(Livro livro);

    public Livro buscaPorId(Long id);
   
}

Lembrete: Esses livros do exemplo existem e recomendo.

Passo 5:

Criei uma camada de business ondem a lógica de negócio será mantida separada da DAO e da camada de View, também está mapeada com @Component, como o foco não é o Spring não utilizei o @Autowired para injetar dependências, mas você pode utilizá-lo.

Comparativo:
No Spring utilizávamos a anotação @Service.

LivroService
@Component
public class LivroService implements LivroServiceI{

    private LivroDaoI    livroDao;
   
    public LivroService(){
        if(livroDao==null){
            livroDao = new LivroDao();
        }
    }
   
    public void salva(Livro livro) {
        livroDao.salva(livro);
    }

    public List listaTodos() {
        return livroDao.listaTodos();
    }

    public void remove(Livro livro) {
        livroDao.remove(livro);
    }

    public Livro buscaPorId(Long id) {
        return livroDao.buscaPorId(id);
    }

}

LivroServiceI
public interface LivroServiceI {
   
    public void salva(Livro livro);

    public List listaTodos();

    public void remove(Livro livro);

    public Livro buscaPorId(Long id);


}
Passo 6:

Para evitar acessar diretamente o Bean e se por ventura necessitar colocar algum atributo de tela criei um Form onde conterá o Bean e os demais atributos de tela caso necessário.

LivroForm

public class LivroForm {

    private Livro livro = new Livro();

    //getters and setters
   
}

Passo 7:

Criei uma classe Controller assim como no Spring o padrão adotado é NomeClasseController, utilizaremos aqui a anotação @Resource TODOS seus controllers deverão ter essa anotação.
@Resource - O VRaptor saberá através dessa anotação qual a convençao para criar a URI exemplo: /nomeController/nomeMetodo.
 Temos também a anotação @Post e @Path("/livro/{id}").
@Post -  Aqui poderíamos criar comportamentos REST, iremos receber nosso form completamente populado.
@Path("/livro/{id}") - Aqui receberemos no nosso bean livro o atributo id preenchido, essa anotação muda a URI que acessará o método.
Foi utilizado também a Classe Result que tem como objetivo retornar um ou mais objetos, assim como mensagens, dentro outas coisas vale a pena ler aqui.
Validação:
validator.checking(new Validations(){{
                that(livroForm.getLivro().getPreco().doubleValue() > 0,"erro", "livro.preco.invalido");
}});
            validator.onErrorUsePageOf(this).formulario();  
Para validar os dados de retorno no método basta chamar o validator.checking, instanciar Validations, dentro do that você colocará a validação, a categoria e a mensagem.
O validator.onErrorUsePageOf(this).formulario(); é utilizado para fazer o direcionamento, dentro passo um this informando que é essa classe (LivroController) que ele vai utilizar no método formulario, ou seja ele irá redirecionar para o formulário com as mensagens de erro.
No JSP para exibir a mensagem basta colocar:
   
       [c:forEach var="error" items="${errors}"]
            ${error.category} - ${error.message}[br /]
        [/c:forEach]

Comparação:
No Spring utilizamos as anotações: @Controller, @RequestMapping, @RequestParam(value = "produto.id") que fariam as mesmas coisas acima.
No caso do Result seria a utilização do ModelAndView quem traz a mesma idéia de enviar um ou mais objetos.
Validação:
No Spring utilizamos no parametro do método do Controller um @Valid e quem trata o erro e adiciona as mensagens após a verificação por um if ou pelo HibernateValidator é o BindingResult.
No JSP colocaríamos por exemplo:
[form:errors path="nome"  /]
LivroController
@Resource
public class LivroController {

    private final Result result;

    private final LivroServiceI livroService;

    private final Validator validator;
   
    public LivroController(LivroServiceI livroService, Result result, Validator validator) {
        this.livroService = livroService;
        this.result = result;
        this.validator = validator;
    }
   
    public void formulario(){
       
    }
   
    public void consulta(){
       
       }
   
    @Post
    public void adiciona(final LivroForm livroForm){
         validator.checking(new Validations(){{
                that(livroForm.getLivro().getPreco().doubleValue() > 0,"erro", "livro.preco.invalido");
                that(!livroForm.getLivro().getTitulo().isEmpty(), "erro", "livro.titulo.nao.informado");
                that(!livroForm.getLivro().getLoja().isEmpty(), "erro", "livro.loja.nao.informado");
            }});
            validator.onErrorUsePageOf(this).formulario(); 
   
            livroService.salva(livroForm.getLivro());
            result.redirectTo(this).lista();
    }
   
    public void remove (Livro livro){
        livroService.remove(livro);
        result.nothing();
    }
   
    public List lista() {
        return livroService.listaTodos();
    }
   
    @Post
    public void pesquisa(LivroForm livroForm) {
        result.redirectTo(this).exibe(livroForm.getLivro().getId());
    }
   
    @Path("/livro/{id}")
    public LivroForm exibe(Long id){
        LivroForm livroForm = new LivroForm();
        livroForm.setLivro(livroService.buscaPorId(id));
        return livroForm;
    }
   
}

Assim como no Spring, no VRaptor um método terá um JSP que o representa, assim o VRaptor por convenção o redirecionará.

Passo 8:

Os JSPs devem estar dentro da pasta WEB-INF -> jsp -> nomeDoQueEleRepresenta -> nomeMetodoQueEleRepresenta.

Exemplo:


Simples se o controller vai criar a URI, nossa estrutura do JSP deverá estar representando esse acesso, nosso controller chama-se LivroController e dentro há um método exibe sua url ficará /livro/exibe, dentro da pasta jsp (padrão) deverá conter a pasta livro (LivroController, remove-se do nome Controller), exibe (Método que há dentro de LivroController), por convenção ele saberá se achar e fazer a escolha do jsp para abrir no browser.
No exemplo para download tem todos JSPs, acesso via EL aos valores ea única taglib que utilizei foi a de formatação já citada no exemplo Spring MVC.

Comparação:
No caso do Spring é necessário configurar pelo menos 1 XML que representará onde ele encontrará os JSPs e também terá a configuração para ele achar os pacotes que contenham os mapeamentos, isso NÃO é feito no VRaptor, não existe essa configuração, o VRaptor por suas convenções é mais inteligente.

Passo 9:

web.xml
[?xml version="1.0" encoding="UTF-8"?]
[web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"]
  [display-name]projetoVRaptor[/display-name]
  [filter]
    [filter-name]vraptor[/filter-name]
    [filter-class]br.com.caelum.vraptor.VRaptor[/filter-class]
  [/filter]
  [filter-mapping]
    [filter-name]vraptor[/filter-name]
    [url-pattern]/*[/url-pattern]
    [dispatcher]FORWARD[/dispatcher]
    [dispatcher]REQUEST[/dispatcher]
  [/filter-mapping]
[/web-app]
 Notem que a configuração do web.xml é muito mais simples do que a configuração que fazemos no Spring.

Passo 10:

Para internacionalização das mensagens de erro criei um message.properties

livro.preco.invalido=preço deve ser maior que 0.
livro.titulo.nao.informado=O título é obrigatória.
livro.loja.nao.informado=A Loja de venda é obrigatória.
Espero que tenham gostado, o VRaptor é um poderoso framework MVC, para quem já utiliza Spring MVC é muito fácil entender como o VRaptor funciona, também torna bem mais simples a vida do desenvolvedor pois o único XML configurado é o web.xml, isso é uma enorme vantagem, as convenções também tornam o trabalho muito rápido e produtivo facilitando muito nossa vida.

Mais Informações:

Blog da Caelum - Links de Artigos e Cursos
Macelo Madeira - Vantagens do VRaptor
Lucas Toniazzo - Iniciando com VRaptor
Washington Botelho - Posts sobre Vraptor

Revistas:
Mundo Java (Mundo J) - Ediçoes: 61, 93, 94, 96, 98

Java Magazine - Ediçoes: 17, 38

Um Feliz Ano Novo para todos.

24 de dezembro de 2011

Tutorial Spring MVC

Faz muito tempo que não posto um tutorial completo com um projeto (código exemplo) sobre um framework, atualmente estou desenvolvendo aplicação com Spring MVC e isso acabou me motivando a escrever um tutorial sobre ele.

Aconselho antes a ler sobre Patterns como DAO, Repository, MVC, TO, PO, VO, DTO.

Passo 1:

Executem o Eclipse -> File -> New -> Project -> Dynamic Web Project

Passo 2:

Crie essa estrutura básica de pacotes.



Passo 3:

Criei dentro do pacote domain um bean
public class Produto {
     public Produto(Long id, String nome, String descricao, double preco, String cor, Long quantidade) {
     this.id = id;
     this.nome = nome;
     this.descricao = descricao;
     this.preco = preco;
     this.cor = cor;
     this.quantidade = quantidade;
}
private Long id;
private String nome;
private String descricao;
private double preco;
private String cor;
private Long quantidade;

//getters and setters

}



Passo 4:

Dentro do pacote dao criei a ProdutoDao e a ProdutoDaoI:

Interface:

public interface ProdutoDaoI {

    public void salva(Produto produto);
   
    public List pegaTodos();
   
    public void remove(Produto produto);
   
    public Produto pegaPorId(Long id);
}

Implementação:


Dentro da implementação do meu DAO notem a anotação @Repository essa anotação diz que ali será um repositório de dados ou seja seu DAO (camada de persistência),  com essa anotação automaticamente as exceptions são traduzidas e você não terá preocupações com lock otimista do JPA por exemplo.

@Repository
public class ProdutoDao implements ProdutoDaoI {

    private final static List produtos = new ArrayList();
   
    static {
        populaProdutos();
    }
   
    public void salva(Produto produto) {
        produto.setId(produtos.size() +1l);
        produtos.add(produto);
    }

    public List pegaTodos() {
        return Collections.unmodifiableList(produtos);
    }

    public void remove(Produto produto) {
        Iterator it = produtos.iterator();
        while(it.hasNext()) {
            Produto existente = it.next();
            if(existente.getId().equals(produto.getId())) {
                it.remove();
                break;
            }
        }
    }

    private static void populaProdutos() {
        produtos.add(new Produto(1l, "iPhone", "Celular da apple", 299.90, "prata", 10L));
        produtos.add(new Produto(2l, "DVD Yu Yu Hakusho", "Anime sobre Yusuke Urameshi um detetive sobrenatural.", 1999.99, "prata", 20L));
        produtos.add(new Produto(3l, "Caelum OnLine", "Cursos online da Caelum", 249.00, "verde", 60L));
        produtos.add(new Produto(4l, "Fred Rovella Show", "cd de músicas italianas", 29.90, "azul", 100L));
    }

    public Produto pegaPorId(Long id) {
        for(Produto produto : produtos) {
            if(produto.getId().equals(id)) return produto;
        }
        return null;
    }

}

Passo 5:
 
Nesse Passo serão utilizadas 2 anotações do Spring a @Service e a @Autowired (também citei a @Qualifier para quem vá utilizá-la futuramente).@Autowired: Serve para injeção de beans, como meus beans são simples posso usar tranquilamente essa anotação, mas se meu projeto começar a crescer muito será necessário usar a anotação @Qualifier para indicar qual bean quero injetar e evitar erros de injeção.
@Service: Serve para anotar a camada de serviço.

Dentro do pacote service criei as classe ProdutoService e a interface ProdutoServiceI, é ali que ficarão suas regras de negócio, ela receberá os parametros da camada view, chamará a dao e retornará a resposta para a view.

Interface:
public interface ProdutoServiceI {

    public void salva(Produto produto);

    public List pegaTodos();

    public void remove(Produto produto);

    public Produto pegaPorId(Long id);
}

Implementação:
@Service
public class ProdutoService implements ProdutoServiceI{

    @Autowired
    private ProdutoDao    produtoDao;

    public void salva(Produto produto) {
        produtoDao.salva(produto);
    }

    public List pegaTodos() {
        return produtoDao.pegaTodos();
    }

    public void remove(Produto produto) {
        produtoDao.remove(produto);
    }

    public Produto pegaPorId(Long id) {
        return produtoDao.pegaPorId(id);
    }
}


Passo 6:


As classes da camada de pacotes view, criei mais 2 pacotes form e controller, no pacote Form eu criei uma classe que terá os dados das páginas JSP e no pacote Controller as classes que controlam as chamadas do JSP para a service (Leia Controller como Managed Bean do JSF ou as Actions do Struts).


Form:

Aqui podemos ver as anotações do Hibernate Validator.
@NotEmpty: Anotação para validar se o valor é vazio.

@NotNull: Anotação para validar se o valor é nulo.
Message: Você pode customizar as mensagens que por padrão são em inglês.

public class ProdutoForm {

    private Long id;
    @NotEmpty(message = "Valor não pode ser vazio")
    private String nome;
    @NotEmpty(message = "Valor não pode ser vazio")
    private String descricao;
    private double preco;
    @NotEmpty(message = "Valor não pode ser vazio")
    private String cor;
    @NotNull(message = "Valor não pode ser nulo")
    private Long quantidade;

    //getters and setters

}


Controller:
@Controller
@RequestMapping("/produto/**")
public class ProdutoController {

    @Autowired
    private ProdutoService    produtoService;

    private ProdutoForm        produtoForm;

    private Produto         produto;
   
    @RequestMapping("/produto/formulario")
    public ModelAndView formulario() {
        return new ModelAndView("formulario").addObject("produtoForm", new ProdutoForm());
    }
   
    @RequestMapping("/produto/adiciona")
    public ModelAndView adiciona(@Valid ProdutoForm produtoForm, BindingResult result) {
        if (result.hasErrors()) {
            return new ModelAndView("formulario").addAllObjects(result.getModel());
        }
        populaBean(produtoForm);
        produtoService.salva(produto);
        return new ModelAndView("lista").addObject("produtos", produtoService.pegaTodos());
    }

    @RequestMapping("/produto/lista")
    public ModelAndView lista() {
        return new ModelAndView("lista").addObject("produtos", produtoService.pegaTodos());
    }
   
    @RequestMapping(value = "/produto/remove", method = RequestMethod.GET)
    public ModelAndView remove(@Valid @RequestParam(value = "produto.id") long id) {
        produto = new Produto();
        produto.setId(id);
        produtoService.remove(produto);
        return new ModelAndView("lista").addObject("produtos", produtoService.pegaTodos());
    }
   
    @RequestMapping("/produto/consulta")
    public ModelAndView consulta() {
        return new ModelAndView("consulta").addObject("produtoForm", new ProdutoForm());
    }
   
    @RequestMapping("/produto/pesquisa")
    public ModelAndView pesquisa(@Valid ProdutoForm produtoForm, BindingResult result) {
        produto = produtoService.pegaPorId(produtoForm.getId());
        produtoForm = populaForm(produto, produtoForm);
        return new ModelAndView("exibeProduto").addObject("produtoForm", produtoForm);
    }
   
    private void populaBean(ProdutoForm produtoForm) {
        //implementação do método de/para
    }
   
    private ProdutoForm populaForm(Produto produto, ProdutoForm produtoForm) {
       //implementação do método de/para
    }

   //getters and setters
   
}

É aqui que acontece a atuação do Spring MVC, temos a anotação @Controller que diz que essa classe será a página que receberá os valores do formulário e depois irá passar um objeto ou redirecionar para outras páginas.


@Controller: Anotação que diz que aquela classe terá como função  transformar o dados do formulário em dados do modelo, ou seja, gerenciamento entre as camadas View e Model.

@RequestMapping: Essa anotação é onde definimos o caminho do HTTP que irá ser utilizado na nossa aplicação, sendo mapeado na classe, todas as chamadas que contém "/produto/*" serão analisadas pelo Controller.

@RequestParam(value = "produto.id"): Podemos receber tanto o Form completo como apenas o parametro que desejamos com a anotação @RequestParam como parametro do método no Controller.

Podemos também enviar e receber mais de um objeto do(para o) formulário através do ModelAndView, nos frameworks mais antigos enviávamos apenas um objeto no retorno, com o ModelAndView podemos enviar mais.
Exemplo:
return new ModelAndView("exibeProduto").addObject("produtoForm", produtoForm);
Na linha acima estamos dizendo, ModelAndView coloque na página exibeProduto o objeto produtoForm.
ou ModelAndView eu quero que na página lista você coloque a lista de produtos.

return new ModelAndView("lista").addObject("produtos", produtoService.pegaTodos());

OBS: repare que o que coloco dentro do ModelAndView("lista") é o JSP lista.jsp.
OBS 2: Spring 3 trabalha por convenção, então baseado em suas anotações, JSPs e métodos , o que está dentro do @RequestMapping é o que criará na uri o caminho que chamará sua página.
Exemplo:
@RequestMapping("/produto/consulta") chamará o JSP consulta e na url ficará: /produto/consulta

Para validar o formulário utilizamos o BindingResult, ele verifica as validações e podemos retornar a página em seu estado no momento que pegamos o erro (ao invés de salvar todos objetos em param ou hiddens, mantendo seu estado.

Para validar nos parametros do método do controller que queremos fazer a validação colocamos no objeto a anotação @Valid, por exemplo: @Valid @RequestParam(value = "produto.id") long id, verifica se o id é válido ou @Valid ProdutoForm produtoForm no caso de um formulário.
Dentro do método adicionamos:


        if (result.hasErrors()) {
            return new ModelAndView("formulario").addAllObjects(result.getModel());
        }

No retorno estamos dizendo: Hei, se houver erro ModelAndView, volta pra página e devolve os objetos que estavam populados com as respectivas mensagens de erro.

Passo 7:
Para configurar o Spring precisamos colocar alguns XMLs (acalme-se não será um caminhão de XML como era antigamente)

Dentro de WebContent -> WEB-INF -> spring econtraremos o servlet-spring.xml e o app-spring.xml

servlet-spring.xml
[?xml version="1.0" encoding="UTF-8"?]
[beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-3.0.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd"]

     
    [bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"]
      [property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/]
      [property name="prefix" value="/WEB-INF/jsp/"/]
      [property name="suffix" value=".jsp"/]
    [/bean]

[/beans]
ViewResolver: aqui ele irá caçar na pasta "WEB-INF/jsp/" os nossos arquivos com sulfixo ".jsp"

app-spring.xml
[?xml version="1.0" encoding="UTF-8"?]
[beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-3.0.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd]
       
    [mvc:annotation-driven /]
    [context:annotation-config /]
   
   [ mvc:resources location="/css/" mapping="/resources/"/]
   [ mvc:resources location="/images/" mapping="/resources/"/]
   [ mvc:resources location="/js/" mapping="/resources/"/]
       
    [context:component-scan base-package="br.com.possege.loja" /]
  
   
    [import resource="spring-servlet.xml"/]

    [bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" /]
   
    [mvc:resources mapping="/resources/**" location="/resources/" /]

    [bean id="messageSource"
        class="org.springframework.context.support.ReloadableResourceBundleMessageSource"]
        [property name="basename" value="classpath:application-message" /]
        [property name="defaultEncoding" value="UTF-8" /]
        [property name="fallbackToSystemLocale" value="false" /]
    [/bean]
    
    [bean id="localeChangeInterceptor"
        class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"]
        property name="paramName" value="lang" /]
    [/bean]
    [bean id="localeResolver"
        class="org.springframework.web.servlet.i18n.CookieLocaleResolver"]
        [property name="defaultLocale" value="pt_BR" /]
    [/bean]
 [/beans]

mvc:annotation-driven: Permite enviar as requisições das classes anotadas com @Controller.
context:annotation-config: Procura todas as classes anotadas com @PersistenceContext, @Autowired, entre outros, fazendo automaticamente a injeção de dependência.
context:component-scan: Procura todas as classes anotadas no pacote definido, assim não precisamos mapeá-las em XML, quando o scan é feito as classes são passadas por um filtro e é criada a definição em um bean para cada uma delas, quem determina a definição do bean é a anotação.
mvc:resources: Serve para o acesso GET dos arquivos estáticos, como CSS, JS, etc.
import resource: Importa o outro XML de configuração do Spring.

Passo 8:

Vamos configurar o web.xml
[?xml version="1.0" encoding="UTF-8"?]
[web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"]
[display-name]projetoSpring[/display-name]

    [servlet]
        [servlet-name]spring[/servlet-name]
        [servlet-class]org.springframework.web.servlet.DispatcherServlet[/servlet-class]
        [init-param]
            [param-name]contextConfigLocation[/param-name]
            [param-value]/WEB-INF/spring/app-config.xml[/param-value]
        [/init-param]
        [load-on-startup]1[/load-on-startup]
    [/servlet]

    [!-- Spring MVC Dispatcher Servlet --]
    [servlet-mapping]
        [servlet-name]spring[/servlet-name]
        [url-pattern]/[/url-pattern]
    [/servlet-mapping]
   
    [!-- Permitir comandos HTTP RESTfull (GET, POST, PUT, DELETE) --]
    [filter]
        [filter-name]hiddenHttpMethodFilter[/filter-name]
        [filter-class]org.springframework.web.filter.HiddenHttpMethodFilter[/filter-class]
    [/filter]

    [filter-mapping]
        [filter-name]hiddenHttpMethodFilter[/filter-name]
        [servlet-name]spring[/servlet-name]
    [/filter-mapping]

    [session-config]
        [session-timeout]10[/session-timeout]
    [/session-config]

    [!--SiteMesh --]
    [filter]
        [filter-name]sitemesh[/filter-name]
        [filter-class]com.opensymphony.sitemesh.webapp.SiteMeshFilter[/filter-class]
    [/filter]

    [filter-mapping]
        [filter-name]sitemesh[/filter-name]
        [url-pattern]/*[/url-pattern]
    [/filter-mapping]
   
    [!-- Encoding --]
    [filter]
        [filter-name]encodingFilter[/filter-name]
        [filter-class]org.springframework.web.filter.CharacterEncodingFilter[/filter-class]
        [init-param]
            [param-name]encoding[/param-name]
            [param-value]UTF-8[/param-value]
        [/init-param]
        [init-param]
            [param-name]forceEncoding[/param-name]
            [param-value]true[/param-value]
        [/init-param]
    [/filter]
    [filter-mapping]
        [filter-name]encodingFilter[/filter-name]
        [url-pattern]*[/url-pattern]
    [/filter-mapping]
   
    [error-page]
        [error-code]405[/error-code]
        [location]/erro[/location]
    [/error-page]
    [error-page]
        [error-code]500[/error-code]
        [location]/erro[/location]
    [/error-page]
    [error-page]
        [error-code]404[/error-code]
        [location]/erro[/location]
    [/error-page]
    [error-page]
        [error-code]400[/error-code]
        [location]/erro[/location]
    [/error-page]
[/web-app]

 Aqui configuramos o Spring, uma pog para permitir comandos HTTP Restfull, os filtros, a configuração do SiteMesh, Encoding e páginas de erro.

O redirecionamento de um 404, 500, etc, particularmente achei bizarro a solução que encontrei foi criar um ErroController e apontar para um JSP chamado erro.
Até cheguei abrir uma discussão no GUJ mas não obtive resposta.

ErroController:
@Controller
@RequestMapping("/")
public class ErroController {

    @RequestMapping("/**")
    public ModelAndView erro() {
        return new ModelAndView("erro");
    }
}

JSP:
[%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%]
[html]
    [head]
        [title][spring:message code="produto.erro.titulo" /][/title]
    [/head]
    [body]
        [p]
            [spring:message code="produto.erro.msg_default_erroGenerico" /]
        [/p]
    [/body]
 [/html]

Passo 9:

Configurando o SiteMesh, já adianto que não fiz CSS para esse exemplo, mas o SiteMesh é um ótimo template e já o deixei configurado.

Para configurar o SiteMesh eu criei na pasta WEB-INF o decorators.xml e uma sub pasta chamada decorators com o principal.jsp dentro.

decorators.xml
[xml]
[?xml version="1.0" encoding="UTF-8"?]
[decorators defaultdir="/decorators/principal.jsp"]

    [decorator name="principal"]
        [pattern]/*[/pattern]
    [/decorator]
   
[/decorators]
[/xml]

principal.jsp
[!DOCTYPE HTML]
[%@ taglib prefix="decorator" uri="http://www.opensymphony.com/sitemesh/decorator"%]
[%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%]
[%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%]
[html]
    [head]
        [title][decorator:title default="Possege"/][/title]
        [meta charset="utf-8" /]
        [meta http-equiv="pragma" content="no-cache" /]
        [meta http-equiv="expires" content="-1" /]
        [meta http-equiv="cache-control" content="no-cache" /]
       
        [meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0;" /]       
        [meta name="format-detection" content="telephone=no" /]

        [meta name="apple-mobile-web-app-capable" content="yes" /]
        [meta name="apple-mobile-web-app-status-bar-style" content="black" /]       
       
       
        [decorator:head /]
    [/head]
    [body]
        [div]
            [div]
                [decorator:body/]
            [/div]
        [/div]
        [script src="http://www.google.com/jsapi"][/script]
       [script type="text/javascript" src="[c:url value="http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js" /]"][/script]
  [/body]
[/html]

Passo 10:

Criei uma pasta na raiz do projeto chamada resources que leva meu application-message_pt_BR.properties para internacionalização.
produto.lista.titulo=Lista de Produtos

produto.novo.titulo=Novo Produto
produto.novo.nome=Nome
produto.novo.descricao=Descri\u00E7\u00E3o
produto.novo.preco=Pre\u00E7o
produto.novo.cor=Cor
produto.novo.quantidade=Quantidade

produto.consulta.titulo=Consulta Produto
produto.consulta.codigo=C\u00F3digo
produto.consulta.lista=Listar Todos Produtos
produto.consulta.consulta=Consultar

produto.exibe.titulo=Produto Encontrado
produto.exibe.codigo=C\u00F3digo:
produto.exibe.nome=Nome:
produto.exibe.descricao=Descri\u00E7\u00E3o:
produto.exibe.preco=Pre\u00E7o:
produto.exibe.cor=Cor:
produto.exibe.quantidade=Quantidade:

produto.erro.titulo=Erro
produto.erro.msg_default_erroGenerico=Ocorreu um erro.

Passo 11:

Por fim criei todos os JSPs, não vou colocá-los aqui no blog mas vou colocar algumas tags que são essênciais e úteis.

As tag libs que mais utilizei:
[%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%]
[%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%]
[%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%]
[%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%]

Tags úteis:
[spring:message code="produto.exibe.preco" /]
[c:url var="pesquisa" value="/produto/pesquisa" /]
[form:form action="${pesquisa}" id="produtoForm" modelAttribute="produtoForm" method="post"]
[form:input path="nome" /] 
[form:errors path="nome"  /]
[fmt:formatNumber value="${produtoForm.preco }" type="currency"/]
[fmt:formatDate pattern="dd/MM/yyyy" value="${produtoForm.algumaData}"/]

spring:message: Coloca as mensagens, quando code ele pega do properties, quando text você digita o texto.
c:url: Submeter a página por um link, no caso estou passando o valor para o form:form
form:form: Nosso formulário, passo a ação, id e o modelAttribute que o Controller irá mandar, posso escolher enviar por get ou post.
for:input: Criar os campos texto para digitação no formulário.
form:errors: Pegar as mensagens de erro enviadas pelo BindingResult.
fmt:formatNumber: Formatar o valor no caso em moeda, há porcentagem e outros valores.
fm:formatDate: Formatar as datas no padrão que defini.

Fiz também um remove ajax utilizando JQuery dentro da aplicação:


[a href="javascript:void(0);" onclick="remove(${produto.id}); return false;"]Remove[/a]

[script type="text/javascript" src="[c:url value="http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js" /]"][/script]
[script type="text/javascript"]
    function remove(id){
        $.get('remove?produto.id='+id,function(){
            $('#produtoRemove-' + id).hide();
            alert('produto removido com sucesso');
            $('#produtoRemove-' + id).remove();
        });
    }
[/script]

Bom todo o fonte disponibilizei o download no GitHub.

Espero que este tutorial o ajude nos pontos que tive problemas, a ideia era mostrar uma solução com o ótimo framework MVC que os Spring nos dá.

Aconselho também estudar VRaptor é muito parecida a forma de programar e é um excelente framework MVC.

Agradecimenos especiais para Caelum e ao Christian Reichel por ter me ajudado com as dúvidas que surgiram quando comecei a programar com Spring MVC.

Comentários são bem vindos e as referências para deixar o seu template mais bonito e mais detalhes sobre Spring MVC e o VRaptor estão abaixo:


Washington Botelho - SiteMesh
Edson Gonçalves - Spring MVC
Rodolfo Chaves - Anotações do Spring
Valdemar Junior - Spring MVC com Tiles
Spring Source - Documentação Oficial
Jérôme Jaglale - Spring MVC Fast Tutorial
NetBeans - Tutorial Spring
Mkyoung - Hello World Spring
Caelum - FJ 27 Spring Framework
Caelum - FJ 28 VRaptor
Caelum - VRaptor online


Um Feliz Natal para todos. =D

4 de dezembro de 2011

Café com Java dia 10/12


O que é Café com Java?

Organizado há algum tempo por eu e o Marky Vasconcelos com extrema ajuda do Paulo Silveira, era simplesmente um encontro para o pessoal fazer um networking. Recentemente tomou um outro formato para atender mais pessoas, com mais temas. 


Porém como mês de Dezembro tem Natal, preparativos para o Ano Novo e etc, faremos o Café com Java Especial de Natal, no Blue Pub a partir das 16:00 hrs.


A entrada será de R$ 20,00 consumiveis e o que passar disso.


Vamos falar de Java, Tecnologia, Metodologias e nos divertir nesse fim de ano.


Horário: 16:00 em diante no Pub
Site do Pub: http://www.thebluepub.com.br/
R. do Pub: Alameda Campinas, 105, travessa da paulista.
Fotos dos outros Cafés com Java: Flickr
GUJ: Link do tópico
Twitter Tag: #CafeComJava

6 de outubro de 2011

Adeus Steve Jobs - #ISad


O mundo chora a perda de Steve Jobs (* 24/02/1955 - + 05/10/2011).
É assim que vou começar esse post, pois é assim que o mundo de TI se sente, estamos tristes pois perdemos uma das pessoas mais geniais que já existiram, se hoje temos nossos computadores do jeito que são devemos a ele.
Steve Jobs foi um inventor, um artista, um visionário e um grande empresário, criou uma das empresas mais valiosas do mundo a Apple Inc.
Steve influenciou milhões de pessoas no mundo inclusive eu, assisti no começo da minha carreira de TI o filme da TNT Piratas do Vale do Silício e o vídeo que ele fez na universidade de Stanford e com certeza isso me serviu muito, o sonho de trabalhar numa empresa visionária, que faz as coisas mais legais do mundo e sempre acreditando no crescimento da empresa, o que mais me tocou foi a paixão e o amor pelo seu trabalho, coisa que sempre falo até hoje inclusive até fiz um post aqui.
Nem tudo na vida dele foi um mar de rosas, não era rico, passou por problemas pessoais, mas deu a volta por cima com a Apple e quando teve que sair da companhia que amava foi um dos fundadores da Pixar outro enorme salto em sua vida.
Em 2003 na Sun Tech Days eu toquei pela primeira vez num PowerBook, na época os macs eram caros e quase ninguém tinha um, este Macbook que pude mexer era um que no Brasil haviam acabado de lançar com a propaganda de um homem grande com um Apple PowerBook de 17" e um cara pequeno com um PowerBook Apple de 20" (vídeo), Steve sempre lançou suas propagandas extravagantes e algumas polêmicas (engraçadas também como do IMac), via na época a IBM como seu inimigo, chamando-a de Big Brother em seu primeiro vídeo de lançamento da Apple faz essa referência ao Big Brother (vídeo), ele tinha uma visão do que os usuários querem, de como eles querem e com qualidade que um produto deve ser, além de um design lindo e inovador, nem todos seus produtos foram para frente, mas o Macintosh colorido e sem fios, o PowerBook, o IMac, o Macbook, o IPod, o IPod Touch, o IPhone e por último o IPad foram produtos que fizeram da Apple o que ela é hoje.
Fiquei super feliz quando comprei meu MacBook White, depois meu IPod Touch, meu IPhone, sempre admirei a qualidade da Apple com seus produtos inovadores, totalmente integrados entre si e simples, práticos e sem problemas.
A notícia sobre sua morte ontem, e depois de muito tempo ver o Twitter baleiando, as homenagens em suas homes do Google, da sua rival a Microsoft, todos os maiores jornais do mundo, blogs técnicos, revistas, as redes sociais, todos desenvolvedores, as pessoas mais importantes de TI entre elas Bill Gates, Wozniak (Fundou a Apple com Jobs), Mark Zuckerberg, Steve Ballmer, Paul Allen, James Gosling, Jack Dorsey (Twitter), Larry Page (Google), Eric Schmidt (Google), os fãs da Apple desejando que ele descansasse em paz nas HashTags (#RIPSteveJobs, #ThankYouSteve, #SteveJobs, #Apple e #ISad) foi realmente muito triste, ele nos serviu de inspiração e com certeza servirá a todas futuras gerações, o homem se foi mas o seu legado a sua marca foi deixada para todos que virão, nunca vamos esquecer a grandiosidade que Steve Jobs foi, o jeito que ele falava deixando as pessoas loucas e apaixonadas por sua empresa e seus produtos, uma pessoa assim hoje em dia é raro e com certeza ele fez um excelente trabalho.
Steve vai deixando um enorme vazio no mundo que dificilmente será preenchido, sentiremos sua falta.

Descanse em paz Steve Jobs .

Homenagem feita por Marcelo Braga.

5 de outubro de 2011

Café com Java - 08/10/2011

 

Mais uma vez tenho o imenso prazer de anunciar o Café com Java que será realizado novamente na Caelum.


O que é Café com Java?

Organizado há algum tempo por eu e o Marky Vasconcelos com extrema ajuda do Paulo Silveira, era simplesmente um encontro para o pessoal fazer um networking. Recentemente tomou um outro formato para atender mais pessoas, com mais temas.

Esse evento contará com 4 palestras de 30 minutos, e será realizado no auditório da Caelum próximo da estação Vila Mariana do metrô, em São Paulo.

Apresentações

10:00 - 10:40 - Lucas Cavalcanti (Começando com VRaptor e as novidades da versão 3.4 - Caelum)
10:40 - 11:00 - lanche
11:00 - 11:40 - Henrique Lima (Arquitetura do MoIP - Passado, Presente e Futuro)
11:40 - 12:20 - Washington Botelho (Testes de integração com DbUnit - Concrete Solutions) 

12:20 - Confraternização

Onde?

Dia: sábado, 08/10/2011 10:00 as 12:20.
Auditorio Caelum - Rua Vergueiro, 3185 - Próximo da estação Vila Mariana do metro.
Inscreva-se, vagas limitadas:
http://www.caelum.com.br/evento/cafecomjava/



Valor?

Entrada franca, mas é obrigatório a inscrição.

Quem pode ir?

Todos! É uma confraternização, um networking, nada formal, também não é algo focado apenas em Java, se você programa em outra linguagem vá também. 

  
Fotos dos outros encontros:

As fotos podem ser encontradas no meu Flickr: Fotos do Café com Java



Twitter HashTag: #CafeComJava
GUJ: Café com Java no GUJ



22 de setembro de 2011

Cursos online na Caelum

 


A Caelum abriu hoje alguns cursos online, com vídeo, apostila e exercícios, o curso é muito didático, estou fazendo o curso Gráficos com Google Chart Tools, os vídeos com explicação do Guilherme Silveira e outros instrutores é auto-explicativo e excelente, seguindo os vídeos e fazendo todos os exercícios passo a passo você com certeza aprenderá de forma rápida e sem dificuldade.
Para o pessoal que mora em estados ou cidades onde há carência na parte de escolas profissionais e de qualidade para linguagens de programação e ferramentas para desenvolvedores e claro para as pessoas que não tem condições de horários ou meios de transporte para ir até a escola está aí a chance de ter cursos de qualidade de forma prática.
Até o momento o aluno terá as opções de curso:

GC-01 - Gráficos com Google Chart Tools
ED-28 - VRaptor: Desenvolvimento web rápido e fácil
SQ-01 - Banco de Dados e SQL
 
Link do site dos cursos: http://online.caelum.com.br/
Link do Blog da Caelum: http://blog.caelum.com.br/ha-bom-aprendizado-em-cursos-online/
Site da Caelum: http://www.caelum.com.br/

Vídeo da Caelum online: Caelum online

14 de setembro de 2011

QConSP 2011 - Eu Fui e foi Show!



Esse ano houve a segunda edição do QConSP (Twitter: #QConSP) com diversas palestras de alto nível, o melhor evento de TI do ano, diversos palestrantes de fora do Brasil, vou falar um pouco do fim de semana na QCon São Paulo.
Os slides das palestras podem ser vistos acompanhando a time line do #QConSP pelo twitter.
Antes de falar das apresentações vou falar da galera (que com certeza esquecerei de botar todos, pois foram muitos amigos tanto os que estavam fora como os que moram em outros estados do Brasil), foi ótimo rever o pessoal do JavaCE que foram numa caravana enorme para o QCon, o Handerson Frota, o Celso Martins, o Danilo Sato que atualmente está na Europa, a Loiane (IBM), o Diego Plentz, Bruno Borges de Wicket, o Fabio Akita, Luca Bastos, Christiano Milfont, Lucas Cavalcanti, Maurício Linhares, Fernando Boaglio, Washington Botelho, Bruno Oliveira, Alberto Luiz Souza, Cristiano Sanchez, Jean Donato, Alexandre Freire, Marcelo Tozzi,  o pessoal do GURUSP, do CafeComJava (Alexandre Saudate, Rafael Afonso, Léo Biscassi e Christian Reichel), muitos amigos do GUJ (incluindo os desaparecidos como Fernando Meyer, Fábio Kung e o Daniel Destro) e é claro está de Parabéns novamente pela organização a CAELUM, revi meus grandes amigos que considero como irmãos, o Paulo Silveira, o Guilherme Silveira, o Guilherme Moreira que atualmente cuida da Caelum no DF, o Nico Steppat (atualmente cuidando da Caelum RJ), o Sérgio Lopes, Luiz Bassi, Renata Bassi, Camila Farinho, Cecilia Fernandes, Adriano Almeida, Anderson Leite, David Paniz, Rubem Azenha, Douglas Campos (qmx), Gabriel Oliveira, José Donizetti, Raphael Lacerda, certeza que estou esquecendo pessoas... 


Sábado:

No Sábado assisti as palestras:
Jim Webber - Aprendizados de grandes sistemas HTTP-centric.

Sérgio Lopes - Por uma Web mais rápida: Técnicas de otimização de Sites
Danilo Sato - Refatoração em larga escala

Guilherme Silveira - Design de código: a qualidade que faz a diferença
Daniel Destro -
Arquitetura de um sistema crítico de alta disponibilidade com soluções open source
Raphael Lacerda - Além do CDI com Seam 3
Daniel Sobral - Akka - Uma plataforma para o desenvolvimento de sistemas concorrentes e distribuídos para a JVM 
 

Lightning Talks

Christian Reichel - Por um Java mais funcional

José Donizetti - Dicas para testar código legado.
Eder Ignatowicz - Desenvolvimento Ágil Orientado a Testes: Como a busca pela qualidade transformou uma equipe de desenvolvimento Java
Daniel Cukier - Desenvolvendo sua infra-estrutura com testes
Handerson Frota - Aceite os testes de aceitação
Eduardo Bregaida - Cultura da Empresa - um problema na Adoção Ágil 

Eu adorei ter tido a oportunidade no QCon de apresentar um Lightning, achei que ia estourar o tempo, no final ainda sobrou um minuto e quarenta e um segundos rs ;D

Depois fomos para o hora extra no bar Opção continuar o networking.

Domingo:

As palestras que assisti no domingo foram:
Kunal Bhasin - Caching e NoSQL? 
Khawaja Shams - MythBusters - Mission Cloud Computing @ NASA
Nelson Haraguchi -  Escalando e Otimizando Projetos Legados
Saulo Arruda -  5 anos em 1 - aprendendo a empreender
Cecilia Fernandes - Melhorando um ambiente ágil
Fernando de la Riva -  Lean Startups
Cristiano Sanchez e Wladimir Domingues - Aplicações Móveis Híbridas: usando Web e Nativo juntos

Final das contas, o evento superou o de 2010, vale cada centavo, aprendi muitas táticas algumas que já comecei utilizar na empresa, o QConSP é um evento que se mostrou eficaz e de grande valia, não só por essas ótimas palestras, mas também pelo networking, rever os amigos que não estão por perto e conhecer as pessoas que normalmente conversamos apenas pelo fórum ou através de emails, messengers e afins...
Parabéns Caelum por mais esse sucesso.

Ano que vem tem mais QConSP.

Nos vemos lá =)  

10 de agosto de 2011

Café com Java 20/08



Dia 20/08/2011(Sábado) haverá o Café com Java.

O que é Café com Java? 

Organizado a algum tempo por eu e o Marky Vasconcelos, era simplesmente um encontro para o pessoal fazer um networking. Mas como concluimos que seria uma boa idéia apresentarmos alguns assuntos em forma de palestras para compartilhar um conteúdo mais técnico antes do PUB, esse Café com Java será um pouco diferente.

Esse evento contará com 4 palestras de 30 minutos, e será realizado no auditório da Caelum próximo da estação Vegueiro do metrô.

Apresentações: 

09:30 - 09:45 - Paulo Silveira (Boas vindas)
09:45 - 10:30 - Adriano Almeida (Java 7 na prática: o que muda no meu código?)
10:30 - 11:00 - Eduardo Bregaida (Refatoração de Código com Capitão Nascimento)
11:00 - 11:45 - lanche
11:45 - 12:15 - Alexandre Saudate (SOA)
12:15 - 12:45 - Marcos Vasconcelos (Android Overview)

Preciso me inscrever?

Sim, apenas para quem for assistir as palestras, pois o auditório tem um espaço limitado.
Para o HappyHour não será necessário.
Preencha o formulário: AQUI

Onde?
Auditorio Caelum - Rua Vergueiro, 3185 - Próximo da estação Vila Mariana do metro.

Quem pode ir? 

Todos! É uma confraternização, um networking, nada formal, também não é algo focado apenas em Java, se você programa em outra linguagem vá também.

Posso chamar amigos?
Claro que SIM =)

Fotos de outros Café com Java: Flickr

Eu estarei lá e você?


Não esqueçam!

Dia: 20/08/2011
Hora:  09:30 - 12:45 na Caelum, após as 12:00 hrs no barzinho e Lanchonete Batidão também na Vila Mariana até a hora que todo mundo for embora

Preencha o formulário (Somente para quem for assistir as palestras): AQUI
Local: Auditorio Caelum - Rua Vergueiro, 3185 - metrô Vila Mariana - mapa.
Local Batidão (HappyHour): Rua Domingos de Morais, 1527 - Vila Mariana (próximo do metrô) - mapa.
Twitter HashTag: #CafeComJava
GUJ: Café Com Java
 

Caelum: Site

2 de julho de 2011

FISL 12 - Eu Fui!



Hoje foi o dia da minha palestra Refatoração de Código com Capitão Nascimento no FISL que postei no período da tarde lá no evento.
Eu achei o evento demais, as pessoas muito interessadas, pessoas de todas as idades e muitas garotas, para o pessoal que fala que mulheres e TI não rolam... bom aqui em Porto Alegre haviam muitas do Feminino Livre.
A palestra estava bem cheia e consegui distribuir os 10 kg de brindes que levei de SP.
O pessoal se interessou principalmente por TDD e qualidade de Teste, foi motivador.

Depois acabei indo passear pelo evento, muitas empresas e faculdades, vários grupos de usuários, foi bem divertido.

Logo após o almoço fui assistir as palestras: Nós somos todos piratas! O Capitalismo Selvagem, depois uma boa discussão sobre o LibreOffice, a palestra Manipulação de Arquivos com Apache POI e por fim a palestra Metasploit Framework: a lightsaber for pentesters!

Foram muito boas todas essas palestras e discussões que participei.

Conheci pessoas muito legais do RJ, SP e claro de POA, o evento acabou mas a amizade continua.

Agora mês de Agosto Café com Java e Setembro QConSP.

Espero ver todo mundo lá.

FISL 12 - Refatoração de Código com Capitão Nascimento

2 de junho de 2011

A equipe faz o sucesso do projeto

Desculpem pela demora dos posts e a falta de post técnicos, o tempo anda muito curto e estou fazendo muita coisa ao mesmo tempo.
Nesses anos todos de Java, vi diversos tipos de equipes, gerentes, etc, chegando a conclusão óbvia que a equipe é que faz realmente a diferença, não importa se você utiliza metodologias ágeis, se você não tem um ótimo time seu projeto dança do mesmo modo.
Já postei sobre uma equipe que eu adorei trabalhar com excelentes profissionais anteriormente e hoje vou falar sobre a equipe que trabalho nesses quase 2 anos de 5A/Casas Bahia.
Fui contratado e comecei no dia 28 de Agosto de 2009 quem me entrevistou foi José Roberto para trabalhar na Loja Virtual das Casas Bahia.
Vou falar apenas dos desenvolvedores com quem trabalhei diretamente e me proporcionaram conhecimento e bons momentos durante os projetos, já que fiz um networking gigante na empresa e não daria para falar de todos rs ;P

Felipe Torres Carrasco, trabalhou comigo na época da loja virtual, manda muito bem em Java, um ótimo profissional, atualmente ele está em uma equipe diferente da minha, mas quando trabalhamos juntos acabamos levando diversos conceitos e mudando alguns paradigmas antigos que estavam implantados na cultura da empresa na época.

Robson Simonassi, estudou comigo e sempre debatíamos sobre Java, antes de entrar para trabalhar com o Felipe trabalhou no mesmo projeto da JAPI 2 anos depois que eu havia saído da empresa.

Hoje trabalho com o pessoal da empresa Advus em projetos internos e eles todos me lembram muito a época que trabalhei na Masterdom.

Marcelo Ingarano, é nosso líder técnico e arquiteto de sistemas Java, me lembra demais o Christian Reichel da Masterdom, um enorme conhecimento, um cara que está sempre ensinando e ajudando, mantém a equipe unida, é ele quem me passa trabalho e é super exigente como todo líder técnico deveria ser.

Alexandre Barboza (Aspira)
, é também um dos líderes técnicos, cara responsável, também sempre está ajudando e fazendo as coisas andarem.

Lucio Toledo, bom o Lucio é praticamente a pessoa que mais trabalhou comigo nos projetos, todos os projetos que ele estava eu também estava, mesmo com poucos anos de experiência é um cara que conseguiu absorver muita coisa em um curto espaço de tempo, é um ótimo programador, sempre se dedicando em tudo que faz, ele me lembra o Thiago Senna em nível de aprendizagem, uma pessoa capaz de resolver diversos problemas, sempre calmo e focado ajudou muito no projeto.

André Ueda, é um desenvolvedor (atualmente está na área de análise) que também ajudou muito, super gente boa, também um cara que aprende rápido, discute os problemas quando preciso e enchi o saco dele para gerar massas e massas de testes no projeto que trabalhou comigo rsss

Carlos Bergamasco (Refactor Man), o Carlos é um excelente profissional, dedicado e também atua como líder técnico em alguns projetos, chamo ele de Refactor Man devido ao fato dele refatorar código até o máximo possível, ele deveria escrever um livro de refatoração (FATO), no último projeto que trabalhei com ele o Carlos ajudou-me demais, principalmente na hora de refatorar alguns métodos que unimos, ele já é desenvolvedor Sênior e faz APIs para facilitar nossas vidas, manda super bem.

Vanderlei Banin, trabalha em um outro projeto, manja muito de JSF, é um cara que faz o diabo pra resolver pepinos do framework, também manda bem na parte de integração e automatização, super gente fina está também sempre discutindo sobre melhores soluções.

Henrique Souza, trabalhou comigo e com o Lúcio no nosso primeiro projeto quando fui para essa equipe, ele aprende muito rápido, manda muito bem em SQL, ele veio de outra linguagem e em pouco tempo aprendeu Java, hoje ele está em outra equipe mas trouxe muita ajuda no start do projeto que eu e o Lúcio desenvolvemos.

Braulio Consani Moura, desenvolvedor Sênior e instrutor da Caelum, está no mesmo projeto que o Henrique e o Fábio (próximo), manja muito de arquitetura e tem uma ótima didática, fui assistir algumas aulas dele na Caelum e mandou super bem, na parte de arquitetura também faz tudo certo e com qualidade, agregou muito na equipe.

Fábio Lourencetti, Fábio é também desenvolvedor Sênior e líder de um dos projetos que trabalhamos, ele é um dos mais reservados da equipe, super gente boa também, sempre que possível vou lá encher o saco dele, ele tem enormes conhecimentos na área de mercado financeiro, passou diversos sites sobre o assunto, é também um ótimo desenvolvedor Java e com certeza também traz muita qualidade para a equipe.

Gilnei Piauhy, é um desenvolvedor bem alegre e sem tempo ruim, super divertido, ele está se desenvolvendo muito rápido na equipe, sempre esforçado, é um grande programador e um ótimo amigo.

Júlio C. Fradico, está desenvolvendo comigo um gerador de conteúdo para testes, um framework que espero que em breve esteja na net para ajudar na comunidade Java, ele tem um grande conhecimento, também corre atrás de como resolver diversos problemas, dedicado e sempre se preocupando com a qualidade do código gerado.

Renato de Carvalho Ceadareanu, um programador sênior com grande conhecimento e capacidade, refez todo um projeto que estava ruim e além de deixá-lo mais organizado, ele também o deixou mais bonito e funcional, tem um profundo conhecimento de diversos frameworks para deixar seus códigos com maior qualidade, sem perder performance ou qualidade, também manda super bem na área de gerencia de projetos, uma grande pessoa.

Bom esses são os desenvolvedores e líderes que trabalho atualmente e tenho que deixar aqui registrado que a equipe se ajuda muito e isso agrega demais para o sucesso de todos nossos projetos dentro da empresa, todos são de estudar e correr atrás, não existe comodismo dentro da nossa equipe e isso que traz qualidade no nosso software, sinceramente dá vontade de pegar todos esses profissionais mais os que citei no post sobre a equipe da Masterdom e colocamos em uma empresa, com certeza acabaria se tornando uma equipe pró-ativa total, com conhecimentos extremos e qualidade desejada de todos os clientes.
Ter profissionais qualificados com excelente conhecimento, pró-ativa, sem comodismo, que sempre busca aprender coisas novas, buscando o melhor para o projeto faz toda a diferença e essas duas equipes tenho orgulho de citar neste blog, pois é muito difícil achar profissionais assim no mercado, quando acham não é uma equipe é um indivíduo ou outro, ter pessoas com esse perfil unidas garante a qualidade de um software que seria a "menina dos olhos" em qualquer empresa.

Parabéns a todos.