6

我的 JSON 数据进来了request().body().asFormUrlEncoded().get("records")

[{"string":"foo","termId":"793340"},{"string":"bar","termId":"460288"}]

我的表单定义:

public static class MyForm {
    @Constraints.Required
    public List<Map<String,String>> records;
    public String someField;
}

它不会records自动绑定。然后我尝试使用 POJO:

public static class Record {
    public String string;
    public String termId;
    public void setString(String string) {
        this.string = string;
    }
    public void setTermId(String termId) {
        this.termId = termId;
    }
}

并改编了表格:

public static class MyForm {
    @Constraints.Required
    public List<Record> records;
    public String someField;
}

它也不会自动绑定数据。对于这个简单的用例,我真的需要使用像杰克逊这样的低级 API 吗?任何指针?找不到复制/粘贴示例,并且从杰克逊那里找到了,org.codehaus.jackson并且com.fasterxml.jackson在我的类路径中。

更新 2013-05-10:添加了一个辅助字段someField以澄清这records只是一个字段,而不是整个数据结构。下面的答案(我在这个编辑屏幕上看不到答案,所以没关系,只有一个)有效,但仅限于记录。这是一个例子:

private List<Record> recordsFromRequest() {
    String[] jsonData = request().body().asFormUrlEncoded().get("records");
    Form<Record> recordDummyForm = Form.form(Record.class);
    Iterator<JsonNode> it = Json.parse(jsonData[0]).iterator();
    List<Record> records = new ArrayList<>();
    while (it.hasNext()) {
        records.add(recordDummyForm.bind(it.next()).get());
    }
    return records;
}

对于我做的其他表单字段,像往常一样:

Form<MyForm> form = play.data.Form.form(MyForm.class).bindFromRequest();

所以现在我得到了所有发布的表单数据,我的问题就这样解决了(谢谢!)。但是,它有点难看。我还想不通的是如何将所有发布数据放在一个对象中。如果有人回复此问题,我将更新问题并删除此部分。否则我会在几天内接受单一答案。

4

2 回答 2

2

在我看来,您应该使用此处jackson官方文档中描述的 API 。

我假设您使用 获取 JSON request().body().asFormUrlEncoded().get(),因此它返回String[]包含您的 JSON 字符串。你可以做这样的事情(也许有点复杂并且错过Exception处理):

String[] jsonData = request().body().asFormUrlEncoded().get("records")
MyForm myForm = new MyForm();
// Record should act as form, because each JSON string data contain this type
Form<Record> form = Form.form(Record.class);
// parse the JSON string and assign iterator 
Iterator<JsonNode> it = Json.parse(jsonData[0]).iterator(); 
// assign to the MyForm instance
while (it.hasNext()) {
    formData.records.add(form.bind(it.next()).get()); // bind the JSON and add
}

因此,在上面代码的末尾,((MyForm) formData).records应该包含List<Record>来自 JSON 的对象。

于 2013-05-09T12:21:04.193 回答
1

我试图重现您的错误。所以我创建了一个模型如下:

public class EasyContact {

public String someField;

@Required
public List<Record> records;

public static class Record {
    public String string;
    public String termId;
    @Override
    public String toString() {
        return "Record [string=" + string + ", termId=" + termId + "]";
    }
}

@Override
public String toString() {
    return "EasyContact [someField=" + someField + ", records=" + records+ "]";
}
}

然后像这样一个简单的控制器:

    public static Result submit() {
    Form<EasyContact> filledForm = form(EasyContact.class).bindFromRequest();
    Logger.info("Posted binding: " + filledForm.get().toString());
    return ok();
}

现在是测试的时候了:

curl -X POST -H 'Content-Type: application/json' -d '{"someField":"didac", "records": [{"string": "string1", "termId": "111"},{"string": "string2", "termId": "222"}]}' localhost:9000/contacts

在播放命令行中,我可以看到正确的输出:

[info] application - Posted binding: EasyContact [someField=didac, records=[Record [string=string1, termId=111], Record [string=string2, termId=222]]]

我发现的唯一错误是未在请求中设置 Content-Type (-H ...)。在这种情况下,框架会引发 IllegalState 异常。

于 2013-12-16T20:49:44.387 回答