I am building an app in java on play 2.2.
I have a java enum as a parameter in a function that I use in routes.
This is my enum class. I searched around and found out I need to implements QueryStringBindable to use it in routes.
public enum Something implements QueryStringBindable<Something> {
    a,
    b,
    c;
    @Override
    public F.Option<ClientStatus> bind(String key, Map<String, String[]> params) {
        String[] arr = params.get(key);
        if (arr == null || arr.length == 0) {
            return F.Option.None();
        } else {
            Something status = Something.valueOf(arr[0]);
            return F.Option.Some(status);
        }
    }
    @Override
    public String unbind(String key) {
        return null;
    }
    @Override
    public String javascriptUnbind() {
        return null;
    }
}
Yet I tried in my routes:
GET    /someurl     controllers.Application.function(status: util.enums.Something)
But it returns bad request with error message as:
For request 'GET /someurl' [util.enums.Something]
I googled and didn't find any answer working in my case. Did I miss something or play doesn't support binding enums?
I had the same problem and I finally found out that it is not solvable as is.
By reading the documentation for PathBindable and QueryStringBindable I found that play framework requires the Bindable to provide a No Argument public constructor. Which by definition is no possible with enum in Java.
So I had to wrap my enum to solve this. In your example we would have something like:
public enum Something {
    a,
    b,
    c;
    public static class Bound implements QueryStringBindable<Bound>{
       private Something value;
        @Override
        public F.Option<ClientStatus> bind(String key, Map<String, String[]> params) {
            String[] arr = params.get(key);
            if (arr != null && arr.lenght > 0) {
                this.value = Something.valueOf(arr[0]);
                return F.Option.Some(this);
            } else {
                return F.Option.None();
            }
        }
        @Override
        public String unbind(String key) {
            return this.value.name();
        }
        @Override
       public String javascriptUnbind() {
            return this.value.name();
       }
       public Something value(){
           return this.value;
       }
    }
}
and then you have to use the type some.package.Something.Bound as a type in your routes file.
EDIT: using that in a template is slightly more tricky. And you have to know a bit of scala. To follow @Aleksei's comment
<a href="@routes.MyController.showStuff(myEnumVar)">link</a>
should become
<a href="@{
   routes.MyController.showStuff(new MyEnumVarWrapper(myEnumVar)).url
}">link</a>
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With