2009-06-08 11 views
13

Wenn ich den folgenden JSON von einem RESTful-Client bekomme, wie entziffere ich die java.util.Date elegant? (Ist es möglich, ohne Angabe (aka. Hartcodierung) das Format, das ist, was meine ich mit elegant ...)Grails Datum unmarshalling

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

Antwort

18

Der sauberste Weg ist wahrscheinlich einen benutzerdefinierter Databinder für mögliche Datumsformate zu registrieren.

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 
       } 
      } 
    } 
} 

Sie würden auch eine 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))); 
    } 
}   

und erstellen Sie eine Frühlings-Bean-Definition in Ihre Grails-app/conf/Frühjahr/resources.groovy implementieren müssen:

beans = { 
    "customEditorRegistrar"(CustomEditorRegistrar) 
} 

und schließlich definieren Sie die Datumsformate in Ihrem Grails-App/conf/Config.groovy:

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

Sie fragen sich, ob es einen Grund gibt, warum Sie sich dafür entscheiden, dies in Java (wie oben) und nicht in Groovy zu implementieren? Der Code wäre bei Groovy etwas kürzer. –

+0

Ich habe einen ähnlichen Code in Java implementiert, als Groovy früher viel langsamer war als jetzt. Groovy machte einen großen Sprung in dieser Angelegenheit. Ich benutze nur den alten Java-Code aus Faulheit ;-) –

+0

Schönes Stück Code, klassisch von dem, was Sie tun würden. Am saubersten wäre es jedoch, das Gebietsschema zum Abrufen des Formats zu verwenden, anstatt es durch Parsing-Versuche zu iterieren. – Gepsens

5

Beachten Sie, dass die neue Version von Grails 2.3+ diese Art von Funktion standardmäßig unterstützt. Siehe Date Formats for Data Binding

, der mit dem, wenn Sie gezwungen sind, vor dem 2.3 eine Version von Grails zu verwenden, die CustomEditorRegistrar aktualisiert werden kann mit dem folgenden Code der deprecation Warnung zu beseitigen, und verwendet auch die @Component Anmerkung, die erlaubt Sie entfernen/überspringen den Schritt des Hinzufügens der Bean direkt in resources.groovy. Auch nicht, dass ich den Namen der Grails-Konfigurationseigenschaft in grails.databinding.dateFormats geändert habe, was der Eigenschaft entspricht, die jetzt in Grails 2.3+ unterstützt wird. Schließlich ist meine Version eine .groovy, nicht .java Datei.

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

Danke Mann. Du hast meinen Tag gerettet. @BindingFormat ist die richtige Wahl. –