Más allá de lo que ves: noviembre 2012

jueves, 22 de noviembre de 2012

Cambiar User Agent en Chrome

Si deseas simular el acceso a un sitio web como si accedieras desde una determinada versión de Internet Explorer o desde Opera Mobile con Android o con iPhone por ejemplo, en Chrome tenemos la posibilidad de modificar el User Agent que el navegador envía en la petición al servidor.

Es sencillo, tan solo debes hacer lo siguiente:

  • En Herramientas selecciones Herramientas para desarrolladores.
  • En la esquina inferior derecha haces clic en Settings
  • Seleccionas la pestaña Overrides
  • Activas la opción User Agent
  • Por último no tienes más que seleccionar el User Agent que deseas simular.

En el caso de que no venga el User Agent específico que deseas simular no tienes más que seleccionar la opción Other... y en el campo de texto de la derecha indicar el user agent específico, por ejemplo:

Para simular acceso con Opera Mobile 12 desde la siguiente dirección copias el User Agent específico:

http://www.useragentstring.com/Opera%20Mobile12.02_id_19595.php

User Agent específico:

Opera/12.02 (Android 4.1; Linux; Opera Mobi/ADR-1111101157; U; en-US) Presto/2.9.201 Version/12.02

Por último lo pegas en el campo de texto de chrome como se puede ver en la captura:



Sencillo, ¿no?

sábado, 17 de noviembre de 2012

Estreno look & feel en montesinos.org.es

Espero que os guste, he intentado que tenga un diseño sencillo y actualizado.

La verda que la imagen sobra, pero para los que lo ven desde el tablet, móvil...

viernes, 16 de noviembre de 2012

Solucionado problema al no lanzar evento onDeviceReady Cordova 2.2.0 (PhoneGap)

Probando las posibilidades que ofrece Cordova (PhoneGap anterior) me he encontrado con que siguiendo los ejemplos y usando el Bind de eventos para onDeviceReady el código que he puesto en el método destinado al efecto no se ejecuta cuando lo pruebo directamente en el navegador sin lanzar la ejecución en ningún terminal.

Entorno: Mac, Chrome, Cordova 2.2, Eclipse Juno

El caso es que basta con añadir al tab body una llamada a la función que deseamos de inicio en el evento onLoad.

