#javascript #json #function #gson
#javascript #json #функция #gson
Вопрос:
Возможно ли создать подобный json с помощью Gson? Функция javascript без ключа находится внутри json.
{
autosave: {
save( editor ) {
return editor.saveData( editor.id, editor.getData() );
},
waitingTime: 2000
}
Заранее спасибо.
Комментарии:
1. Нет, функции не включены в JSON.
2. Я знаю, что это недопустимый json. Но я думаю, что это выполнимо, хотя и не рекомендуется.
3. Почему? Это недопустимо, и вы не можете сделать это с помощью любого stringifier. Вы могли бы добавить функции в строку JSON после упорядочивания объекта, но чего это стоит, ни один анализатор не может разобрать этот JSON. Типичным способом доставки функций в JSON является реализация функции (функций) в приложении и включение имени функции в виде строки. Затем после синтаксического анализа JSON в приложении вы можете заменить строковые значения, представляющие функцию, на реальные функции.
4. Это особое требование. Спасибо за ваш ответ. Теперь я знаю, как этого добиться.
5. Gson — совершенно неподходящий инструмент для такого требования. Почему бы не использовать генератор кода JavaScript или просто создать действительный JavaScript с шаблонами или что-то более подходящее? JSON расшифровывается как «объектная нотация JS», а не «JS», и он не может обрабатывать ничего, кроме объектов, массивов и литералов.
Ответ №1:
Наконец, я нахожу способ сделать это с помощью TypeAdapterFactory. Вот код.
class AutosaveAdapter implements TypeAdapterFactory {
@Override
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> tokenType) {
final TypeAdapter<T> adapter = gson.getDelegateAdapter(this, tokenType);
return new TypeAdapter<T>() {
@Override
public T read(JsonReader reader) throws IOException {
return adapter.read(reader);
}
@Override
public void write(JsonWriter writer, T value) throws IOException {
JsonElement tree = adapter.toJsonTree(value);
if (value instanceof Autosave) {
String dom = value.toString();
JsonObject jo = (JsonObject) tree;
jo.addProperty("autosave", dom );
}
gson.getAdapter(JsonElement.class).write(writer, tree);
}
};
}
}
И
class Autosave {
int waitingTime;
@Expose(serialize = false, deserialize = false)
String name;
@Expose(serialize = false, deserialize = false)
String arguments;
@Expose(serialize = false, deserialize = false)
String body;
Autosave(int waitingTime, String name, String arguments, String body) {
this.waitingTime = waitingTime;
this.name = name;
this.arguments = arguments;
this.body = body;
}
public String toString() {
return "{ waitingTime:" waitingTime ","
name " ( " arguments " ) { " body " } "
"}";
}
}
Для тестирования:
public static void main(String... args) {
Autosave autosave = new Autosave(2000, "save", "editor", "return editor.saveData( editor.id, editor.getData() );");
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.setLenient();
Gson gson = gsonBuilder
.excludeFieldsWithoutExposeAnnotation()
.registerTypeAdapterFactory(new AutosaveAdapter())
.create();
System.out.println(gson.toJson(autosave));
}
Комментарии:
1. Вы заметили, что результат отличается от того, что вы задали в своем вопросе, и не соответствует ему?