GWT – JSON dates

JSON no tiene un tipo de dato Date, así que cuando transfieres fechas mediante JSON debes convenir un formato de fecha -por ejemplo, yyyy-MM-dd’T’hh:mm:ss.SZ- Un ejemplo de fecha en este formato sería “2013-03-08T16:23:35.000+0000”.

Para facilitar un poco las cosas, decidí utilizar un Overlay Type para la representación de mi objeto y acceder a sus propiedades mediante getter’s y setter’s. Estos métodos realizan la conversión de cadena a fecha, y viceversa, con la ayuda de la clase DateTimeFormat.

    public class Audiencia extends JavaScriptObject {</p><pre><code>    private final static DateTimeFormat dateTimeFormat = DateTimeFormat.getFormat("yyyy-MM-dd'T'hh:mm:ss.SZ");

    public final native int getId()/*-{
        return this.id;
    }-*/;

    public final Date getInicio(){
        return dateTimeFormat.parseStrict(getInicioNative());
    };

    private final native String getInicioNative()/*-{
        return this.inicio;
    }-*/;

    public final Date getFin(){
        return dateTimeFormat.parseStrict(getFinNative());
    };

    private final native String getFinNative()/*-{
        return this.fin;
    }-*/;

    protected Audiencia() {
    }

    public static void getAudiencias(String idSala,
            final AsyncCallback&lt;Audiencia[]&gt; callback) {
        try {
            String queryParams = "?sala="+URL.encodeQueryString(idSala);
            RequestBuilder rb = new RequestBuilder(RequestBuilder.GET,
                    Consts.REST_AUDIENCIAS + queryParams);
            rb.sendRequest(null, new RequestCallback() {

                @Override
                public void onResponseReceived(Request request,
                        Response response) {
                    if(response.getStatusCode() == 200){
                        JavaScriptObject jso = JSON.decode(response.getText());
                        DSResponse ds = new DSResponse(JSOHelper.getAttributeAsJavaScriptObject(jso, "response"));
                        if(ds.getStatus() == 0){
                            Record[] records = ds.getData();
                            Audiencia[] audiencias = new Audiencia[records.length];
                            for(int i=0;i&lt;records.length;i++){
                                audiencias[i] = (Audiencia) records[i].getJsObj();
                            }
                            callback.onSuccess(audiencias);
                        }else{
                            callback.onFailure(new Exception(ds.getAttributeAsString("data")));
                        }
                    }else{
                        callback.onFailure(new Exception(response.getStatusText()));
                    }
                }

                @Override
                public void onError(Request request, Throwable exception) {
                    callback.onFailure(exception);
                }
            });
        } catch (Exception e) {
            callback.onFailure(e);
        }
    }

}
</code></pre><p>

Esto es necesario porque el método JSON.decode) crea el objeto Javascript con propiedades (inicio y fin) de tipo String.

Anuncios

Java – Obtener el tipo de dato de las propiedades de un objeto

Para obtener el tipo de dato de las propiedades de un objeto podemos utilizar la reflexión.

Por ejemplo si tenemos las siguientes clases

public class Libro{
String isbn;
String titulo;
Autor autor;
}
public class Autor{
String id;
String nombre;
Date fechaNacimiento;
}

Un método para obtener el tipo de dato de una propiedad, incluso propiedades anidadas, sería el siguiente

private Class<?> getPropertyType(Class<?> clazz,String property){
 try{
 LinkedList<String> properties=new LinkedList<String>();
 properties.addAll(Arrays.asList(property.split("\\.")));
 Field field = null;
 while(!properties.isEmpty()){
 field = FieldUtils.getField(clazz,properties.removeFirst(),true);
 clazz=field.getType();
 }
 return field.getType();
 }catch(Exception e){
 throw new RuntimeException(e);
 }
}

Lo invocaríamos de la siguiente manera

Class<?> type=getPropertyType(Libro.class,"autor.fechaNacimiento");
System.out.println(type.toString()); //imprime java.util.Date

Notesé el uso de la clase FieldUtils de la librería Apache Commons Lang, cuyo método getField busca el campo recursivamente en la jerarquía de las clase y sus interfaces. Para agregar la librería a nuestro proyecto hay que agregar la siguiente dependencia


<dependency>
 <groupId>org.apache.commons</groupId>
 <artifactId>commons-lang3</artifactId>
 <version>3.1</version>
 </dependency>

Para listar todas las propiedades de un objeto recursivamente podemos utilizar como ejemplo el código de la clase FieldUtils.

Con la librería Jackson podemos obtener un esquema JSON de cualquier objeto. El detalle es que los tipos de datos que obtendríamos serían sólo los permitidos en JSON (string, number, boolean, object, array, null).

ObjectMapper mapper=new ObjectMapper();
System.out.println(mapper.generateJsonSchema(Libro.class));

Fuentes:
http://stackoverflow.com/questions/11125409/find-the-field-type-using-jackson-json
http://stackoverflow.com/questions/3567372/access-to-private-inherited-fields-via-reflection-in-java
http://wiki.fasterxml.com/JacksonJavaDocs
http://jackson.codehaus.org/1.8.8/javadoc/org/codehaus/jackson/map/ObjectMapper.html#generateJsonSchema(java.lang.Class)
http://wiki.fasterxml.com/JacksonTreeModel