Importante no olvidar quitarlo al generar la apk si no se nos ejecutará dos veces ( me ha pasado ;( )

Os dejo un sencillo ejemplo:
    
var app = {
         // Application Constructor
         initialize: function() {          
             this.bindEvents();
         },
         
         // Bind Event Listeners
         // Bind any events that are required on startup.
         bindEvents: function() {
             document.addEventListener('deviceready', 
                   app.onDeviceReady, false);           
         },
         
         // deviceready Event Handler
         onDeviceReady: function() {
             console.log("Entrando");
         },
     };
Como decía basta añadir en el body de la página lo siguiente: onload="app.onDeviceReady()".

miércoles, 14 de noviembre de 2012

Serializar objeto Java en String ( Base 64 )

En referencia al artículo anterior: http://www.montesinos.org.es/2012/11/almacenar-objetos-java-en-base-64-en.html la solución para almacenar directamente el objeto serializado pasaría por añadir una línea con el código siguiente:

private static final long serialVersionUID = -1361890418743713893L;

Donde -1361890418743713893L será la versión de la clase compilada y hará que nuestro código no de excepción, aquellos atributos nuevos que no posea la clase serializada se inicializarán a los valores por defecto.

El código de ejemplo es igual de simple, utiliza Commons Codec versión 1.7 y Commons Lang 2.4
import java.io.IOException;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang.SerializationUtils;

public class Main {

 public static void main(String args[]) throws IOException {
  // Instanciar el objeto que vamos a usar.
  ConsultaForm m = new ConsultaForm(1, "javi", "montesinos");
  m.getCursos().add(1);
  m.getCursos().add(222);

  // Pasar Java a un JSON como array de Bytes para codificar en base 64
  byte[] u = SerializationUtils.serialize(m);
  // Codificar json en bytes a una cadena base64
  String s = Base64.encodeBase64String(u);
  // Guardar el objeto en un campo de la base de datos.
  System.out
    .println("Guadar formulario de consulta en la base de datos : "
      + s);

  // Recuperar objeto en base 64 de la base de datos y decodificar a un
  // array de bytes
  String savedSearchValue = "rO0ABXNyAAxDb25zdWx0YUZvcm0AAAAAAAAAAQIABEkAAmlkTAAJYXBlbGx" +
    "pZG9zdAASTGphdmEvbGFuZy9TdHJpbmc7TAAGY3Vyc29zdAAQTGphdmEvdXRpbC9MaXN0O0wABm5vbW" +
    "JyZXEAfgABeHAAAAABdAAKbW9udGVzaW5vc3NyABNqYXZhLnV0aWwuQXJyYXlMaXN0eIHSHZnHYZ0DA" +
    "AFJAARzaXpleHAAAAACdwQAAAAKc3IAEWphdmEubGFuZy5JbnRlZ2VyEuKgpPeBhzgCAAFJAAV2YWx1" +
    "ZXhyABBqYXZhLmxhbmcuTnVtYmVyhqyVHQuU4IsCAAB4cAAAAAFzcQB+AAcAAADeeHQABGphdmk=";
  byte[] dataDos = Base64.decodeBase64(savedSearchValue);

  // Mapear el array de bytes a un objeto SavedSearch
  Object o = SerializationUtils.deserialize(dataDos);
  if (o instanceof ConsultaForm) {
   System.out.println(o.toString());
  } else {
   System.out.println("Noooooooooooooooop !");
  }
 }

}

martes, 13 de noviembre de 2012

Almacenar objetos java en Base 64 en una base de datos


Con el objetivo de almacenar objetos Java por ejemplo que representan en una herramienta de reporting el formulario de filtro para que los usuarios puedan obtener sus propios listados, así como guardarlos y poder reutilizarlos he echado un vistazo al código de SugarCRM para ver como lo hacen ellos.

Por lo que he podido comprobar, guardan en la tabla de consultas guardadas (saved_search para los curiosos) el propietario de la consulta, el módulo sobre el cual esta disponible, clientes, oportunidades... y un String como el que podeis ver al final del correo. Algo parecido ya había visto en Asp.Net si no recuerdo mal.

El caso es que ese chorizo no es otra cosa que un array en php con todos los parametros necesarios para montar el formulario de la consulta, serializado y luego codificado en Base 64.

Para utilizarlo a la hora de mostrar el formulario de consulta descodifican en Base 64 la cadena y posteriormente la deserializan.

Siguiendo un patrón como este para Java he construido un pequeño código que hace lo mismo pero con un objeto Java que puede representar nuestro ConsultaEntidadForm del dominio, pero tenemos un pequeño problema. Si almacenamos el String y posteriormente sobre ConsultaEntidadForma hago un cambio compilo y actualizo, nos saltará una excepción cuando intentemos recuperar el objeto de la base de datos, el motivo no es otro que las versiones de la clase Java almacenada en la base de datos mediante el String en Base 64 y la versión de la clase Java cargada en la aplicaicón serán diferentes.

Así pues en lugar de serializar y codificar en Base 64 lo que he hecho es pasar Java a JSON y codificar a Base 64 con esto cuando debemos recuperar el proceso es descodificar Base 64 y pasar a JSON y mapear el JSON a nuestro objeto Java de modo que ya no habrá Excepción.

Dejo un pequeño ejemplo de lo sencillo que es el proceso en ambos sentidos, las únicas librerías necesarias son Commons Codec y Jackson Mapper:

import java.io.IOException;

import org.apache.commons.codec.binary.Base64;
import org.codehaus.jackson.map.ObjectMapper;

public class SaveJsonSavedSearch {

    public static void main(String args[]) throws IOException {    
        // Instanciar el objeto que vamos a usar.
        SavedSearch m = new SavedSearch(1, "javi", "montesinos");                    
        m.getCursos().add(1);
        m.getCursos().add(222);
     
        // Instanciar el helper para convertir Java a JSON y JSON a Java
        ObjectMapper mapper = new ObjectMapper();            
     
        // Pasar Java a un JSON como array de Bytes para codificar en base 64
        byte[] jsonBytes = mapper.writeValueAsBytes(m);
        // Codificar json en bytes a una cadena base64
        String s = Base64.encodeBase64String(jsonBytes);
        // Guardar el objeto en un campo de la base de datos.
        System.out.println("Guadar formulario de consulta en la base de datos : " + s);  

        // Recuperar objeto en base 64 de la base de datos y decodificar a un array de bytes
        String savedSearchValue = "eyJpZCI6MSwiY3Vyc29zIjpbMSwyMjJdLCJhcGVsbGlkbyI6ImphdmkiLCJub21icmUiOiJtb250ZXNpbm9zIn0=";
        byte[] dataDos = Base64.decodeBase64(savedSearchValue);
     
        // Mapear el array de bytes a un objeto SavedSearch
        SavedSearch o = mapper.readValue(dataDos, 0, dataDos.length, SavedSearch.class);
        if(o instanceof SavedSearch){
            System.out.println(o.toString());
        } else {
            System.out.println("Noooooooooooooooop !");
        }                      
    }
}

Veré la forma de poder guardar directamente el objeto Java serializado, si la hay.

String en Base 64 que representa el objeto que deseamos guardar:

YToyNzp7czoxMzoic2VhcmNoRm9ybVRhYiI7czoxNToiYWR2YW5jZWRfc2VhcmNoIjtzOjU6InF1ZXJ5IjtzOjQ6InRydWUiO3M6MjI6ImN1c3RvbUVuaGFuY2V
kUXVlcnlTZXQiO3M6MDoiIjtzOjI3OiJjYW1wYW5hX2FjdGl2YV8xX2NfYWR2YW5jZWQiO2E6MTp7aTowO3M6MjoiVEQiO31zOjI1OiJjYW1wYW5hX3Npbl92c
19jX2FkdmFuY2VkIjtzOjA6IiI7czoyOToiYmxhbnF1ZW9fY2FwaXRhbGVzX2NfYWR2YW5jZWQiO3M6MDoiIjtzOjMzOiJjYW1wYW5hX3Npbl92aWdpbGFuY2lh
X2NfYWR2YW5jZWQiO3M6MDoiIjtzOjI3OiJjYW1wYW5hX2RlX2JhamFzX2NfYWR2YW5jZWQiO3M6MDoiIjtzOjI5OiJjYW1wYW5hX3ByZXZlbnB5bWVfY19hZ
HZhbmNlZCI7czowOiIiO3M6MjA6ImxpbmVhXzkwMF9jX2FkdmFuY2VkIjtzOjA6IiI7czoyNjoidmlhX3dlYl9wcmV2aW5nX2NfYWR2YW5jZWQiO3M6MDoiIjtzOj
I3OiJ2aWFfd2ViX3ByZXZlbmlyX2NfYWR2YW5jZWQiO3M6MDoiIjtzOjQ6IkVTT3AiO2E6Mzp7aTowO3M6MjoiT1IiO2k6MTtzOjI6Ik9SIjtpOjI7czozOiJBTkQiO3
1zOjg6IkVTT3BQb3N0IjthOjM6e2k6MDthOjE6e2k6MDtzOjA6IiI7fWk6MTthOjE6e2k6MDtzOjA6IiI7fWk6MjthOjE6e2k6MDtzOjA6IiI7fX1zOjExOiJFU0FkZE1v
ZHVsZSI7YTozOntpOjA7czo4OiJBY2NvdW50cyI7aToxO3M6ODoiQWNjb3VudHMiO2k6MjtzOjg6IkFjY291bnRzIjt9czoxMDoiRVNBZGRGaWVsZCI7YTozOntp
OjA7czoxNjoiYWN0aXZpZGFkX2MtdGV4dCI7aToxO3M6MTY6InNpY19jb2RlLXZhcmNoYXIiO2k6MjtzOjE2OiJjZW50cm9zX3ZzX2MtaW50Ijt9czoxMzoiRVNB
ZGRPcGVyYXRvciI7YTozOntpOjA7czo0OiJMSUtFIjtpOjE7czo2OiJFTkRJTkciO2k6MjtzOjI6IkVRIjt9czoxMToiRVNBZGRTZWFyY2giO2E6Mzp7aTowO3M6Mjo
iNDMiO2k6MTtzOjI6IjEyIjtpOjI7czoxOiIyIjt9czo3OiJFU09wUHJlIjthOjM6e2k6MDtzOjA6IiI7aToxO3M6MDoiIjtpOjI7czowOiIiO31zOjk6InNob3dTU0RJViI7czo
yOiJubyI7czoxMzoic2VhcmNoX21vZHVsZSI7czo4OiJBY2NvdW50cyI7czoxOToic2F2ZWRfc2VhcmNoX2FjdGlvbiI7czo2OiJ1cGRhdGUiO3M6MTQ6ImRpc3Bs
YXlDb2x1bW5zIjtzOjEyMzoiTkFNRXxQUk9WSU5DSUFfQ3xWQUxPUl9DTElFTlRFX0N8UEhPTkVfT0ZGSUNFfENBTVBBTkFfQUNUSVZBXzFfQ3xDQU1QQU5BX
0FDVElWQV8yX0N8RVNUQURPX0RFTF9DTElFTlRFX0N8QVNTSUdORURfVVNFUl9OQU1FIjtzOjg6ImhpZGVUYWJzIjtzOjQ5MzoiQ0FNUEFOQV9ERV9CQUpBU
19DfEVTVEFET19XRUJfUFJFVkVOSVJfQ3xFU1RBRE9fQ0FNUEFOQV9QUkVWRU5QWU1FX0N8Q0lGX05JRl9DfENBTVBBTkFfUFJFVkVOUFlNRV9DfENBTVBBT
kFfU0lOX1ZTX0N8VklBX1dFQl9QUkVWRU5JUl9DfFZJQV9XRUJfUFJFVklOR19DfExJTkVBXzkwMF9DfEVTVEFET19XRUJfUFJFVklOR19DfEJMQU5RVUVPX0NBU
ElUQUxFU19DfEVTVEFET19MSU5FQV85MDBfQ3xFU1RBRE9fQ0FNUEFOQV9UT1RBTERBVF9DfEVTVEFET19DQU1QQU5BX1ZTX0N8RVNUQURPX0NBTVBBT
kFfQkxBTlFVRU9fQ0FQX0N8Qk9OT19QRU5ESUVOVEVfQ3xGRUNIQV9DT05UUkFUT19WU19DfEVTVEFET19DQU1QQU5BX0JBSkFTX0N8RkVDSEFfQ09OVFJ
BVE9fUFRfQ3xQSE9ORV9BTFRFUk5BVEV8Q0FNUEFOQV9TSU5fVklHSUxBTkNJQV9DfFNJQ19DT0RFfEZJQ0hFUk9TX0xPUERfQ3xNRVNfQkFKQV9QVF9DfE1
FU19CQUpBX1ZTX0N8TU9USVZPX0JBSkFfUFRfQyI7czo3OiJvcmRlckJ5IjtzOjQ6Ik5BTUUiO3M6OToic29ydE9yZGVyIjtzOjM6IkFTQyI7czo4OiJhZHZhbmNlZ
CI7YjoxO30="

Tutorial ZK - Responsive Design (javaHispano)

La gente de javaHispano esta desarrollando una serie de 4 artículos de los cuales tienen ya dos publicados donde recogen como utilizar una de las nuevas características de ZK 6.5, Responsive Design. El objetivo de esta característica es contemplar toda la variedad de dispositivos y pantallas disponibles en el mercado.

Los enlaces de las entregas publicadas son los siguientes:

http://www.javahispano.org/portada/2012/10/27/zk-responsive-design-enfoquefilosofia.html
http://www.javahispano.org/portada/2012/11/9/zk-65-responsive-design.html

Por otra parte también han publicado una serie de 5 artículos en español para poder iniciarse con ZK de una forma sencilla.

http://www.javahispano.org/portada/2012/10/1/framework-zk-tu-primer-proyecto-web-con-zk-1-5.html


sábado, 10 de noviembre de 2012

El índice del miedo

He acabado de leer el libro "El índice del miedo" de Robert Harris. Me habló de el un compañero del trabajo y me atrajo el argumento. La verdad es que me ha gustado, ha habido algun momento en el que se ha perdido un poco, pero en líneas generales me ha gustado.

Alex, el protagonista del libro, un matematico estadounidense que ha trabajado en el CERN monta una fondo de inversiones con cobertura, cuyas operacions son realizadas por un algoritmo que maximiza la rentabilidad y reduce los riesgos. Un día comienza realizar operaciones fuera de la logica que debe seguir su funcionamiento.

Lo peor para mi ha sido el argot de algunos conceptos de bolsa que se me escapaban y tenia que buscarlos para que me quedará clara la idea.

Buena elección, se lee rápido ya que te engancha y es pequeñito, unas 300 páginas.

http://www.lecturalia.com/libro/75227/el-indice-del-miedo

http://www.amazon.es/%C3%ADndice-miedo-Intriga-grijalbo-ebook/dp/B008R8A71O