自动绑定复杂(JSON)表单数据 [英] Bind complex (JSON) form data automatically
问题描述
我的JSON数据来自request().body().asFormUrlEncoded().get("records")
My JSON data coming in 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:
It doesn't bind the records
automatically. Then I tried with a POJO instead:
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
.
It doesn't bind the data automatically either. Do I really need to use low level APIs like jackson for this simple use case? Any pointer? Couldn't find a copy/paste example, and from jackson I have org.codehaus.jackson
and com.fasterxml.jackson
on my classpath.
更新2013-05-10:添加了辅助字段someField
,以阐明records
只是一个字段,而不是整个数据结构.以下答案来自(我无法在此编辑屏幕上看到答案,所以没关系,只有一个)有效,但仅适用于记录.这是一个示例:
UPDATE 2013-05-10: added a secondary field someField
to clarify that the records
is just one field, not the whole data structure. The answer below from (I cannot see the answers on this edit screens, so never mind, there is just one) works, but only with the records. Here's an example:
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;
}
与往常一样,对于其他表单字段:
For the other form fields I do, as usual:
Form<MyForm> form = play.data.Form.form(MyForm.class).bindFromRequest();
因此,现在我可以获取所有已发布的表单数据,并且可以通过这种方式解决我的问题(谢谢!).但是,这有点丑陋.我还不能弄清楚的是如何将所有发布数据都放在一个对象中.如果有人对此进行了答复,那么我将更新问题并删除此部分.否则,几天后我会接受一个答案.
So right now I get to all the posted form data, and my problem is solved this way (thanks!). However, it's a bit ugly. What I can't figure out yet is how to have all post data in one object. If someone replies to this then I'll update the question and remove this part. Otherwise I'll accept the single answer in a couple of days.
推荐答案
我认为,您应该使用官方文档
In my opinion, you should use jackson
API's as described in the official documentation here.
我假设您使用request().body().asFormUrlEncoded().get()
获得了JSON,因此它返回包含您的JSON字符串的String[]
.您可以执行以下操作(可能有点复杂,可能会错过Exception
处理):
I assume that you get the JSON with request().body().asFormUrlEncoded().get()
, so it return String[]
containing your JSON String. You can do something like this (Maybe a little complicated one and miss Exception
handling) :
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>
对象.
So, at the end of the code above, ((MyForm) formData).records
should contains List<Record>
object from your JSON.
这篇关于自动绑定复杂(JSON)表单数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!