sexta-feira, 28 de setembro de 2012

Gerenciador de Senhas

Salve galera,

Aqui vai uma dica de app útil para Android. É uma app bem simples, que criei para suprir uma necessidade própria.. e achei interessantes compartilhar ela no google play.

  Gerenciador de Senhas

"Dificuldades em controlar e lembrar-se de todos os dados de acesso a sites, conta bancaria, e-mails e outros? Esse aplicativo resolve seu problema lembrando você de todas as suas senhas no momento em que você precisa. Mantenha suas senhas seguras e sempre a mão com esse aplicativo. Requer autenticação de acesso para manipular e visualizar as senhas."

A aplicação requer autenticação, para ter a certeza de que é você mesmo que está visualizando as senhas. O campo login não é obrigatório, e depois de um tempo percebi que ele pode ser usado para salvar as letras que compõem a senha da conta bancária.

Como disse, ela é bem simples e útil, e o melhor de tudo..  é gratuíta! Vale a pena testar!!

Segue o link para o download Gerenciador de Senhas.



Até a próxima!


quarta-feira, 26 de setembro de 2012

Glassfish - Secure Admin must be enabled to access the DAS remotely.

Salve galera,

Após a instalação do Glassfish, quando você tentar acessar o painel administrativo remotamente, você vai se deparar com a seguinte mensagem:

Secure Admin must be enabled to access the DAS remotely. 

Como liberar o acesso? 

1º Passo - Entre na pasta bin do glassfish e pare o servidor caso ele esteja rodando. Execute o seguinte comando:

$ ./asadmin stop-domain

2º Passo - Execute o seguinte comando e defina uma senha 

$ ./asadmin change-master-password

3º Passo - Inicie o servidor com o seguinte comando

$ ./asadmin start-domain

4º Passo - Defina uma senha administrativa, para acesso remoto

$ ./asadmin change-admin-password

5º Passo - Faça a liberação para acesso remoto

$ ./asadmin enable-secure-admin 


E agora o acesso remoto está liberado! espero que ajude =D

até a próxima!

sábado, 8 de setembro de 2012

Redimensionar Imagem em Java

Salve galera,

Quem aqui nunca precisou pegar uma imagem de 2000x1800 e colocar em um espaço de 500x500? É exatamente esse problema que esse post vem resolver. Na verdade, precisamos fazer um calculo ninja jedi para conseguir escalar a imagem.
Esse calculo consiste em:
  • Descobrir o que é menor na imagem, se é a altura ou a largura.
  • Caso existir um lado menor, descobir seu percentual em relação ao lado maior.
  • Agora em cima do espaço disponível (500x500)temos que tirar o percentual calculado anteriormente do menor lado da imagem.


Se a imagem já tiver altura igual a largura, nada será feito.

Então aqui está ele, o calculo, pronto para uso.


class ImageResizerService {
 
    public byte[] read(String file) {
        byte[] buffer = new byte[1024];

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

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

    public byte[] read(String file, double requiredWidth, double requiredHeight) {


        BufferedImage imagem = ImageIO.read(new File(file));

        double originalWidth = imagem.getWidth();
        double originalHeight = imagem.getHeight();
        double newWidth = 0;
        double newHeight = 0;
        double diff = 0;

        if (requiredHeight == 0) {
            requiredHeight = requiredWidth;
        }

        if (requiredWidth == 0) {
            requiredWidth = requiredHeight;
        }

        if(originalWidth < requiredWidth && originalHeight < requiredHeight){
            return read(file)
        }

        if(requiredWidth == 0 && requiredHeight == 0){
            return read(file)
        }

        if (originalWidth > originalHeight) {
            diff = originalWidth - originalHeight;
            newWidth = requiredWidth;            
            diff = diff / originalWidth;
            newHeight = newWidth - (newWidth * diff);
        } else if (originalWidth < originalHeight) {
            diff = originalHeight - originalWidth;
            newHeight = requiredHeight;            
            diff = diff / originalHeight;
            newWidth = newHeight - (newHeight * diff);
        } else {

            if (requiredHeight > requiredWidth) {
                requiredHeight = requiredWidth;
            } else if (requiredHeight < requiredWidth) {
                requiredWidth = requiredHeight;
            }

            newHeight = requiredHeight;
            newWidth = requiredWidth;
        }



        int type = BufferedImage.TYPE_INT_RGB;
        boolean isPng = file.toUpperCase().endsWith("PNG")

        if (isPng) {
            type = BufferedImage.BITMASK;
        }


        BufferedImage new_img = new BufferedImage((int) newWidth, (int) newHeight, type);
        Graphics2D g = new_img.createGraphics();
        g.setComposite(AlphaComposite.Src);
        g.drawImage(imagem, 0, 0, (int) newWidth, (int) newHeight, null);
        ByteArrayOutputStream out = new ByteArrayOutputStream();

        if (isPng) {
            ImageIO.write(new_img, "PNG", out);
        }else{
            ImageIO.write(new_img, "JPG", out);
        }

        try {
            return out.toByteArray();
        } finally {
            out.close();
        }
    }

}


Se esse é o melhor ou mais fácil algoritimo não sei, desenvolvi ele apartir da minha necessidade, e até o momento não tive problemas com "deformação" de imagens. Ah, e notem que caso seja solicitada uma um tamanho maior do que o tamanho da imagem existente, ele não faz nada, pois o objetivo é não perder a qualidade da imagem. E caso o tamanho solicitado seja menor do que a imagem existente mas não obedeça suas proporções, ele manterá a proporção, não obedecendo as medidas silicitadas, sempre nivelando por um dos valores (altura ou largura). Nesse caso, pomos sempre passar ou só largura, ou só altura.

Até a próxima!

Apache mascarando porta do Glassfish

Salve galera,

Uma situação muito comum para quem desenvolve aplicações que executam em um container java, como Glassfish ou Tomcat, é a necessidade de "mascarar" a porta do container atrás de um servidor web tradicional. Vou tentar explicar melhor.
Normalmente, subimos nosso container em uma porta diferente da 80, que é a porta web padrão, como por exemplo na porta 8080. Então para o usuário acessar nossa aplicação, ele precisa conectar em http://www.minhaempresa.com.br:8080/MinhaAplicacaoJava. Isso pode gerar alguns problemas, como o usuário não fixar a url do sistema, ou se confundir na hora da digitação, além de se tornar menos profissional, ao meu ver.
O objetivo proposto no artigo, é poder acessar a aplicação no seguinte endereço:
http://www.minhaempresa.com.br/MinhaAplicacaoJava. Sendo que teremos um servidor web apache rodando na porta 80 e um servidor java Glassfish rodando na porta 8080.

Depois de pesquisar um pouco, percebi que a maneira mais simples e transparente para atingir o objetivo, era instalar um módulo no servidor apache para tal funcionalidade. O nome do módulo é mod_jk.

Vamos  a instalação

Ambiente ondo foi implementado:

