sexta-feira, 24 de agosto de 2012

Download de Arquivos com Grails

Fala galera!

Neste post, vou mostrar com disponibilizar um arquivo para download com Grails, e como disponibilizar a visualização de uma imagem qualquer fora dos recursos do projeto.


    //Model
    class Arquivo{
       String file
    }
  
    //Controller
    def show(){
        def item = Arquivo.get(params.id)    
        def arquivo = grailsAttributes.getApplicationContext().getResource("/images/image-not-found.png").getFile().toString()

        if(item != null){
            def base = '/var/www/htdocs/imagens'
            def file = new File(base, item.file)

            if(file.exists()){
               arquivo = file.getAbsolutePath()
            }                
        }
        response.outputStream << readImage(arquivo)                     
    }

    def download(){
        def item = Arquivo.get(params.id)            

        if(item != null){
            def base = '/var/www/htdocs/arquivos'
            def file = new File(base, item.file)

            if(file.exists()){
                file.getAbsolutePath()                
                response.setContentType("application/octet-stream")
                response.setHeader("Content-disposition", "attachment;filename=${file.getName()}")
                response.outputStream << file.newInputStream()
                return
            }                
        }    
        
        render view: 'link-quebrado'
    }

     public byte[] readImage(String file) {
        byte[] buffer = new byte[1024];

        InputStream is = new FileInputStream(file);
        ByteArrayOutputStream out = new ByteArrayOutputStream();

        while (is.read(buffer) != -1) {
            out.write(buffer);
        }
        return out.toByteArray();
    }

Agora vamos a explicação.

Primeiramente criamos a classe Arquivo, que será reponsável por identificar o arquivo solicitado. Nessa caso, recebemos o arquivo via upload, e disponibilizamos ele para download ou como visualização de imagem.

Disponibilizando uma imagem:

A Closure show é usada para visualização de uma imagem. Nela recuperamos a imagem solicitada, através do id do arquivo. Armazenamos a imagem em um array de bytes, e jogamos ela pra dentro do outputStream. O link será algo mais ou menos assim. Caso a imagem não exista, é disponibilizada uma imagem padrão.


   

Simples?! Isso é Grails!

Disponibilizando um arquivo para download:

A Closure download é usada para fazer o download do arquivo solicitado. Nela recuperamos o arquivo solicitado, lemos seu conteúdo e adicionamos no outputStream. Caso o arquivo não exista, é renderizado uma pagina padrão de link quebrado.

Simples?! Isso é Grails!

E com isso, concluímos os ensinamentos =D

Até a próxima!

Upload de arquivos em Grails - Parte 2

Fala galera!

Nesta poste irei continuar com o assunto upload de arquivos com Grails. No primeiro post vimos como salvar o arquivo no banco de dados, e agora vamos ver como salvar esse arquivo em disco. Como tudo no Grails é simples, isso não poderia ser diferente. Então vamos ao que interessa.  

Importânte: Lebrando que temos que ter o atributo do multipart no g:form para funcionar.
def create(){
  //Todo código de criação aqui

  upload('/var/www/htdocs/imagens')

}

//Closure que salva o arquivo em disco
def upload = { path ->

     def fileName = params.arquivo.originalFilename
     def file = request.getFile("arquivo") //arquivo é o id do componente type=file

     if(!file.empty){
      file.transferTo(new File(path, "${fileName}"))
     }
}

Simples assim! No próximo post, vamos ver como recuperar esse arquivo, disponibilizando ele para download ou em img (no caso de imagens).

Até a próxima!

Upload de arquivos em Grails

Fala galera..

Aqui vai uma útilidade, simples e fácil. Nos últimos dias venho me aventurando com Grails, e já estou bem inclinado a mudar minha linguagem web número 1 de Java para Groovy, usando o Grails! São  inúmeras as facilidades nesse framework, sem contar a linguagem dinâmica e produtiva. Neste poste vou mostrar uma delas. Já perdi algumas horas fazendo essa mesma tarefa em Java, pois precisamos de bibliotecas de terceiros, configuração no web.xml e tudo mais. Com grails não, em poucos mínutos, sem ter ne noção de como funcionava, consegui configurar. Vamos lá!

Primeiramente, na classe de modelo você precisa ter um campo do tipo array de bytes (supondo que você vai gravar a imagem no banco)

class User{
   String name
   byte[] avatar
   
   static constraints = {
       avatar(size:0..131072, nulable: true)
   }
}


Se gerarmos as views automáticamente, o upload já vai estar pronto para o uso, assim:

grails create-controler User
grails generate-all User

Caso o campo seja configurado manualmente em uma tela existente, temos que adicionar na tag g:form o seguinte valor:

enctype="multipart/form-data"


Ex.:


Esse parâmetro é quem faz toda a mágica. Sem ele, nosso upload não vai funcionar.

Aqui o campo para download, que fica na tela:


   



Isso já será o suficiente para fazer o upload de uma imagem. Um detalhe importante, é que na edição do registro, quando não informado nenhum avatar, o valor existente é substituido por nada. Então, o interessantes é testarmos isso no método edit.


def oldAvatar = userInstance.avatar

userInstance.properties = params

if(!userInstance.avatar){
    userInstance.avatar = oldAvatar;
}

E pronto. O avatar já está sendo carregado e salvo no banco de dados. No próximo post, vou mostrar como salvar esse arquivo em disco, caso não queira salvar no banco de dados.


Até a próxima!