Image Image Image Image Image
Scroll to Top

Topo

md5

23

nov
2011

Sem Comentários

Em Blog
Código
Java

Por Allison

Criando uma Tag Library para carregar a imagem de um perfil do Gravatar

Em 23, nov 2011 | Sem Comentários | Em Blog, Código, Java | Por Allison

Há alguns dias eu estava querendo um tempo para estudar um pouco a API do Gravatar, que por sinal funciona muito bem aqui no WordPress. Lendo a documentação de uso, percebi que muito fácil de você obter a imagem de um perfil do Gravatar usando um hash do e-mail do usuário com criptografia MD5.

Primeiramente, como sou um usuário fanático do jQuery, tentei resolver a bronca direto por Javascript, mas acabei empacando na geração do hash MD5, não sei porque, mais aqui nenhuma implementação Javascript para MD5 funcionou, assim parti para o plano B, usando a API Java para gerar o hash MD5, perfeito, funcionou corretamente, tá bom, mas agora eu tenho a implementação lá em uma classe Java, como que eu ligo isto com a minha view HTML/JSP ?

Usando o VRaptor 3.4, fiz uma requisição AJAX/JSON e retornava o hash e fazia o carregamento da imagem via jQuery, assim:

01	$(document).ready(function(){
02	   $('#button').bind('click', function(){
03	      var email = $('#email').attr('value');
04
05	      var url = "<c:url value='/gravatar/get-md5/'/>";
06	      $.post(url, {email: email}, function(data){
07	         var url = "http://www.gravatar.com/avatar/" + data.string + "?s=200";
08	         $('#result').html($("<img/>").attr('src', url)).append('<br/><i>' + data.string + "</i>");
09	      });
10	   });
11	});

Na minha aplicação Java eu tinha duas classes, uma que implementava o hash MD5 e a outra que era o meu controller da requisição AJAX/JSON:

01	package com.wp.carlos4web.cpropriedades.md5;
02
03	import java.io.UnsupportedEncodingException;
04	import java.security.MessageDigest;
05	import java.security.NoSuchAlgorithmException;
06
07	public class MD5 {
08	    public static String hex(byte[] array) {
09	        StringBuffer sb = new StringBuffer();
10	        for (int i = 0; i < array.length; ++i) {
11	            sb.append(Integer.toHexString((array[i] & 0xFF) | 0x100).substring(
12	                    1, 3));
13	        }
14	        return sb.toString();
15	    }
16
17	    public static String md5Hex(String message) {
18	        try {
19	            MessageDigest md = MessageDigest.getInstance("MD5");
20	            return hex(md.digest(message.getBytes("CP1252")));
21	        } catch (NoSuchAlgorithmException e) {
22	        } catch (UnsupportedEncodingException e) {
23	        }
24	        return null;
25	    }
26	}
27	// Controller.
28	package com.wp.carlos4web.cpropriedades.controllers;
29
30	import com.wp.carlos4web.cpropriedades.md5.MD5;
31
32	import br.com.caelum.vraptor.Get;
33	import br.com.caelum.vraptor.Post;
34	import br.com.caelum.vraptor.Resource;
35	import br.com.caelum.vraptor.Result;
36	import br.com.caelum.vraptor.view.Results;
37
38	@Resource
39	public class HomeController
40	{
41	    private Result result;
42
43	    public HomeController(Result result) {
44	        super();
45	        this.result = result;
46	    }
47
48	    @Get("/")
49	    public void index ()
50	    {
51
52	    }
53
54	    @Post("/gravatar/get-md5/")
55	    public void generateMD5Hash(String email)
56	    {
57	        String hash = MD5.md5Hex(email);
58
59	        this.result.use(Results.json()).from(hash).serialize();
60	    }
61	}

O código é bem simples, e funcionou, atendendo o que eu precisava, só que daí pensei em ‘componentizar’ essa solução, daí acabei refletindo e vi que seria inviável inicialmente, logo então pensei em uma solução alternativa à uma interação/codificação Javascript/AJAX, logo a única saída seria escrever uma tag própria para isso, pronto, encapsula a lógica em uma classe Java e vincula a mesma em uma tag acessível pelo HTML/JSP.

As tag libraries, ou tag support do Java são bem simples de serem utilizadas e implementadas, não sou um grande conhecedor, mas com algumas pesquisas na documentação consegui desenvolver a solução sem muitos problemas. Bom primeiramente precisamos criar a nossa classe que contém a implementação necessária, mais qual implementação ?

A implementação/ligação com a classe que gera o hash e que cria o elemento IMG para ser inserido no corpo da página HTML/JSP, o código da classe está na listagem abaixo e é bem simples, repare que os atributos ‘email’ e ‘imageSize’ são os parâmetros da nossa tag na página HTML/JSP.

