用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解析> _>

+0

感谢您的帮助,我会更容易使用js覆盖类型。 但是,如何翻译我的json文本以获得客户?在这个例子中,他使用:$ wnd.jsonData [0]; 在我来说,我有一个字符串(从RequestBuilder推出) – Tim 2010-08-10 14:32:00

+0

完美的工作,谢谢。我错过了eval函数。 祝你好运 – Tim 2010-08-11 10:09:38

+0

为什么你在eval的字符串周围使用大括号?在此代码: '返回的eval( '(' + responseString + ')');' – Davor 2013-05-28 16:43:03