2009-06-08 28 views
13

Si obtengo el siguiente json de un cliente RESTful, ¿cómo desatalo elegantemente el java.util.Date? (¿Es posible sin proporcionar (aka. Codificación dura) el formato, eso es lo que quiero decir con elegancia ...)Grails Sincronizar la fecha

{ 
    "class": "url", 
    "link": "http://www.empa.ch", 
    "rating": 5, 
    "lastcrawl" : "2009-06-04 16:53:26.706 CEST", 
    "checksum" : "837261836712xxxkfjhds", 
} 

Respuesta

18

La manera más limpia es probablemente registrar un DataBinder personalizado para posibles formatos de fecha.

import java.beans.PropertyEditorSupport; 
import java.text.ParseException; 
import java.text.SimpleDateFormat; 
import java.util.ArrayList; 
import java.util.Collections; 
import java.util.List; 

public class CustomDateBinder extends PropertyEditorSupport { 

    private final List<String> formats; 

    public CustomDateBinder(List formats) { 
     List<String> formatList = new ArrayList<String>(formats.size()); 
     for (Object format : formats) { 
      formatList.add(format.toString()); // Force String values (eg. for GStrings) 
     } 
     this.formats = Collections.unmodifiableList(formatList); 
    } 

    @Override 
    public void setAsText(String s) throws IllegalArgumentException { 
     if (s != null) 
      for (String format : formats) { 
       // Need to create the SimpleDateFormat every time, since it's not thead-safe 
       SimpleDateFormat df = new SimpleDateFormat(format); 
       try { 
        setValue(df.parse(s)); 
        return; 
       } catch (ParseException e) { 
        // Ignore 
       } 
      } 
    } 
} 

También había necesidad de implementar un PropertyEditorRegistrar

import org.springframework.beans.PropertyEditorRegistrar; 
import org.springframework.beans.PropertyEditorRegistry; 

import grails.util.GrailsConfig; 
import java.util.Date; 
import java.util.List; 

public class CustomEditorRegistrar implements PropertyEditorRegistrar { 
    public void registerCustomEditors(PropertyEditorRegistry reg) { 
     reg.registerCustomEditor(Date.class, new CustomDateBinder(GrailsConfig.get("grails.date.formats", List.class))); 
    } 
}   

y crear una definición de primavera-frijol en su griales-app/conf/primavera/resources.groovy:

beans = { 
    "customEditorRegistrar"(CustomEditorRegistrar) 
} 

y finalmente defina los formatos de fecha en su grial-app/conf/Config.groovy:

grails.date.formats = ["yyyy-MM-dd HH:mm:ss.SSS ZZZZ", "dd.MM.yyyy HH:mm:ss"] 
+0

¿Solo me pregunto si hay una razón por la que elegiría implementar esto en Java (como arriba) en lugar de Groovy? El código sería un poco más corto con Groovy. –

+0

Implementé una pieza similar de código en Java en tiempos anteriores cuando Groovy era mucho más lento de lo que es ahora. Groovy dio un gran salto adelante en este asunto. Solo estoy reutilizando el antiguo código Java de la pereza ;-) –

+0

Una buena pieza de código, un clásico de lo que harías. Aunque la forma más limpia sería utilizar la configuración regional para recuperar el formato en lugar de iterar a través de los intentos de análisis. – Gepsens

5

Tenga en cuenta que la nueva versión de Grails 2.3+ admite este tipo de característica de fábrica. Ver Date Formats for Data Binding

Dicho esto, si se ven obligados a utilizar una versión de Grails antes de la 2.3, el CustomEditorRegistrar se puede actualizar mediante el siguiente código para eliminar la advertencia desaprobación, y también utiliza la anotación @Component, lo que permite puede eliminar/omitir el paso de agregar el bean directamente en resources.groovy. Además, no es que haya cambiado el nombre de la propiedad de configuración de griales a grails.databinding.dateFormats, que coincide con la propiedad ahora admitida en Grails 2.3+. Finalmente, mi versión es un archivo .groovy, no .java.

import javax.annotation.Resource 
import org.codehaus.groovy.grails.commons.GrailsApplication 
import org.springframework.beans.PropertyEditorRegistrar 
import org.springframework.beans.PropertyEditorRegistry 
import org.springframework.stereotype.Component 

@Component 
public class CustomEditorRegistrar implements PropertyEditorRegistrar { 

    @Resource 
    GrailsApplication grailsApplication 

    public void registerCustomEditors(PropertyEditorRegistry reg){ 
     def dateFormats = grailsApplication.config.grails.databinding.dateFormats as List 
     reg.registerCustomEditor(Date.class, new CustomDateBinder(dateFormats)) 
    } 
} 
+0

Gracias hombre. Salvaste mi día. @BindingFormat es la elección correcta. –