How to register global databinding for LocalDate in spring mvc?

Viewed 2216

I'd like to use LocalDate as type in a Servlet created with spring-mvc. The users should be able to provide the date in multiple valid formats yyyyMMdd, yyyy-MM-dd, yyMMdd, yy-MM-dd.

Therefor I'm trying to register my own converter for that class and register it globally for the whole application. But it is never picked up

Problem: my custom editor is never called.

@Bean
public CustomEditorConfigurer init() {
    CustomEditorConfigurer c = new CustomEditorConfigurer();
    c.setPropertyEditorRegistrars(new PropertyEditorRegistrar[] {
            (registry) -> registry.registerCustomEditor(LocalDate.class, new LocalDatePropertyEditor())
    });
    return c;
}

public class LocalDatePropertyEditor extends PropertyEditorSupport {
    @Override
    public void setAsText(String text) {
        this.setValue(LocalDate.parse(text, DateTimeFormatter.ISO_DATE));
    }

    @Override
    public String getAsText() {
        return this.getValue().toString();
    }
}


@RestController
public void DateServlet {
    @RequestMapping("/test")
    public void test(@RequestParam LocalDate date) {

    }
}

When calling: localhost:8080/test?date=2017-07-05

Exception: Parse attempt failed for value [2017-07-05]

During debug I can see the LocalDatePropertyEditor class is never called. But why?

2 Answers

Well, Even I faced the problem and could not get PropertyEditor to work without initBinder():

Adding below code to each controller would work, I am using springboot v1.5:

@InitBinder
    public void initBinder(WebDataBinder binder) {
        binder.registerCustomEditor(LocalDate.class, 
            new LocalDateEditor());
    }

But bit more easier solution apart from using WebMvcConfigurerAdapter as described by @membersound is to use converters

@Component
public class LocalDateSerializeConverter implements Converter<String, LocalDate> {
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern(AppConstants.DATE_FORMAT_YYYY_MM_DD);

    @Override
    public LocalDate convert(String text) {
        return LocalDate.parse(text, formatter);
    }
}
Related