Makoto Hashimoto

Just for fun!

Esse post foi motivado pela forma não elegante que eu estava tratando as exceções em requisições ajax em minhas aplicações com VRaptor.

Sempre que eu fazia uma requisição ajax e precisava de tratar um erro acabava fazendo de uma forma bem procedural. Utilizava o retorno do callback do ajax e verificava se o retorno era um erro ou o dado esperando. Mas isso está bem longe de ser uma forma elegante de se tratar erros, sem falar que para cada ocasião é necessário verificar se o dado é erro ou não de forma diferente.

Então tive a ideia de não tratar mais o erro no controller e deixar para tratar no callback de erro do ajax, mas ai tive outro problema. Como ter mais de uma error page? Uma vez que a página de erro customizada para o usuário não seria muito útil para receber no callback de erro. Postei minha dúvida para a lista do VRaptor da Caelum (caelum-vraptor@googlegroups.com) e o Lucas Cavalcante (@lucascs) me deu a idéia de fazer um interceptor com um try…catch e utilizar o accept do Header para saber se a requisição é ajax. Gostei da ideia, implementei e resolvi fazer este post.

A implementação foi bem fácil e tranquila. Primeiro criei um Interceptor que chamei de AjaxExceptionInterceptor.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
    @Intercepts
    public class AjaxExceptionInterceptor implements Interceptor {
       
        private HttpServletRequest request;
        private Result result;
       
        public AjaxExceptionInterceptor(HttpServletRequest request, Result result) {
            this.request = request;
            this.result = result;
        }

        public boolean accepts(ResourceMethod method) {
            return request.getHeader("accept").contains("application/json");
        }

        public void intercept(InterceptorStack stack, ResourceMethod method,
                Object resourceInstance) throws InterceptionException {
            try {
                stack.next(method, resourceInstance);
            } catch (Exception e) {
                result.use(Results.http()).body(e.getCause().getMessage());
            }
        }

    }

Reparem nas implementações dos métodos “accepts” e “intercept” exigidas pelo contrato da interface Interceptor.

Você verá que na implementação do método “accepts” é verificado se é uma chamada ajax pelo conteúdo do accept do Header.

E na implementação do método “intercept” foi colocado um try…catch e caso o controller lance uma excessão, a mesma será capturada e então é enviada uma resposta com a mensagem da exception e não o html padrão do tomcat ou algum outro customizado no web.xml.

O controller é implementado sem tratar as exceções ou lançando as exceções customizadas.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
    @Resource
    public class IndexController {

        private final Result result;

        public IndexController(Result result) {
            this.result = result;
        }

        @Path("/")
        public void index() {
        }
       
        @Post
        @Path("/testaCodigo")
        public void testaCodigo(String codigo) {
            if (codigo == null || codigo.isEmpty()) {
                throw new RuntimeException("Código Inválido");
            }
           
            result.use(Results.json()).withoutRoot().from("Sucesso!!!!").serialize();
        }

    }

E por último basta fazer a chamada ajax na página.

1
2
3
4
5
6
7
8
9
10
11
12
    $.ajax({
        url : "<c:url value='/testaCodigo' />",
        type: "post",
        dataType: "json",
        data: "codigo=" + $("#codigo").val(),
        success: function (data) {
            alert(data);
        },
        error: function (jXHR, textStatus, errorThrown) {
            alert(jXHR.responseText);
        }
    });

Repare que agora temos um código mais elegante onde não precisamos verificar o retorno do callback de sucesso para saber se é um erro ou o dado esperado. Agora usamos o callback de erro do $.ajax do jQuery para capturar o erro caso ele ocorra e dar o tratamento desejado.

Clique aqui para ver o projeto completo que fiz com esse exemplo funcional no github.

January 24th, 2011

Meu ambiente de trabalho em 7 itens

2 Comments, Agile, Giran, Java, by makoto.

Meu ambiente de trabalho em 7 itens, alguém começou esse meme e então meu amigo @jeveaux me convocou para participar e falar um pouco sobre meu ambiente de trabalho.

1) Macbook Pro de 13″

Além de muito bonito é uma máquina fantastica. Na minha opinião macbook pro de 13″ é a melhor escolha para quem procura mobilidade e performance. E ainda vem com o OSX, um Sistema Operacional estável, elegante e muito intuitivo. Não poderia deixar de falar do trackpad ANIMAL dele, que sem sombra de dúvidas é o melhor do planeta. Definitivamente cada dia que passa fica mais impossível voltar a usar um PC.

2) Google

Utilizo o tempo todo o santo Google para buscar todo tipo de coisa. Utilizo também o GMail e o Calendar que juntos salvam várias vidas. E tudo isso obviamente integrado sincronizado com o meu IPhone.

3) Git + gitHub

Git é uma ferramenta de controle de versão distribuida extremamente fantastica. Onde cada usuário possui um repositório completo na sua máquina, o que possibilita o maior números de commits. Pois mesmo se a tarefa/módulo/funcionalidade/etc ainda não esteja pronta você pode fazer o seu commit tranquilo que só vai ficar no seu repositório local, dai quando realmente terminar é só dar um push para o repositório “master”.

E o serviço do Github é matador. Eu utilizo na Giran, nos meus projetos pessoais e em meus projetos open-sources. Como diz meu amigo @franciscosouza o Github já faz parte da minha vida.

4) Eclipse

Trabalho quase que exclusivamente com Java e na minha humilde opinião o Eclipse é a melhor IDE disparada. Mas é sempre bom saber usar outras ferramentas como o VIM que me ajuda bastante quando faço acesso remoto via SSH.

