获取和使用远程JSON数据

zco*_*rts 3 gwt json javascript-objects

我正在开发一个小应用程序并使用GWT来构建它.我刚尝试向远程服务器发出请求,该服务器将以JSON的形式返回响应.我尝试过使用叠加类型概念,但我无法使用它.我一直在改变代码,所以它与谷歌GWT教程留下的地方略有不同.

JavaScriptObject json;
    public JavaScriptObject executeQuery(String query) {
        String url = "http://api.domain.com?client_id=xxxx&query=";
        RequestBuilder builder = new RequestBuilder(RequestBuilder.GET,
                URL.encode(url + query));
        try {
            @SuppressWarnings("unused")
            Request request = builder.sendRequest(null, new RequestCallback() {
                public void onError(Request request, Throwable exception) {
                    // violation, etc.)
                }

                public void onResponseReceived(Request request,
                        Response response) {
                    if (200 == response.getStatusCode()) {
                        // Process the response in response.getText()
                        json =parseJson(response.getText());
                    } else {

                    }
                }
            });
        } catch (RequestException e) {
            // Couldn't connect to server
        }
        return json;
    }

    public static native JavaScriptObject parseJson(String jsonStr) /*-{
        return eval(jsonStr );
        ;
    }-*/;
Run Code Online (Sandbox Code Playgroud)

在chrome的调试器中,我得到了伞形,无法看到堆栈跟踪和GWT调试器死于NoSuchMethodError ...任何想法,指针?

小智 13

您可以查看GWT AutoBean框架.

AutoBean允许您从Plain Old Java Object序列化和反序列化JSON字符串.

对我来说这个框架变得至关重要

  • 代码比JSNI对象更清晰(JavaScript Native Interface)
  • 不支持Google不支持的框架(如RestyGWT)

您只需使用getter和setter定义接口:

// Declare any bean-like interface with matching getters and setters, 
// no base type is necessary
interface Person {
  Address getAddress();
  String getName();
  void setName(String name):
  void setAddress(Address a);
}

interface Address {
  String getZipcode();
  void setZipcode(String zipCode);
}
Run Code Online (Sandbox Code Playgroud)

稍后您可以使用工厂序列化或反序列化JSON String(请参阅文档):

// (...)

String serializeToJson(Person person) {
  // Retrieve the AutoBean controller
  AutoBean<Person> bean = AutoBeanUtils.getAutoBean(person);

  return AutoBeanCodex.encode(bean).getPayload();
}

Person deserializeFromJson(String json) {
  AutoBean<Person> bean = AutoBeanCodex.decode(myFactory, Person.class, json);
  return bean.as();
}

// (...)
Run Code Online (Sandbox Code Playgroud)

Stack Overflow上的第一篇文章(!):我希望这有帮助:)


Jas*_*erk 5

  1. 使用JsonUtils#safeEval()评估JSON字符串,而不是调用的eval()直接.
  2. 更重要的是,不要尝试传递异步调用的结果(比如RequestBuilder#sendRequest()回调用者使用return- 使用回调:

    public void executeQuery(String query,
                             final AsyncCallback<JavaScriptObject> callback)
    {
      ...
      try {
        builder.sendRequest(null, new RequestCallback() {
          public void onError(Request request, Throwable caught) {
            callback.onFailure(caught);
          }
    
          public void onResponseReceived(Request request, Response response) {
            if (Response.SC_OK == response.getStatusCode()) {
              try {
                callback.onSuccess(JsonUtils.safeEval(response.getText()));
              } catch (IllegalArgumentException iax) {
                callback.onFailure(iax);
              }
            } else {
              // Better to use a typed exception here to indicate the specific
              // cause of the failure.
              callback.onFailure(new Exception("Bad return code."));
            }
          }
        });
      } catch (RequestException e) {
        callback.onFailure(e);
      }
    }
    
    Run Code Online (Sandbox Code Playgroud)


Wes*_*ley 5

通常,您描述的工作流程包括四个步骤:

  1. 提出要求
  2. 接收JSON文本
  3. 解析JavaScript对象中的JSON
  4. 使用叠加类型描述这些JavaScript对象

听起来你已经让步骤1和2正常工作了.

解析JSON

JSONParser.parseStrict会做得很好.你将被退回一个JSONValue物体.

这将允许您避免使用自定义本机方法,并且还将确保在解析JSON时它可以防止任意代码执行.如果您的JSON有效负载是可信的并且您想要原始速度,请使用JSONParser.parseLenient.在任何一种情况下,您都不需要编写自己的解析器方法.

假设你期待以下JSON:

{
  "name": "Bob Jones",
  "occupations": [
    "Igloo renovations contractor",
    "Cesium clock cleaner"
  ]
}
Run Code Online (Sandbox Code Playgroud)

既然您知道JSON描述了一个对象,那么您可以告诉JSONValue您期望获得一个对象JavaScriptObject.

String jsonText = makeRequestAndGetJsonText(); // assume you've already made request
JSONValue jsonValue = JSONParser.parseStrict(jsonText);
JSONObject jsonObject = jsonValue.isObject(); // assert that this is an object
if (jsonObject == null) {
  // uh oh, it wasn't an object after
  // do error handling here
  throw new RuntimeException("JSON payload did not describe an object");
}
Run Code Online (Sandbox Code Playgroud)

描述为叠加类型

现在您知道您的JSON描述了一个对象,您可以获取该对象并根据JavaScript类对其进行描述.假设你有这种叠加类型:

class Person {
  String getName() /*-{
    return this.name;
  }-*/;
  JsArray getOccupations() /*-{
    return this.occupations;
  }-*/;
}
Run Code Online (Sandbox Code Playgroud)

您可以通过执行强制转换使新的JavaScript对象符合此Java类:

Person person = jsonObject.getJavaScriptObject().cast();
String name = person.getName(); // name is "Bob Jones"
Run Code Online (Sandbox Code Playgroud)