Olá desenvolvedores! Hoje iremos implementar o download de imagens, uma vez que já implementamos duas maneiras de fazer upload de imagens. E também já a adicionamos a tabela e estamos exibindo a imagem na tela, junto com os dados do usuário.

Mas se quisermos visualizar a imagem em tamanho real, tem todo aquele processo, clica com o botão direito sobre a imagem, escolhe a opção “Copiar o endereço da imagem” e cola o respectivo endereço no navegador. Não faz sentido, exceto para nós programadores, no sentido de poder analisar a informação da URL. Mas enfim, para encurtar a conversa, o tutorial de hoje implementará o download das imagens.

CORREÇÃO

Antes iremos proceder com uma correção, a imagem está sendo exibida na coluna do nome. O ajuste será bem simples, na tela cadastroUsuario.jsp nos campos da tabela onde exibimos o cabeçalho das colunas adicione a tag <th> para a imagem logo abaixo a tag onde exibimos o ID. E aproveitando, exclua o login bem como sua coluna, e atente-se porque a exclusão ocorrerá em dois lugares.

IMPLEMENTANDO O DOWNLOAD NO JSP

Voltando ao tema do tutorial, o que queremos é fazer o download da imagem após clicar sobre ela. E para isso o que precisamos é de um link para fazermos a requisição do lado da servlet, ou seja, do lado do servidor.

Agora a imagem estará dentro do link, isto no HTML iremos envolver a imagem com a tag de link. O que precisamos é chamar uma classe Java do lado do servidor, servlet, com o “salvarUsuario” passando a ação de download, bem como o código do usuário.

<td>
<a href=”salvarUsuario?acao=download&user=${}”><img src=”<c:out values ${user.tempFotoUser}/>”
alt=”” title=”” ></a> </td>

E como a imagem é do usuário, passaremos também o código do usuário, para que seja pesquisado no banco de dados a imagem daquele usuário, para então a rotina de download entrar em ação.

IMPLEMENTANDO O DOWNLOAD NO DAO

O código do usuário é passado para que possamos consultar no banco de dados a informação desejada, desse modo, será necessário adicionar ao método listar() na classe de conexão DaoUsuario.Java os atributos referentes a imagem.

IMPLEMENTANDO O DOWNLOAD NA SERVLET

Assim na servlet usuario.java, onde já temos implementada a ação e temos também o código do usuário, no método doGet só teremos que passar para a servlet a ação de download, tal como no Delete e Editar e o id.

Aproveitaremos o código onde temos implementado em uma estrutura de decisão as rotinas de deletar, editar e listar. Assim, se a ação escolhida pelo usuário na tela for para fazer o download, o fluxo do código será redirecionado para esta condição.

Dentro da condição a primeira providência é consultar o usuário no banco de dados por meio do id. E se ao consultar o usuário for diferente de nulo, neste caso iremos processar a rotina de download.

E para que o download seja feito de forma correta teremos que passar para a resposta alguns parâmetros, estes parâmetros voltarão para o navegador, onde uma nova tela será aberta e então a imagem será carregada. E para realizar esta ação teremos que “setar” os parâmetros “content-Disposition” e “attachment” para o cabeçalho. o parâmetro attachment carrega ainda o nome do arquivo e a extensão.

Atente-se que não podemos antecipadamente saber que tipo de imagem o usuário irá carregar, dessa forma essa informação deverá ser recuperada de forma dinâmica. Sabemos que o contentType retorna imagem/img, assim nos interessa o que está depois da barra. E para pegar somente esta informação iremos transformá-la em um vetor, onde a primeira parte será zero e a que nos interessa será 1. Utilizaremos o método split que quebra uma String em várias substrings a partir de uma expressão regular (regex), ou como é falado popularmente, “a partir de um caractere especificado”.

IMPLEMENTANDO O PROCESSAMENTO DA IMAGEM

A imagem deverá estar em um array de bytes, e então criaremos um novo objeto que você já conhece, o base64 do pacote org.apache.tomcat.util.codec.binary.Base64, a partir dele invocaremos a decodificação da imagem.

byte[] imageFotoBytes = new Base64().decodeBase64(usuario.getFotoBase64());

E agora colocaremos os bytes em um objeto de entrada para processar, este objeto receberá o imageFotosBytes.

InputSream is = new ByteArrayInputStream(imageFotoBytes));

Recapitulando, setamos o cabeçalho colocando a resposta para identificar o tipo de arquivo. E então convertemos a base64 para bytes, e depois para um fluxo de entrada. Agora iremos escrever a resposta para o navegador.

Começamos declarando uma variável de controle para o fluxo, e logo, ela é do tipo inteiro. E também instanciando um array de saída com tamanho padrão de 1024. E a saída com um outputStream que virá do response, ou seja, do objeto de resposta, colocando este objeto dentro de uma variável fica mais fácil, manipulá-lo.

Enquanto a variável de controle read após receber os valores da leitura dos dados, retornar algo diferente de -1 é porque tem conteúdo para serem lidos. Neste caso, escreveremos no objeto de saída o tamanho dos bytes que estão sendo lidos.

Após a escrita, finalizamos a leitura com um flush() e fechamos o fluxo com um close(), ambos sendo invocados pelo OutputStream, e tudo acontecendo dentro do laço de decisão else if. E então é só testar.

os.flush();
os.close();

EM POUCAS PLAVARAS

E nossa aplicação fica cada vez mais completa. O tutorial de hoje trouxe o passo a passo da implementação do download. E novamente, um código bem estruturado nos permite o reaproveitamento de classes e até de rotinas, Eu fico por aqui e nós nos vemos no próximo tutorial onde implementaremos as rotinas de upload e download de arquivos.