5) Giran

O ambiente que a Giran oferece é muito show. É uma empresa jovem com uma estrutura hierárquica horizontal, ela nos oferece total liberdade, uma biblioteca recheada de livros, macbooks, aulas de inglês e temos a nossa disposição um Xbox 360 e muitos jogos \o/ ! Sem sombra de dúvidas é um ambiente que me motiva bastante.

Não poderia deixar de citar as pessoas, e a Giran possui um time multi-disciplinar com nerds de todos os tipos. Pessoa essas que me fazem crescer tanto pessoalmente quanto profissionalmente todos os dias. Posso dizer que sou um privilegiado, pois faço o que gosto com pessoas legais e em um ambiente totalmente d+!

6) Scrum + XP

Na Giram usamos a combinação matadora Scrum + XP e adotamos uma postura não covarde, o que vem dando muito certo. Estamos obtendo resultados muito bons e o melhor de tudo clientes satisfeitos.

7) VirtualBox

Infelizmente nem tudo é perfeito e o maldito IE é o “navegador” mais usado. Por isso eu necessito de uma VM só para fazer os testes das aplicações no IE. Escolhi o VirtualBox porque ele é leve, gratuito e open-source.

Para não quebrar a corrente

Indico meus amigos a participar:

  • Rafael Carneiro (@rcarneiro)
  • Carlan Calazans (@carlancalazans)
  • Washington Botelho (@wbotelhos)
  • André Tagliati (@tagliati)
  • Gabriel Benz (@glbenz)

Quando estamos desenvolvendo sistemas web sempre aparece aquela tela monstro com mais de 20 campos, dai bate aquele desânimo. Cansado de sofrer com isso desenvolvi o jQuery Form Fill Plugin.

O Form Fill recebe um objeto JSON e preenche um form com os valores do objeto, simples assim!

Segue abaixo as features do plugin:

  • Preenche todos os tipos de elementos do form:

    • text
    • password
    • hidden
    • textarea
    • checkbox
    • radio
    • select
  • Preenche campos que utilizam o jQueryUI Datepicker

    • Data no formato texto. Ex: mm/dd/yyyy ou yyyy-mm-dd
    • Data em milisegundos.
  • Resolve nomes de elementos em estilo de objeto (usuario.nome) por default, mas também funciona sem estilo (nome).

Vamos fazer um exemplo com as opções default do plugin.

Primeiro iremos fazer um form com os nomes dos elementos no estilo O.O.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
    <form id="form1">
        <label>Nome:</label>
        <input type="text" name="user.name" />
        <br /><br />

        <label>E-mail:</label>
        <input type="text" name="user.email" />
        <br /><br />

        <label>Phone:</label>
        <input type="text" name="user.phone.codeArea" size="3" maxlength="3" />
        <input type="text" name="user.phone.number" size="11" maxlength="10" />
        <br /><br />

        <label>Date:</label>
        <input type="text" name="user.date1" id="date1" /> from string (mm/dd/yyyy, mm-dd-yyyy, yyyy-mm-dd or yyyy/mm/dd)
        <br /><br />

        <label>Date 2:</label>
        <input type="text" name="user.date2" id="date2"/> from milliseconds
        <br /><br />

        <label>Gender:</label>
        <select name="user.gender">
            <option>--select--</option>
            <option value="F">Female</option>
            <option value="M">Male</option>
        </select>
        <br /><br />

        <label>Is Administrator?</label>
        <!--input type="checkbox" name="user.admin" value="Y" -->

        <input type="radio" name="user.admin" value="Y"> Yes
        <input type="radio" name="user.admin" value="N"> No
        <br /><br />

        <label>Rules:</label>

        <input type="checkbox" name="user.rules[0].id" value="1" /> Admin<br />
        <input type="checkbox" name="user.rules[1].id" value="2" /> User<br />
        <input type="checkbox" name="user.rules[2].id" value="3" /> Developer
        <br /><br />

        <input type="button" id="btnExample1" value="Fill" />
        <input type="reset" value="Reset" />
    </form>

Agora vamos implementar o evento onclick do botão Fill do form1. Vamos criar um objeto JSON e chamar o método fill no seletor do form1 e a mágica será feita.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
    $("#btnExample1").click(function() {                   
        var user = {"name" : "Makoto Hashimoto",
                    "email" : "makoto@makoto.blog.br",
                    "phone" : {
                        "codeArea" : "+55",
                        "number" : "2755555555"
                    },
                    "date1": "03/30/1981",
                    "date2": "354769200000",  // 1981-03-30 in milliseconds
                    "gender" : "M",
                    "admin" : "Y",
                    "rules" : [
                        {"id" : "1", "name": "Admin"},
                        {"id" : "3", "name": "Developer"}
                    ]                              
        };
       
        $("#form1").fill(user);
    });

Seguem abaixo os links das páginas do projeto e do projeto no Github.

Página do Projeto – http://makoto.blog.br/formFill

Projeto no Github – http://github.com/makotohashimoto/formFill

April 20th, 2010

Maré de Agilidade em Vitória

3 Comments, Agile, Eventos, by makoto.

Acompanhando o Maré de Agilidade de BH teremos o Maré de Agilidade em Vitória, chamado de Maré Vix. Este grande evento ocorrerá na faculdade Faesa Campus I no dia 29 de Maio.

Com os patrocínios da GiranCaelumGUJinfoQBRHighlanQualidata e PowerLogic contará com grandes palestrantres:

Para maiores informações acesse: http://www.mare-vix.com/index.php/palestras/