【问题标题】:play framework - bind enum in routes播放框架 - 在路由中绑定枚举
【发布时间】:2014-01-30 22:10:36
【问题描述】:

我在 play 2.2 上用 java 构建一个应用程序。

我在路由中使用的函数中有一个 java 枚举作为参数。

这是我的枚举类。我四处搜索,发现我需要实现 QueryStringBindable 才能在路由中使用它。

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;
    }
}

但我尝试过我的路线:

GET    /someurl     controllers.Application.function(status: util.enums.Something)

但它返回错误的请求,错误消息为:

对于请求 'GET /someurl' [util.enums.Something]

我用谷歌搜索并没有找到任何适合我的答案。我错过了什么还是 play 不支持绑定枚举?

【问题讨论】:

    标签: java playframework enums playframework-2.0


    【解决方案1】:

    我遇到了同样的问题,我终于发现它无法按原样解决。

    通过阅读PathBindableQueryStringBindable 的文档,我发现播放框架需要 Bindable 来提供无参数公共构造函数。根据定义,在 Java 中 enum 是不可能的。

    所以我不得不包装我的枚举来解决这个问题。在您的示例中,我们将有类似的内容:

    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;
           }
        }
    }
    

    然后您必须使用类型 some.package.Something.Bound 作为您的路由文件中的类型。

    编辑:在模板中使用它有点棘手。而且您必须了解一些scala。 关注@Aleksei 的评论

    <a href="@routes.MyController.showStuff(myEnumVar)">link</a>
    

    应该变成

    <a href="@{
       routes.MyController.showStuff(new MyEnumVarWrapper(myEnumVar)).url
    }">link</a>
    

    【讨论】:

    • 我考虑过相同的解决方案,但对我来说听起来太老套了。所以我最终将该字段绑定到一个字符串并在我的控制器中解析该字符串以获得一个枚举。不过,这个 hacky 解决方案是最接近游戏 2 的解决方案。
    • 这种方式似乎更有效,但至少你玩的框架会在有人拼写错误时为你返回正确的 http 错误代码。
    • 当需要从模板调用操作时,您的解决方案不是很清楚。我的意思是这样的代码:&lt;a href="@routes.MyController.showStuff(myEnumVar)"&gt;link&lt;/a&gt; 我需要放置什么而不是 myEnumVar?
    【解决方案2】:

    我想对答案做一个小的修正: (返回类型不是ClientStatus,解绑函数要使用key参数,是用来生成url的)

    public enum Something {
    a,
    b,
    c;
    
    public static class Bound implements QueryStringBindable<Bound>{
       private Something value;
    
        @Override
        public F.Option<Bound> 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 key + "=" + this.value.name();
        }
    
        @Override
       public String javascriptUnbind() {
            return this.value.name();
       }
    
       public Something value(){
           return this.value;
       }
    }
    

    }

    【讨论】:

    • 欢迎来到 Stack Overflow!这确实是对现有答案的评论。多一点代表,you will be able to post comments。如果您想将此作为不同的答案提供,请解释为什么您认为与现有答案相比这是正确或更好的。
    猜你喜欢
    • 1970-01-01
    • 2015-10-18
    • 2018-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多