[2.1.1 java] Map enum parameter in routes

505 views
Skip to first unread message

Andrea Guarini

unread,
May 13, 2013, 2:42:09 PM5/13/13
to play-fr...@googlegroups.com
Hi,
I'm trying to use a custom defined Enum as a parameter type in my controllers and routes. I would like to map a portion of the request URL as an Enum.

The Enum is defined as following:

public enum Sorting implements QueryStringBindable<Sorting2>, PathBindable<Sorting2>
{
@EnumValue("I")
IMPORTANT_FIRST, 
@EnumValue("N")
NEWEST_FIRST, 
@EnumValue("O")
OLDEST_FIRST;
private Sorting value;

@Override
public Option<Sorting> bind(String key, Map<String, String[]> data)
{
String[] vs = data.get(key);
        if (vs != null && vs.length > 0) {
            String v = vs[0];
            value = Enum.valueOf(Sorting.class, v);
            return Option.Some(value);
        }
        return Option.None();
}
@Override
public String unbind(String key)
{
return key + "=" + value;
}
@Override
public String javascriptUnbind()
{
return value.toString();
}

@Override
public Sorting bind(String key, String txt)
{
        this.value = Enum.valueOf(Sorting.class, txt);
    return this;
}
}

My controller action is:

public static Result enumTest(Sorting s)

My route is:
GET  /enumTest/:s controllers.Application.enumTest2(s:full.path.to.Sorting)

My test url in the browser:

Play says this:
Bad request
For request 'GET /enumTest/IMPORTANT_FIRST' [full.path.to.Sorting]

Play is compiling the code successfully and I don't get any exceptions in the console at runtime.
How can I solve this?

Thank you for your help.

Edouard Pelosi

unread,
Feb 13, 2014, 12:48:25 AM2/13/14
to play-fr...@googlegroups.com
The class that implements PathBindable and QueryStringBindable need to provider a noarg public constructor.
So enum cannot use it as all constuctors are private.
I solved it by wrapping it in another class like this:


enum MyEnum {
   stuff,
   thing
}

class MyWrapper implements QueryStringBindable<MyWrapper>, PathBindable<MyWrapper> {

         private MyEnum value;

        //getter setter

        @Override
        public CrudEntitiesBindable bind(String key, String txt) {
            this.value = MyEnum.valueOf(txt);
            return this;
        }

        @Override
        public F.Option<MyWrapper> bind(String key, Map<String, String[]> data) {
            String[] strings = data.get(key);
            if(strings != null && strings.length > 0){
                MyWrapper c = new MyWrapper();
                c.value = MyEnum.valueOf(strings[0]);
                return F.Some(c);
            }else{
                return F.None();
            }
        }

        @Override
        public String unbind(String key) {
            return this.value.name();
        }

        @Override
        public String javascriptUnbind() {
            return this.value.name();

Oleg Derid

unread,
Jun 20, 2014, 9:50:31 AM6/20/14
to play-fr...@googlegroups.com
Thanks mate for sharing the solution. Please, help with the following:

I couldn't find the CrudEntitiesBindable class import package in 2.3 play Java API reference, please advice which one is ok to use?

P.S. the following are required to resolve the rest of the entitites
import play.libs.F;
import play.mvc.PathBindable;
import play.mvc.QueryStringBindable;
import java.util.Map;
Reply all
Reply to author
Forward
0 new messages