用gwt 2.0解析json [英] Parse json with gwt 2.0

查看:148
本文介绍了用gwt 2.0解析json的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图解析JSON来自我的gwt 2.0应用程序中的流程。



最好的方法是什么?我应该使用javascriptobject吗? JSonParser?我失去了我在网上创建的东西,因为从来没有gwt版本。

  String text ={\\ \\ item\:[{\ Id\:\ 1\,\ Name\:\ Bob\},{\ Id\ :\ 2\,\ Name\:\ John\},{\ Id\:\ 3\,\ Name\ :\法案\}]}; 

如何使用我的物品清单?



预先感谢任何帮助

解决方案

答案取决于您相信多少JSON :)当然,它可能来自您的应用程序,但是如果插入一些不可信的用户输入,您将面临一个可能的安全漏洞。


$ b 所以:


  • 来自可信来源的JSON ,我使用 JavaScript Overlay Types 。他们使JSON与GWT无缝集成,我肯定会推荐这种方法。但是,在内部,这会调用至少两件事情的 eval()函数:JSON解析速度非常快(它使用浏览器本机代码),并且可能不安全。 Google了解有关JSON相关安全问题的更多信息。 JSONParser 也可以通过 eval()解析JSON,当您调用其 parseLenient (String jsonString) 方法,但它绝对不如JSO有吸引力。
  • 对于不可信来源/输入,
  • 应使用 JSONParser 通过 JSONParser.parseStrict(String jsonString) (可用于GWT> = 2.1) - 你必须编写更多的代码y,但你可以确定输入是正确处理的。您也可以考虑将json.org的官方 JSON解析器与JSO集成 - 编写一个 JSNI 函数返回解析对象并将其转换为JSO - in理论它应该工作;)(这就是GWT内部与JSO做的事情,至少从我了解的内容来看)



至于在JSON中访问列表,有适当的类: JsArray (通用,其他JSO列表), JsArrayString 等。如果你看看它们的实现,那么它们只是本地JS数组的JSNI包装器,所以他们速度非常快(但由于某种原因而受到限制)。






编辑回复Tim的评论:



我写了一个简单的抽象类,在处理JSO和JSON时有助于最小化样板代码:

  import com.google.gwt.core.client.JavaScriptObject; 

public abstract class BaseResponse extends JavaScriptObject {
//你可以在这里添加一些静态字段,比如状态码等。

/ **
*必填项{@link JavaScriptObject}
* /
保护BaseResponse(){}
$ b / **
*使用< code> eval< / code>从服务器解析JSON响应
*
* @param responseString包含JSON的原始字符串repsonse
* @返回一个JavaScriptObject,已经转换为适当的类型
* /
public static final native< T extends BaseResponse> T getResponse(String responseString)/ * - {
//您应该可以在这里使用安全的解析器
//(如json.org中的解析器)
return eval('( '+ responseString +')');
} - * /;
}

然后你写下你的实际JSO:

  import com.example.client.model.User; 

public class LoginResponse extends BaseResponse {

LoginResponse(){}
$ b public final String getToken()/ * - {
返回this.t;
} - * /;

public final int int getId()/ * - {
return parseInt(this.u [0]);
} - * /;

// ...

//将此JSO转换为POJO的辅助方法
public final User getUser(){
return new User (getLogin(),getName(),getLastName());


最后在你的代码中:

  // response.getText()包含JSON字符串
LoginResponse loginResponse = LoginResponse.getResponse(response.getText());
// ^无需投射\o /

您的JSON看起来像这样(由 JSONLint 提供,一个很棒的JSON验证器):

< pre $ {
item:[
{
Id:1,
Name:Bob
},
{
Id:2,
姓名:John
},
{
:3,
Name:Bill
}
]
}

因此,我会写一个描述该列表项目的JSO:

  public class TestResponse extends BaseResponse {
$ b $ protected TestResponse(){}
$ b public final String getId()/ * - {
return this.Id;
} - * /;

public final String getName()/ * - {
return this.Name;
} - * /;

//返回列表的静态帮助
//代码未经测试,但您应该明白;)
public static final JsArray< TestResponse> getTestList(String json)/ * - {
var stuff = eval('('+ json +')');
return stuff.item;
} - * /;
}

然后,在您的代码中调用 TestResponse.getTestList(someJsonString)并使用获得的 JsArray TestResponse s是自动创建的)。很酷,呃? ;)起初可能有点混淆,但相信我,一旦你开始使用它就会有意义,而且比通过 JSONParser 。 $ c>> _>


i'm trying to parse JSON coming from a flow in my gwt 2.0 application.

What is the best way ? Should I use javascriptobject ? JSonParser ? I'm lost with what I'm founding on the web because there's never the gwt version.

String text = "{\"item\":[{\"Id\":\"1\",\"Name\":\"Bob\"},{\"Id\":\"2\",\"Name\":\"John\"},{\"Id\":\"3\",\"Name\":\"Bill\"}]}";

How can I play with my list of items ?

Thanks in advance for any help

解决方案

The answer depends on how much you trust that JSON :) Sure, it might be coming from your application, but if insert some untrusted user input, you are facing a possible security hole.

So:

  • for JSONs from trusted sources, I use JavaScript Overlay Types. They make integrating JSON with GWT seamless and I'd definitely recommend this approach. However, internally, this calls the eval() function which means (at least) two things: JSON parsing will be extremely fast (it uses browsers native code for that) and will be possibly insecure. Google for more info about JSON related security issues. JSONParser can also parse JSON via eval(), when you invoke its parseLenient(String jsonString) method, but it's definitely less attractive than JSO.
  • for untrusted sources/input, you should use JSONParser via JSONParser.parseStrict(String jsonString) (available in GWT >=2.1) - you'll have to write more code that way, but you can be sure that the input is properly handled. You might also look into integrating the "official" JSON parser from json.org with JSO - write a JSNI function that returns the parsed object and cast it to your JSO - in theory it should work ;) (that's what GWT does internally with JSOs, at least from what I understood)

As for accessing lists in JSON, there are appropriate classes for that: JsArray (generic, for lists of other JSOs), JsArrayString, etc. If you look at their implementation, they are just JSNI wrappers around the native JS arrays, so they are very fast (but limited, for some reason).


Edit in response to Tim's comment:

I wrote a simple abstract class that helps to minimize the boilerplate code, when dealing with JSOs and 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 + ')');
    }-*/;
}

Then you write your actual JSO as such:

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());
    }
}

And finally in your code:

// response.getText() contains the JSON string
LoginResponse loginResponse = LoginResponse.getResponse(response.getText());
// ^ no need for a cast \o/

Your JSON looks like this (courtesy of JSONLint, a great JSON validator):

{
    "item": [
        {
            "Id": "1",
            "Name": "Bob"
        },
        {
            "Id": "2",
            "Name": "John"
        },
        {
            "Id": "3",
            "Name": "Bill"
        }
    ]
}

So, I'd write a JSO that describes the items of that list:

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;
    }-*/;
}

Then, in your code you call TestResponse.getTestList(someJsonString) and play around with the JsArray you get (the TestResponses it contains are created automagically). Cool, eh? ;) It might be a bit confusing at first, but believe me, it will make sense once you start using it and it's a lot easier than parsing via JSONParser >_>

这篇关于用gwt 2.0解析json的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