9

我不得不说我对如何使用新的 Play Framework 2 处理请求参数有点困惑。关于如何发出请求的数据来自不同的来源。到目前为止,以下是可能性:

1 - 如果你做一个简单的 GET :

ctx().request().queryString()

2 - 如果您使用 HTML 表单进行 POST :

表格 :

<form method="post" action="/">
    <input type="hidden" name="foo" value="bar" />
    <input type="hidden" name="t" value="1" />
    <input type="hidden" name="bool" value="true" />
    <input type="submit" name="submit" value="Submit" />
</form>

方法 :

public static Result test() {
    ctx().request().queryString();             // {} ; As expected
    ctx().request().body();                    // contains data
    ctx().request().body().asFormUrlEncoded(); // contains data
    ctx().request().body().asJson();           // empty
    return ok();
}

这似乎很正常。

现在,如果我添加@BodyParser.Of(BodyParser.Json.class)(假设我同时接受 Ajax POST 和普通 POST 以在非 JS 情况下回退):

@BodyParser.Of(BodyParser.Json.class)
public static Result test() {
    ctx().request().queryString();             // {} ; as Expected
    ctx().request().body();                    // contains data
    ctx().request().body().asFormUrlEncoded(); // empty : Shouldn't this contains data since I posted them via a simple form ?!
    ctx().request().body().asJson();           // empty
    return ok();
}

然后,地狱发生了:如果没有填写一个简单表单的值(asJson、asFormUrlEncoded 等),我怎么能得到它们?!

3 - 如果您通过 AJAX 进行 POST :

// Code in JS used :
$.ajax({
    'url': '/',
    'dataType': 'json',
    'type': 'POST',
    'data': {'foo': 'bar', 't': 1, 'bool': true}
});

结果 :

public static Result test() {
    ctx().request().queryString();             // {}
    ctx().request().body();                    // contains data
    ctx().request().body().asFormUrlEncoded(); // contains data
    ctx().request().body().asJson();           // empty
    return ok();
}

@BodyParser.Of(BodyParser.Json.class)

@BodyParser.Of(BodyParser.Json.class)
public static Result test() {
    ctx().request().queryString();             // {}
    ctx().request().body();                    // contains data
    ctx().request().body().asFormUrlEncoded(); // empty
    ctx().request().body().asJson();           // empty : Shouldn't this contains data since I espect JSON ?!
    return ok();
}

asJson()根据文档,这里的不一致是应该返回数据的方法

注意:这样,对于非 JSON 请求,将自动返回 400 HTTP 响应。(http://www.playframework.org/documentation/2.0/JavaJsonRequests)

我想知道的是,对于可以接受来自 HTML 的简单帖子或带有 POST 的 Ajax 请求的 POST 来说,最好的装饰器+方法是什么?

4

2 回答 2

7

我建议使用 PlayFramework 提供的 Form 类。表单将其值绑定到提供的请求数据。

有两种不同的 Form 实现:

  1. DynamicForm:POST 数据可通过 Map 访问器方法获得
  2. Form:Form 的通用形式将 POST 数据映射到实体类的实例[更多信息]

    该表单还提供了一些有用的功能,如自动类型转换、验证、错误报告等。

一个带有动态表单的简单示例:

阿贾克斯请求:

$.post("@routes.Application.movetodo()", 
    { "id": 123, "destination": destination }, function(data)
        {
           // do something when request was successfull
        });

路由文件:

GET     /                           controllers.Application.index()
POST    /movetodo                   controllers.Application.movetodo()

控制器实现:

public static Result movetodo()
{
    DynamicForm data = form().bindFromRequest(); // will read each parameter from post and provide their values through map accessor methods
    // accessing a not defined parameter will result in null
    String id = data.get("id");
    String destination = data.get("destination");

    return ok();
}
于 2012-06-10T12:44:37.650 回答
0

asJson() 为空的原因是,默认情况下,$.ajax将发送内容类型设置为'application/x-www-form-urlencoded; 的请求;字符集=UTF-8'。您需要将其设置为'application/json; 字符集=utf-8'

$.ajax({
    contentType: "application/json; charset=utf-8",
    ...
})
于 2014-05-22T07:05:11.760 回答