Custom querystring parameters in Play

Usually, actions in Play does not receive complex parameters. If you take a look in your project, probably you will see just simple parameters. Integers, Longs etc. Yesterday, trying to find questions to answer in the Play forum, I found one about receiving a java.util.Date parameter in the controller’s action.

    public static Result findByDate(Date date){
    	System.out.println(date);
    	return ok();
    }

When you configure this action in your routes file, an error will be printed in your console.

    No QueryString binder found for type java.util.Date. Try to implement an implicit     QueryStringBindable for this type

By default, Play does not know how to transform a querystring parameter into a Date object. That’s why we have the QueryStringBindable interface. This is like a formatter, but to querystring parameters. The first thing we need to do is to implement our converter.

	public class DateParameter implements QueryStringBindable<DateParameter>{

		private SimpleDateFormat formatter = new SimpleDateFormat("dd/MM/yyyy");
		private Date value;

		@Override
		public Option<DateParameter> bind(String key,
				Map<String, String[]> parameters) {
			if(parameters.containsKey(key)){
				String date = parameters.get(key)[0];
				try {
					this.value = formatter.parse(date);
				} catch (ParseException e) {
					throw new IllegalArgumentException(e);
				}
				return Option.<DateParameter>Some(this);
			}
			return Option.<DateParameter>None();
		}

		public Date getValue() {
			return value;
		}

		@Override
		public String javascriptUnbind() {			
			return null;
		}

		@Override
		public String unbind(String key) {
			return "key="+formatter.format(value);
		}

	}

Now you need to receive this object as a parameter in your action and change your routes file as well.

    public static Result findByDate(DateParameter date){
    	System.out.println(date.getValue());
    	return ok();
    }

 GET /findByDate	controllers.NewsController.findByDate(date:binders.DateParameter)

A last thing here. In our action, we invoke the getValue method to recover the parsed date. This is why you should keep state in your QueryStringBindable object. Every time a request is made to a method receiving a DateParameter, Play will instantiate this object.

If you have or had this necessity, you can use this interface or the PathBindable, for the cases when the parameter is mixed in the url.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s