01	package com.wp.carlos4web.gravatar;
02
03	import java.io.IOException;
04
05	import javax.servlet.jsp.JspException;
06	import javax.servlet.jsp.tagext.TagSupport;
07
08	import com.wp.carlos4web.cpropriedades.md5.MD5;
09
10	public class GravatarTag extends TagSupport
11	{
12	    private static final long serialVersionUID = 1066237315711135837L;
13
14	    protected String    email;
15
16	    protected int       imageSize = 200;
17
18	    @Override
19	    public int doEndTag() throws JspException
20	    {
21	        if(email != null && !email.isEmpty())
22	        {
23	            try
24	            {
25	                // Gera o hash MD5.
26	                String hash = MD5.md5Hex(email);
27
28	                // Monta a URL para a imagem remota.
29	                String url = "http://www.gravatar.com/avatar/" + hash + "?s=" + imageSize;
30
31	                // Monta a tag HTML IMG com a URL remota.
32	                String img = "<img src='" + url + "'/>";
33
34	                // Insere no corpo da página onde a tag está sendo chamada.
35	                this.pageContext.getOut().write(img);
36	            } catch (IOException e) {
37	                e.printStackTrace();
38	            }
39	        }
40	        return super.doEndTag();
41	    }
42
43	    public String getEmail() {
44	        return email;
45	    }
46
47	    public void setEmail(String email) {
48	        this.email = email;
49	    }
50	    public void setImageSize(int imageSize) {
51	        this.imageSize = imageSize;
52	    }
53
54	    public int getImageSize() {
55	        return imageSize;
56	    }
57	}

Como vocês viram o código é bem simples. Não existe regra sobre qual pacote deve ficar a sua classe, somente no arquivo TLD de descrição você deverá informar o caminho dela, exemplo: ‘br.pacote.pacote.SuaClasse’. Não esqueça:

  • Criar os métodos setters para os seus atributos, caso falte algum será gerada uma exception na sua aplicação.

Caso contrário não irá funcionar.

O próximo passo e a estruturação da nossa tag, para isso eu segui o padrão do desenvolvimento de tags, no meu diretório WEB-INF, eu criei um diretório tags e dentro dele um diretório com um nome significativo, neste caso ‘gravatar’. Dentro dele, seguindo a convenção, criei um arquivo .TLD com o nome da minha classe, logo ‘gravatar.tld’. Abaixo segue a codificação do mesmo, que também é bem simples e segue um padrão.

01	<?xml version="1.0" encoding="ISO-8859-1" ?>
02	<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN" "http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd">
03
04	<taglib>
05	    <tlibversion>1.0</tlibversion>
06	    <jspversion>1.1</jspversion>
07	    <shortname>gravatar</shortname>
08	    <uri>http://carlos4web.wordpress.com/</uri>
09	    <info>Insere uma tag IMG com o gravatar de um usuário a partir do seu E-mail.</info>
10
11	    <tag>
12	        <name>gravatar</name>
13	        <tagclass>com.wp.carlos4web.gravatar.GravatarTag</tagclass>
14	        <bodycontent>JSP</bodycontent>
15	        <info>Say Hi</info>
16
17	        <attribute>
18	            <name>email</name>
19	            <required>true</required>
20	            <rtexprvalue>true</rtexprvalue>
21	        </attribute>
22	        <attribute>
23	            <name>imageSize</name>
24	            <required>false</required>
25	            <rtexprvalue>true</rtexprvalue>
26	        </attribute>
27	    </tag>
28	</taglib>

O próximo passo é usar a nossa tag, esta é a parte mais fácil da brincadeira, primeiramente, declare o import da nossa tag library:

1	<%@ taglib prefix="carlos" uri="/WEB-INF/tags/gravatar/gravatar.tld" %>

Agora é só chamar quando você precisar:

01	<table>
02	    <tr>
03	        <td valign="top">
04	            <carlos:gravatar email="carlosjrcabello@gmail.com" imageSize="30"/>
05	        </td>
06	        <td valign="top">
07	            <carlos:gravatar email="carlosjrcabello@gmail.com" imageSize="50"/>
08	        </td>
09	        <td valign="top">
10	            <carlos:gravatar email="carlosjrcabello@gmail.com" imageSize="100"/>
11	        </td>
12	        <td valign="top">
13	            <carlos:gravatar email="carlosjrcabello@gmail.com" imageSize="300"/>
14	        </td>
15	    </tr>
16	</table>

Lembrando pessoal, que segundo a API do Gravatar, quando a imagem do perfil não é encontrada, é retornado uma imagem padrão com a logo do gravatar. Caso você queira, existem mais parâmetros na API para customizar isso.

Conclusão

Bom pessoal, essa é uma solução do ‘mundo real‘ no desenvolvimento de aplicações WEB, porque? Com esse código, você investe um tempo X para fazê-lo, depois você ganha muito tempo somente reusando ele, lembrem-se dos princípios de agilidade e reusabilidade de código.

Este é um exemplo didático, está bem simples, quem quiser enriquecer esta solução com os outros recursos da API do Gravatar fique a vontade, no final será uma solução muito bacana e utilizável.

Download

Para quem quiser baixar o exemplo da tag, estou deixando disponível lá no Github o código junto da estrutura do projeto, segue o endereço abaixo:

https://github.com/carlosjrcabello/gravatar-tag-support

Referências


http://java.sun.com/j2ee/tutorial/1_3-fcs/doc/JSPTags6.html – contém exemplos bem claros de como utilizar.


http://stackoverflow.com/questions/224748/jsp-custom-tag-library-unable-to-find-setter-method-for-the-attribute – contém a solução para um problema que uma hora ou outra você irá passar, que é a ordem da declaração dos elementos no arquivo TLD.


http://java.sun.com/developer/technicalArticles/xml/WebAppDev3/ – Mais exemplos de como trabalhar com o arquivo TLD.

http://en.gravatar.com/site/implement/ – informações sobre a API e implementações.

Por enquanto é só pessoal, um abraço e até a próxima.

Dúvidas e comentário usem o espaço de comentários abaixo.

Fonte: Carlos4web

Tags | , , , , , , , , ,