JSON с классами? - PullRequest
       21

JSON с классами?

5 голосов
/ 13 ноября 2009

Есть ли стандартизированный способ хранить классы в JSON, а затем снова преобразовывать их обратно в классы из строки? Например, у меня может быть массив объектов типа Вопросы. Я хотел бы сериализовать это в JSON и отправить его (например) на страницу JavaScript, которая преобразует строку JSON обратно в объекты. Но тогда он сможет преобразовывать Вопросы в объекты типа Question, используя уже созданный мной конструктор:

function Question(id, title, description){

}

Есть ли стандартизированный способ сделать это? У меня есть несколько идей о том, как это сделать, но изобретать велосипед и так далее.

Edit:

Чтобы прояснить, что я имею в виду под классами: несколько языков могут использовать классы (JAVA, PHP, C #), и они часто будут общаться с JavaScript через JSON. На стороне сервера данные хранятся в экземплярах классов, но при их сериализации они теряются. После десериализации вы получаете структуру объектов, которая не указывает, какой тип объектов у вас есть. JavaScript поддерживает прототип ООП, и вы можете создавать объекты из конструкторов, которые станут typeof этого конструктора, например, вопрос выше. У меня была идея реализовать классы, реализующие интерфейс JSONType с двумя функциями:

public interface JSONType{
  public String jsonEncode();//Returns serialized JSON string
  public static JSONType jsonDecode(String json);
}

Например, класс Question будет реализовывать JSONType, поэтому, когда я сериализую свой массив, он будет вызывать jsonEncode для каждого элемента в этом массиве (он обнаруживает, что он реализует JSONType). Результат будет примерно таким:

[{typeof:"Question", id:0, title:"Some Question", description:"blah blah blah"},
 {typeof:"Question", id:0, title:"Some Question", description:"blah blah blah"},
 {typeof:"Question", id:0, title:"Some Question", description:"blah blah blah"}]

Код javascript затем будет видеть атрибут typeof и будет искать функцию Question, а затем будет вызывать статическую функцию для объекта Question, аналогично интерфейсу выше (да, я понимаю, что здесь есть дыра в безопасности XSS). ). Объект jsonDecode будет возвращать объект типа Question и будет рекурсивно декодировать значения JSON (например, может быть значение комментария, представляющее собой массив комментариев).

Ответы [ 4 ]

6 голосов
/ 13 ноября 2009

Вам придется создать свой собственный сериализатор, который обнаружит Question (и другие классы) и сериализует их как вызовы конструктора вместо нотации объекта JSON. Обратите внимание, что вам понадобится способ сопоставить объект с вызовом конструктора. (Какие свойства исходят из каких параметров?)

Все остальные: под классами он подразумевает функции, используемые в качестве конструкторов; Я предполагаю, что он пытается сохранить прототип.

1 голос
/ 13 ноября 2009

Вы смотрели на JSON.NET ? Он может сериализовать / десериализовать объекты .NET в JS и наоборот. Это зрелый проект, и я очень рекомендую его.

Кроме того, если вы могли бы изменить определение вашей функции 'Вопрос', чтобы она брала один объект со свойствами вместо отдельных аргументов, вы можете сделать что-то вроде этого:

Рабочая демоверсия

 function Question(args)
 {
  this.id = args.id;
  this.text = args.text;
 }

 Question.prototype.alertText = function() { alert(this.text); };

 $(document).ready(
  function()
  {
   var objectList = 
     {
      'list' : [ 
       { 'id' : 1, 'text' : 'text one' }
       ,{ 'id' : 2, 'text' : 'text two' }
       ,{ 'id' : 3, 'text' : 'text three'}
       ],
      'type' : 'Question'
     };


   var functionName = objectList['type'];
   var constructor = window[functionName];
   if(typeof constructor !== 'function')
   {
    alert('Could not find a function named ' + functionName);
    return;
   }

   var list = objectList['list'];
   $.each(list,
    function()
    {
     var question = new constructor(this);
     question.alertText();
    }
   );
  }
 );

В примечании, пожалуйста, добавьте к своим интерфейсам .NET «I», например. это должен быть IJsonType, а не JsonType.

typeof - это ключевое слово, поэтому укажите имя свойства в кавычках, если хотите его использовать.

0 голосов
/ 27 февраля 2013

Это может быть полезно. http://nanodeath.github.com/HydrateJS/ https://github.com/nanodeath/HydrateJS

Используйте hydrate.stringify для сериализации объекта и hydrate.parse для десериализации.

0 голосов
/ 13 ноября 2009

Это очень опасно, но eval может обработать любой текст и выполнить его. http://www.w3schools.com/jsref/jsref_eval.asp

Но НЕ используйте его. Может сделать что-то вроде передачи параметров, которые вы хотите передать в конструктор как объект JSON, и вызвать конструктор вместе с ним ...

function Question({"id" : "val", "title", "mytitle", "description" : "my desc"}){
...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...