如何正确使用JsonUtils.safeEval()中的JSArray <T>对象?

时间:2019-07-05 13:43:03

标签: javascript json gwt

我正在使用RequestBuilder读取静态JSON文件,并确认我在响应的.getText()方法中看到了预期的JSON。我已经简化了工作以尝试找出确切的问题。这几乎是我能做的准系统。

我使用JsonUtils.safeEval()将响应解析为我的叠加类型,然后将结果传递到一个将结果吐出到页面上的函数中。显然,这种方法还有很多,但是为了简洁起见,我省略了它。

@Override
public void onResponseReceived(Request request, Response response) {    
    JsArray<JSONLeadTime> tmp = JsonUtils.<JsArray<JSONLeadTime>>safeEval(response.getText());
    if (200 == response.getStatusCode()) {
        renderLeadTimes(tmp);
    } else {
        AlertWindow.displayAlert(ERRORS.GENERIC_CLIENT_ERROR);      
    }
}

这里是覆盖类型定义,以供参考。为了记录,还定义了“设备”覆盖类型。您可以从下面的JSON中收集定义,也可以根据需要添加。

public class JSONLeadTime extends JavaScriptObject {
    protected JSONLeadTime() {}
    public final native String getFacility() /*-{ return this.facility; }-*/;
    public final native List<equipment> getEquipment() /*-{ return this.equipment; }-*/;
}

以及正在解析的JSON的示例:

[{
    "JSONLeadTime": {
        "facility": "Temperance",
        "equipment": [{
            "name": "Coil Line",
            "value": "coil-line",
            "lead-time": 2,
            "sales-router-id": [76]
        }]
    }
}]

当我尝试遍历JSArray时,一切都很好,直到我尝试访问overlay类型的方法为止。这是分散结果的方法。当我调用leadTimes.get(i)时,我可以看到“ leadTime”是一个JavaScriptObject,这是我当时期望的。当我调用“ leadTime.getFacility()”时,我将获得NPE。

protected void renderLeadTimes(JsArray<JSONLeadTime> leadTimes) {
    SafeHtmlBuilder sb = new SafeHtmlBuilder();
    for (int i=0; i < leadTimes.length(); i++) {
        JSONLeadTime leadTime = leadTimes.get(i);
        sb.appendEscaped(leadTime.getFacility()); //This is where I get the NPE
        if ( leadTime.getEquipment() != null ) {
            for ( int  x=0; x < leadTime.getEquipment().size(); x++ ) {
                equipment e = leadTime.getEquipment().get(x);
                sb.appendEscaped(" - " + e.getName());
            }
        }
    }       
    view.getDivLeadTimes().setInnerSafeHtml(sb.toSafeHtml());
}

我完全不知所措。我不知道为什么这不起作用。我读过的所有内容都说应该可以。任何尝试尝试的想法都将不胜感激。

2 个答案:

答案 0 :(得分:1)

您的JSON数组包含具有单个JSONLeadTime属性的对象,这些属性的值将与覆盖类型匹配。您丢失了JsArray与叠加层类型之间的中间对象。

答案 1 :(得分:0)

在我的代码中,我首先创建了一个类型,如下所示:

/**
 * This class may not be directly instantiated, and can only be returned from a
 * native method. For example,
 *
 * <code>
 * native JsArray<JavaScriptObject> getNativeArray() /*-{
 *   return [
 *     { x: 0, y: 1},
 *     { x: 2, y: 3},
 *     { x: 4, y: 5},
 *   ];
 * }-* /;
 * </code>
 */
public class TeamMembersJso extends JsArray<TeamMemberJso> {

  protected TeamMembersJso() {
  }
}

然后我将原始JSON数据评估到JavaScript覆盖实例中。

TeamMembersJso jsoData = JsonUtils.safeEval(rawData);

不确定它是否与代码中直接使用JsArray<JSONLeadTime>有关。绝对值得尝试一下我使用的方法,因为它对我来说效果很好。

我正在使用GWT 2.8.2,但是我认为没有太大的区别。