  • Glassfish 3.1.2.2 (build 5).
  • CentOS Linux release 6.0 (Final)
  • Java 7 build 1.7.0_01-b08
  • Apache 2.2.15
  • Tomcat Connectors 1.2.37

A única dependência que tive que instalar no linux foram gcc-c++ e httpd-devel, pois deu problema na compilação do conector. Caso você tenha o mesmo problema, aqui mostro como instalar no Centos:
$ yum install gcc gcc-c++ autoconf automake
$ yum -y install httpd-devel
Ubuntu
$ sudo apt-get install libapache2-mod-jk


Para fazer o processo no ubuntu, você pode acessar: http://recklessdeveloper.blogspot.com.br/2011/06/apache-e-glassfish-301-com-modjk-no.html

O conector você pode baixar em: http://tomcat.apache.org/connectors-doc/. Como eu baixei o source, então tive que compilar. A complilação é bem simples. Você deve descompactar os fontes do mod_jk, entrar na pasta e executar os seguintes comandos:
cd native/
$ ./configure --with-apxs=/usr/sbin/apxs
$ make
$ make install


Após a compilação e instalação, você deve criar o arquivo de configuração. No meu caso, ele foi criado em:
$ /etc/httpd/conf/workers.properties


Esse arquivo deve ter o seguinte conteúdo:
worker.list=worker1
worker.worker1.type=ajp13
worker.worker1.host=localhost
worker.worker1.port=8009


Observação: Essa porta não precisa estar liberada externamente caso os dois servidors estejam rodando na mesma maquina.

Agora devemos configurar o httpd.conf:

LoadModule jk_module modules/mod_jk.so

JkWorkersFile conf/workers.properties
JkLogFile /var/log/mod_jk.log
JkLogLevel debug
JkLogStampFormat "[%a %b %d %H:%M:%S %Y]"
JkOptions +ForwardKeySize +ForwardURICompat -ForwardDirectories
JkRequestLogFormat "%w %V %T"
JKMount /MinhaAplicacaoJava/* worker1



Em JkWorkersFile configuramos o arquivo criado anteriormente. Em JKMount configuramos o contexto da nossa aplicação no Glassfish. Você pode adicionar varios pontos de montagem, um para cada aplicação.

Agora precisamos avisar o Glassfish que ele vai ouvir as requisições desse cara. Entre na pasta bin do Glassfish e execute os seguintes comandos:

$ ./asadmin create-http-listener --listenerport 8009 --listeneraddress 0.0.0.0 --defaultvs server jk-connector

$ ./asadmin set configs.config.server-config.network-config.network-listeners.network-listener.jk-connector.jk-enabled=true

$ .asadmin create-jvm-options  -Dcom.sun.enterprise.web.connector.enableJK.propertyFile=domain-dir=/etc/httpd/conf/workers.properties



E pronto. Agora reinicie o Apache e o Glassfish e pode testar. Caso não funcione, verifique o arquivo de logs gerado em /var/log/mod_jk.log.

Até a próxima! vlw

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!