Auto binding for multiple date formats | Spring

Sometimes we may need to send date in different formats when posting a form or post json objects. Since spring automatically binds the fields of that object (When you use @ModelAttribute/@RequestBody), some field may not automatically be bound.

Think about Date object. Sometimes we may need to bind a date format like Aug 25, 2017 or 11-06-2005 etc. Spring may not bind these dates automatically. In that case we will have to configure spring to bind these format of date strings automatically.

1. Write a Custom Date Format class

public class CustomDateFormat extends DateFormat {
    private static final List<? extends DateFormat> DATE_FORMATS = Arrays.asList(
            new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"),
            new SimpleDateFormat("yyyy-MM-dd"),
            new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
    );

    @Override
    public StringBuffer format(final Date date, final StringBuffer toAppendTo, final FieldPosition fieldPosition) {
        throw new UnsupportedOperationException("This custom date formatter can only be used to *parse* Dates.");
    }

    @Override
    public Date parse(final String source, final ParsePosition pos) {
        Date res;
        for (final DateFormat dateFormat : DATE_FORMATS) {
            if ((res = dateFormat.parse(source, pos)) != null) {
                return res;
            }
        }
        return null;
    }
}

Here we’ve specified 3 types of date format that will be automatically bound with Date object. We can add as more date formats as we want.

2. Register DateFormat

Now we need to register this CustomDateFormat in @ControllerAdvice bean class.

@ControllerAdvice
public class CustomDateEditorRegistrer implements PropertyEditorRegistrar {

    @InitBinder
    @Override
    public void registerCustomEditors(PropertyEditorRegistry registry) {
        registry.registerCustomEditor(Date.class, new CustomDateEditor(new CustomDateFormat(), true));
    }

}

When you add @ControllerAdvice annotation on a class, it’ll invoke before any @Controller class

That’s all, spring will bind string that has one of the above three formats with Date property.

Leave a Reply

Your email address will not be published. Required fields are marked *