我的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;
}
它也不会自动绑定数据。对于这个简单的用例,我真的需要使用像jackson这样的低级API吗?任何指针?找不到复制/粘贴示例,而且我在类路径上有org.codehaus.jackson
和com.fasterxml.jackson
来自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();
所以现在我得到所有发布的表单数据,我的问题就这样解决了(谢谢!)。但是,它有点难看。我还想知道的是如何将所有发布数据放在一个对象中。如果有人回复此问题,我将更新问题并删除此部分。否则我会在几天内接受单一答案。
答案 0 :(得分:2)
在我看来,您应该使用官方文档here中所述的jackson
API。
我假设您使用request().body().asFormUrlEncoded().get()
获取JSON,因此它返回包含您的JSON字符串的String[]
。你可以做这样的事情(可能有点复杂而且错过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
应该包含来自JSON的List<Record>
对象。
答案 1 :(得分: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异常。