用gwt 2.0解析json
问题描述:
我想解析来自我的gwt 2.0应用程序中的流的JSON。用gwt 2.0解析json
什么是最好的方法?我应该使用javascriptobject吗? JSonParser?我迷失在网上,因为它从来没有gwt版本。
String text = "{\"item\":[{\"Id\":\"1\",\"Name\":\"Bob\"},{\"Id\":\"2\",\"Name\":\"John\"},{\"Id\":\"3\",\"Name\":\"Bill\"}]}";
我该如何玩我的物品清单?
预先感谢任何帮助
答
答案取决于你多么相信,JSON :)当然,这可能是从你的应用程序来的,但如果插入一些不信任的用户输入,你面对一个可能的安全孔。
所以:
-
为JSONs来自可信来源,我用JavaScript Overlay Types。他们使JSON与GWT无缝集成,我肯定会推荐这种方法。但是,在内部,这称为
eval()
函数,这意味着(至少)两件事:JSON解析速度非常快(它使用浏览器本机代码),并且可能不安全。 Google了解有关JSON相关安全问题的更多信息。JSONParser
也可以通过eval()
解析JSON,当您调用parseLenient(String jsonString)
方法时,但它绝对不如JSO有吸引力。 -
为不可信来源/输入,你应该使用通过
JSONParser.parseStrict(String jsonString)
JSONParser
(GWT中> = 2.1可用) - 你必须编写更多的代码是这样,但你可以肯定的是,输入被妥善处理。你也可以考虑将“官方”JSON parser from json.org与JSO整合在一起 - 编写一个JSNI函数,返回解析对象并将其转换为JSO--理论上它应该工作;)(这就是GWT在内部对JSO的影响,至少从我的理解)
至于在JSON访问列表,有适当的类为:JsArray
(通用,其他JSOs),JsArrayString
,等等。如果你看看他们执行的名单,他们只是JSNI围绕本地JS数组进行封装,所以它们非常快(但由于某种原因而受到限制)。
编辑回应蒂姆的评论:
我JSOs和JSON打交道时写了一个简单的抽象类,有助于最大限度地减少样板代码,:
import com.google.gwt.core.client.JavaScriptObject;
public abstract class BaseResponse extends JavaScriptObject {
// You can add some static fields here, like status codes, etc.
/**
* Required by {@link JavaScriptObject}
*/
protected BaseResponse() { }
/**
* Uses <code>eval</code> to parse a JSON response from the server
*
* @param responseString the raw string containing the JSON repsonse
* @return an JavaScriptObject, already cast to an appropriate type
*/
public static final native <T extends BaseResponse> T getResponse(String responseString) /*-{
// You should be able to use a safe parser here
// (like the one from json.org)
return eval('(' + responseString + ')');
}-*/;
}
然后你请写下您的实际JSO:
import com.example.client.model.User;
public class LoginResponse extends BaseResponse {
protected LoginResponse() { }
public final native String getToken() /*-{
return this.t;
}-*/;
public final native int getId() /*-{
return parseInt(this.u[0]);
}-*/;
// ...
// Helper method for converting this JSO to a POJO
public final User getUser() {
return new User(getLogin(), getName(), getLastName());
}
}
最后在你的代码:
// response.getText() contains the JSON string
LoginResponse loginResponse = LoginResponse.getResponse(response.getText());
//^no need for a cast \o/
您的JSON看起来像这样(礼貌JSONLint,一个伟大的JSON验证):
{
"item": [
{
"Id": "1",
"Name": "Bob"
},
{
"Id": "2",
"Name": "John"
},
{
"Id": "3",
"Name": "Bill"
}
]
}
所以,我会写一个JSO描述的项目该列表:
public class TestResponse extends BaseResponse {
protected TestResponse() { }
public final native String getId() /*-{
return this.Id;
}-*/;
public final native String getName() /*-{
return this.Name;
}-*/;
// Static helper for returning just the list
// Code untested but you should get the idea ;)
public static final native JsArray<TestResponse> getTestList(String json) /*-{
var stuff = eval('(' + json + ')');
return stuff.item;
}-*/;
}
然后,在你的代码中调用TestResponse.getTestList(someJsonString)
和玩的JsArray
你会得到(它包含的TestResponse
是自动创建的)。很酷,呃? ;)这可能是一个有点混乱在第一,但相信我,它才有意义,一旦你开始使用它,它很多比通过JSONParser
解析> _>
感谢您的帮助,我会更容易使用js覆盖类型。 但是,如何翻译我的json文本以获得客户?在这个例子中,他使用:$ wnd.jsonData [0]; 在我来说,我有一个字符串(从RequestBuilder推出) – Tim 2010-08-10 14:32:00
完美的工作,谢谢。我错过了eval函数。 祝你好运 – Tim 2010-08-11 10:09:38
为什么你在eval的字符串周围使用大括号?在此代码: '返回的eval( '(' + responseString + ')');' – Davor 2013-05-28 16:43:03