Ответ зависит от того, насколько вы уверены, что JSON :) Конечно, это может быть исходя из вашего приложения, но если вставить некоторые ненадежный ввод данных пользователем, вы столкнулись с возможной безопасности дыра.
Итак:
- для JSONs из надежных источников, я использую JavaScript Overlay Types. Они делают интеграцию JSON с GWT бесшовной, и я определенно рекомендую этот подход. Однако внутренне это вызывает функцию
eval()
, которая означает (по крайней мере) две вещи: синтаксический разбор JSON будет чрезвычайно быстрым (для этого используется собственный код браузеров) и будет, вероятно, небезопасным. Google для получения дополнительной информации о связанных с JSON проблемах безопасности. JSONParser
также может анализировать JSON через eval()
, когда вы вызываете его метод parseLenient(String jsonString)
, но он определенно менее привлекателен, чем JSO.
- для ненадежных источников/вход, вы должны использовать
JSONParser
через JSONParser.parseStrict(String jsonString)
(доступен в GWT> = 2.1) - вы должны будете писать больше кода, что путь, но вы можете быть уверены, что вход надлежащим образом. Вы также можете изучить интеграцию «официального» JSON parser from json.org с JSO - написать функцию JSNI, которая возвращает проанализированный объект и отсылает его на ваш JSO - теоретически это должно работать;) (это то, что GWT делает внутри с JSOs, по крайней мере от того, что я понял)
что касается доступа списков в формате 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
s он содержит автоматически). Круто, а? ;) Сначала может показаться немного запутанным, но поверьте мне, это будет иметь смысл, как только вы начнете его использовать, и это много проще, чем синтаксический анализ через JSONParser
> _>
Спасибо за вашу помощь, я собираюсь для использования типов наложения js. Но как бы я перевел свой json-текст, чтобы получить клиента? В этом примере он использует: $ wnd.jsonData [0]; В моем случае у меня есть строка (поступающая из RequestBuilder) – Tim
работает отлично, спасибо. Я пропустил функцию eval. С уважением – Tim
Почему вы использовали фигурные скобки вокруг строки в eval? В этом коде: 'return eval ('+ responseString +') ');' – Davor