Grails Date unmarshalling
Solution 1:
The cleanest way is probably to register a custom DataBinder for possible date formats.
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
}
}
}
}
You'd also need to implement a 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)));
}
}
and create a Spring-bean definition in your grails-app/conf/spring/resources.groovy:
beans = {
"customEditorRegistrar"(CustomEditorRegistrar)
}
and finally define the date formats in your grails-app/conf/Config.groovy:
grails.date.formats = ["yyyy-MM-dd HH:mm:ss.SSS ZZZZ", "dd.MM.yyyy HH:mm:ss"]
Solution 2:
Be aware that the new version of Grails 2.3+ supports this type of feature out of the box. See Date Formats for Data Binding
With that said, if you are forced to use a version of Grails prior to 2.3, the CustomEditorRegistrar
can be updated using the following code to eliminate the deprecation warning, and also uses the @Component
annotation, which allows you to remove / skip the step of adding the bean directly in resources.groovy
.
Also not that I changed the grails configuration property name to grails.databinding.dateFormats, which matches the property now supported in Grails 2.3+. Finally, my version is a .groovy, not .java file.
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))
}
}