Sunday, June 12, 2011

Spring Controller with Date Object Bindings

UPDATE (28 Dec 2011): The new Spring 3.1 release includes a new DateFormatter, which provides this flexibility for passing in date fields in URLs.  Below is the original post for those still interested in the WebDataBinder API. 

I guess this is turning into a series on time handling, but I wanted to share how to use the data binders in Spring to pass around date classes.  After all, you may want to have URLs that end in some representation of a "day" to page through time-sensitive data, or filter your data based on time, etc.

For example, if you wanted to have a URL parameter of the form "yyyy-MM-dd", i.e. the XML Schema format, and marshal it into a java.util.Date, how would you go about doing this?

Well, Spring provides:
  • an InitBinder to initialize WebDataBinders on a controller - i.e. setup a the binding mechanism on a Spring controller automatically
  • WebDataBinder to register custom property editors to convert certain types.  In this case the type is java.util.Date, and the property editor is also provided by Spring - CustomDate Editor
With this, you can now use a date class with:
  • @RequestParam(value="date", required=false) Date date
  • @RequestMapping(value="/date/{date}", method=RequestMethod.GET) ...
  • @PathVariable("date") Date date

Here's the code:

package mypackage;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import org.springframework.stereotype.Controller;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
@Controller
public class DateController {
@RequestMapping("/dates", method=RequestMethod.GET)
public ModelAndView getDate(@RequestParam(value="date", required=false) Date date) {
ModelAndView mv = new ModelAndView();
if (date == null) {
date = new Date();
}
mv.addObject("date", date);
mv.setView("dates");
return mv;
}
@InitBinder
public void initBinder(WebDataBinder binder) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
dateFormat.setLenient(false);
binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, false));
}
}


Enjoy!

No comments:

Post a Comment