Освоение Ajax: Часть 11. JSON на стороне сервера

Применение JSON на стороне сервера для получения запросов и создания ответов

В предыдущей статье мы занимались изучением преобразования объектов JavaScript в JSON-представление. Формат JSON удобно использовать для передачи (и приёма) данных, полученных из объектов или даже из массивов объектов JavaScript. В данной статье, завершающей эту серию, мы рассмотрим работу с информацией, отправленной на сервер в виде JSON-текста, а также использование этого формата для создания ответа клиенту

Бретт МакЛафлин, автор и редактор, O'Reilly Media, Inc.

Бретт МакЛафлин (Brett McLaughlin) работает с компьютерами со времен Logo (помните маленький треугольник?). За последние несколько лет он стал одним из наиболее известных авторов и программистов сообщества по технологиям Java и XML. Он работал в Nextel Communications над реализацией сложных корпоративных систем, в Lutris Technologies - фактически над созданием серверов приложений, - а с недавнего времени - в O'Reilly Media, Inc., где продолжает писать и редактировать важные и содержательные книги. Его готовящаяся книга "Head Rush Ajax" продолжает отмеченный наградами инновационный подход "Вперед головой" применительно к изучению Ajax. Его недавняя книга Java 1.5 Tiger: Заметки разработчика является первой доступной книгой по новейшей версии технологии Java, а его классическая книга Java и XML остается одной из наиболее авторитетных работ по применению технологий XML в языке Java.



01.10.2008

Настоящая ценность JSON

В предыдущей статье этой серии мы говорили о том, что JSON удобен как формат данных для Ajax-приложений, потому что позволяет быстро конвертировать JavaScript-объекты в строковые значения и наоборот. Так как Ajax-приложения лучше всего приспособлены для отправления и получения обычного текста, то почти всегда предпочтительнее использовать тот API, который умеет его генерировать; JSON же помимо этой возможности позволяет также работать с родными объектами JavaScript и не беспокоиться о том, как эти объекты будут выглядеть в тексте.

Ресурсный центр Ajax на developerWorks
Обратитесь к Ресурсному центру Ajax– универсальному источнику информации об Ajax-программировании, где можно найти статьи, обучающие руководства, форумы, блоги, wiki-материалы, информацию о событиях и новости. Если что-то происходит, то там есть об этом информация.

XML обладает теми же преимуществами текстового формата, что и JSON, однако API для преобразования JavaScript-объектов в XML (а таковые существуют, и не в единственном числе) не так хорошо проработаны по сравнению с программным интерфейсом JSON; создавая и изменяя объекты, вам иногда самим придётся заботиться о том, чтобы выбранный API смог нормально работать с этими объектами. С JSON всё проще: он обрабатывает практически все мыслимые типы объектов и просто возвращает вам данные в приятном JSON-представлении.

Итак, самая главная ценность JSON состоит в том, что он позволяет работать с JavaScript как с JavaScript, а не как с языком форматирования данных. Так что вы можете применять в своём коде все наработанные навыки по работе с JavaScript-объектами, не заботясь о том, как эти объекты будут преобразованы в текст. Вы лишь вызываете в конце простой JSON-метод:

String myObjectInJSON = myObject.toJSONString();

и получаете текст, который можно отправлять на сервер.


Доставка JSON на сервер

В отправке данных JSON на сервер нет ничего особо сложного, но это важный момент, и у вас есть ряд возможностей для выбора. Однако если вы остановите свой выбор на JSON, то дальнейшие решения принимать будет гораздо проще, так как выбор значительно сузится, и вам не придётся сильно напрягаться по этому поводу. В конце концов, вам просто надо доставить JSON-строку на сервер, причём желательно максимально быстро и просто.

Отправление JSON в парах «имя/значение» методом GET

Самый простой способ доставить JSON-данные на сервер – это преобразовать их в текст и послать его как значение пары «имя/значение». Помните, JSON-отформатированные данные – это всего лишь один довольно большой объект, который выглядит приблизительно так, как показано в листинге 1:

Листинг 1. Простой JavaScript-объект в JSON-формате
var people =  { "programmers": [    { "firstName": "Brett", "lastName":"McLaughlin",
"email": "brett@newInstance.com" },    { "firstName": "Jason", "lastName":"Hunter",
"email": "jason@servlets.com" },    { "firstName": "Elliotte", "lastName":"Harold",
"email": "elharo@macfaq.com" }   ],  "authors": [    { "firstName": "Isaac", 
"lastName": "Asimov", "genre": "science fiction" },    { "firstName": "Tad", 
"lastName": "Williams", "genre": "fantasy" },    { "firstName": "Frank", 
"lastName": "Peretti", "genre": "christian fiction" }   ],  "musicians": [    
{ "firstName": "Eric", "lastName": "Clapton", "instrument": "guitar" },   
{ "firstName": "Sergei", "lastName": "Rachmaninoff", "instrument": "piano" }   ]  }

Итак, этот текст можно отправить серверному скрипту внутри пары «имя/значение», например, так:

var url = "organizePeople.php?people=" + people.toJSONString();
xmlHttp.open("GET", url, true);
xmlHttp.onreadystatechange = updatePage;
xmlHttp.send(null);

Вроде бы всё здесь хорошо, но на самом деле есть одна загвоздка: в нашей JSON-строке с данными присутствуют пробелы и другие символы, которые Web-браузер может попытаться интерпретировать. Чтобы эти символы не вызвали проблем на сервере (и не сорвали бы передачу данных) следует добавить в код JavaScript-функцию escape(). Вот так:

var url = "organizePeople.php?people=" + escape(people.toJSONString());
request.open("GET", url, true);
request.onreadystatechange = updatePage;
request.send(null);

Эта функция обрабатывает пробелы, слеши и всё остальное, что может сбить с толку браузер. Она конвертирует их в «безопасные» в этом смысле символы (например, пробел преобразуется в escape-последовательность %20, которую браузеры уже не воспринимают как пробел, а просто без изменений передают на сервер). Затем уже сервер выполнит обратное преобразование (обычно автоматически), и мы получим строку в том виде, в каком она была до передачи.

У этого подхода есть два недостатка:

  • Во-первых, мы отправляем данные, размер которых потенциально может быть очень большим, посредством GET-запроса, имеющего ограничение на длину URL-строки. Максимально допустимый размер строки очень велик, но мы никогда не знаем, насколько длинную строку получим после преобразования объекта в текст, особенно если этот объект достаточно сложен.
  • Во-вторых, мы отправляем данные через сеть открытым текстом – то есть самым небезопасным из всех мыслимых методов передачи данных.

Для ясности замечу, что оба эти недостатка больше связаны с ограничениями GET-запросов, чем со спецификой JSON. Однако если вы отправляете на сервер больше чем просто фамилию или имя пользователя или результат его выбора в форме на вашем сайте, то эти недостатки могут изрядно подпортить вам жизнь. Если вы начинаете работать с данными, которые могут быть хоть сколько-нибудь конфиденциальными или обладать большим размером, вам определённо следует обратить своё внимание на POST-запросы.

Передача JSON-данных методом POST

Если вы решили использовать для отправки JSON-данных на сервер метод POST вместо GET, то больших изменений в код вносить не придётся. Вот всё, что нужно сделать:

var url = "organizePeople.php?timeStamp=" + new Date().getTime();
request.open("POST", url, true);
request.onreadystatechange = updatePage;
request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
request.send(people.toJSONString());

Большая часть этого кода должна быть вам знакома по статье "Освоение Ajax, часть 3: в которой обсуждалось создание POST-запросов. Здесь мы открываем запрос, используя POST вместо GET, и устанавливаем соответствующий заголовок «Content-Type», указывающий на тип ожидаемых данных. В данном случае он будет выглядеть так: application/x-www-form-urlencoded, давая понять серверу, что мы передаём просто текстовые данные, которые он в принципе мог бы получить и из обычной HTML-формы.

Ещё одним небольшим изменением в коде является добавление к URL текущего времени. Это сделано для того, чтобы предотвратить кэширование запросов и обеспечить их создание и отправку при каждом вызове метода; строки URL каждый раз будут немного различаться благодаря изменению временной метки. Это часто используемый приём, гарантирующий, что POST-запрос будет действительно каждый раз генерироваться заново и Web-браузер не попытается кэшировать ответы от сервера.

JSON – это просто текст

При использовании GET и POST-запросов очень важно, что JSON - это, в конце концов, обычный текст. С ним можно легко работать и передавать серверу, так как он не требует никакого специального кодирования. Текстовые данные можно обработать любым серверным скриптом. Если бы JSON был двоичным форматом или каким-нибудь хитро закодированным текстом, всё было бы не так просто. Итак, JSON – это обычные текстовые данные, которые скрипт в принципе мог бы получить и при подтверждении HTML-формы (как мы видели, когда речь шла о заголовке «Content-Type» в POST-запросах), так что вам не нужно сильно заморачиваться по поводу отправки его на сервер.


Интерпретация JSON на сервере

Как только вы написали свой клиентский JavaScript-код, позволяющий пользователям взаимодействовать с вашими Web-страницами и формами, и получили информацию, которую надо отправить на обработку серверной программе, главным действующим лицом в вашем приложении (и, вероятно, во всем том, что мы называем "Ajax-приложениями", предполагая, что вызов серверного скрипта выполняется асинхронно) становится сервер. И здесь выбор, который вы сделали на стороне клиента, решив использовать JavaScript-объекты и JSON-данные, должен совпасть с соответствующим решением на стороне сервера, где выбирается API для декодирования JSON-данных.

Два этапа внедрения JSON на сервер

Работа с JSON на стороне сервера независимо от используемого серверного языка состоит, по сути, из двух этапов:

  1. Поиск JSON-парсера /инструментария/вспомогательного API для вашего серверного языка
  2. Применение JSON-парсера/инструментария/вспомогательного API для извлечения данных из запроса клиента и преобразования их к виду, понятному серверному скрипту

И это всё, что нужно сделать. Давайте более детально рассмотрим оба этапа.

Поиск JSON-парсера

Лучшим ресурсом для поиска JSON-парсера и других инструментальных программных средств, связанных с JSON, является Web-сайт JSON (см. ссылки в Ресурсах). Помимо обучающей информации о самом формате, на этой странице можно найти ссылки на JSON-инструментарии (tools) и JSON-парсеры под любые платформы: от ASP до Erlang, от Pike до Ruby. Просто найдите там язык, на котором написан ваш скрипт, и закачайте соответствующий инструментарий (toolkit). Скопируйте его себе или обновите с помощью него версию вашего серверного языка или просто установите его (существует много вариантов: всё зависит от того, что вы используете на сервере: C#, PHP, Lisp или что-то другое), главное - чтобы скрипты или программы у вас на сервере могли использовать этот инструментарий.

Например, если вы используете PHP, то достаточно просто обновить его до недавней версии 5.2, в которую по умолчанию включено JSON-расширение. Это, пожалуй, самый простой способ начать работать с JSON, если вы используете PHP. Если же вы используете Java-сервлеты, то проще всего задействовать пакет org.json с сайта json.org. Для этого надо скачать архив json.zip с Web-сайта JSON, скопировать файлы с исходными кодами в компиляционную директорию вашего проекта и соответственно скомпилировать их - и вы уже сможете работать с JSON. Примерно то же самое надо сделать и при использовании других языков; лучший помощник в этом – ваш собственный опыт программирования под соответствующую серверную платформу.

Использование JSON-парсера

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

// Это лишь фрагмент большого серверного PHP-скрипта 
require_once('JSON.php');

$json = new Services_JSON();

// принимаем POST-данные и декодируем их
$value = $json->decode($GLOBALS['HTTP_RAW_POST_DATA']);

// теперь работаем с переменной $value как с обычными «сырыми» данными PHP

С помощью этого кода мы помещаем все данные (массивы, множественные строки, единичные значения - всё, что было в JSON-структуре с данными) в переменную $value, причём в родном PHP-формате.

Если бы мы использовали на сервере Java-сервлеты и пакет org.json, то код выглядел бы приблизительно так:

public void doPost(HttpServletRequest request, HttpServletResponse response)
  throws ServletException, IOException {

  StringBuffer jb = new StringBuffer();
  String line = null;
  try {
    BufferedReader reader = request.getReader();
    while ((line = reader.readLine()) != null)
      jb.append(line);
  } catch (Exception e) { //сообщение об ошибке }

  try {
    JSONObject jsonObject = new JSONObject(jb.toString());
  } catch (ParseException e) {
    // crash and burn
    throw new IOException("Ошибка при  разборе строки запроса");
  }

  // Работаем с данными, используя методы типа:
  // int someInt = jsonObject.getInt("intParamName");
  // String someString = jsonObject.getString("stringParamName");
  // JSONObject nestedObj = jsonObject.getJSONObject("nestedObjName");
  // JSONArray arr = jsonObject.getJSONArray("arrayParamName");
  // и так далее...
}

Более подробную информацию можно найти в документации к пакету org.json (см. ссылки в разделе Ресурсы). (Замечание: если вы хотите более детально изучить org.json или другие программные средства для работы с JSON, напишите мне на e-mail и сообщите об этом. Ваши отклики помогают мне решить, о чём следует писать дальше!).


Заключение

Теперь вы уже должны знать техническую сторону использования JSON на сервере. Но в этой и предыдущей статьях мне хотелось не только показать несколько технических аспектов, но и убедить вас в том, что JSON – весьма гибкий и мощный формат данных. Даже если вы не будете использовать его в каждом своём приложении, хороший Ajax- и JavaScript-программист всегда должен иметь под рукой этот полезный инструмент и уметь применить его, когда в том возникнет необходимость.

Мне определённо хотелось бы услышать о вашем собственном опыте работы с JSON и том, какие языки, по вашему мнению, хорошо – или может быть не очень – работают с JSON-данными на стороне сервера. Загляните на страницу группы новостей о Java и XML (ссылки в Ресурсах) и расскажите мне об этом. Наслаждайтесь JSON и всей мощью текстовых форматов данных.

Ресурсы

Научиться

  • Оригинал статьи JSON on the server side (EN).
  • Посмотрите все статьи Серии «Освоение Ajax» (EN). Часть 3 (EN) рассказывает об отправке и получении сложных Ajax запросов и ответов.
  • Самый лучший ресурс для поиска JSON-парсеров и инструментариев – Web-сайт JSON (EN) – виртуальный центр информации обо всём, что связано с JSON.
  • Прочтите JavaDoc для пакета org.json (EN).
  • xml.com (EN). Если вы еще не являетесь опытным XML-программистом, начните с самого лёгкого для понимания online-ресурса об XML.
  • "Ajax для Java-разработчиков: Создание динамических Java-приложенияй" (EN) (Philip McCarthy, developerWorks, сентябрь 2005 г.): взгляните на Ajax с позиции сервера (в Java-ракурсе).
  • "Ajax для Java-разработчиков: Сериализация объектов Java для Ajax" (EN) (Philip McCarthy, developerWorks, октябрь 2005 г.): в этой статье рассказывается, как можно передавать объекты через сеть и как они могут взаимодействовать с Ajax (в Java-ракурсе).
  • "Вызов SOAP Web-сервисов с помощью Ajax" (EN) (James Snell, developerWorks, октябрь 2005 г.): довольно серьёзная статья об интеграции Ajax с существующими Web-сервисами, основанными на SOAP.
  • Домашняя страничка DOM (EN) на World Wide Web Consortium: стартовая точка для изучения всего, что связано с DOM.
  • DOM Level 3 - спецификация ядра (EN): определение ядра Document Object Model как совокупности доступных типов и свойств. Позволит вам использовать DOM в различных языках.
  • Привязки ECMAScript-языков к DOM (EN): очень заинтересует JavaScript-программистов, которые хотят использовать в своём коде DOM.
  • "Ajax: Новый подход к Web-приложениям" (EN) (Jesse James Garrett, Adaptive Path, февраль 2005 г.): прочитайте статью, в которой было придумано название Ajax – рекомендуется к прочтению всем разработчикам, использующим Ajax.
  • Быстрый штурм Ajax (Head Rush Ajax) (EN) (Brett McLaughlin, O'Reilly Media, Inc.): загрузите идеи этой статьи прямо в свой мозг. Стиль Head First («вперёд головой»).
  • Java и XML, второе издание (EN) (Brett McLaughlin, O'Reilly Media, Inc.): Бретт обсуждает преобразования XHTML и XML.
  • JavaScript: Полное руководство (The Definitive Guide) (EN) (David Flanagan, O'Reilly Media, Inc.): изучите подробную инструкцию по работе с JavaScript и динамическими Web-страницами. В следующем издании будут добавлены ещё две статьи по Ajax.
  • «Вперёд с головой» в HTML и CSS & XHTML (EN) (Elizabeth and Eric Freeman, O'Reilly Media, Inc.): (Elizabeth and Eric Freeman, O'Reilly Media, Inc.): узнайте больше о стандартизированных HTML и XHTML, а также о том, как применять CSS к HTML.
  • Страница "XML для новичков": хотите изучить XML, но не знаете, с чего начать? Посетите обновлённый ресурсный центр XML.
  • Ресурсный центр Ajax на developerWorks – это ваш универсальный источник информации обо всём, что связано с Ajax. Просмотрите эти ресурсы и начните разработку Ajax уже сегодня.

Обсудить

Комментарии

developerWorks: Войти

Обязательные поля отмечены звездочкой (*).


Нужен IBM ID?
Забыли Ваш IBM ID?


Забыли Ваш пароль?
Изменить пароль

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Профиль создается, когда вы первый раз заходите в developerWorks. Информация в вашем профиле (имя, страна / регион, название компании) отображается для всех пользователей и будет сопровождать любой опубликованный вами контент пока вы специально не укажите скрыть название вашей компании. Вы можете обновить ваш IBM аккаунт в любое время.

Вся введенная информация защищена.

Выберите имя, которое будет отображаться на экране



При первом входе в developerWorks для Вас будет создан профиль и Вам нужно будет выбрать Отображаемое имя. Оно будет выводиться рядом с контентом, опубликованным Вами в developerWorks.

Отображаемое имя должно иметь длину от 3 символов до 31 символа. Ваше Имя в системе должно быть уникальным. В качестве имени по соображениям приватности нельзя использовать контактный e-mail.

Обязательные поля отмечены звездочкой (*).

(Отображаемое имя должно иметь длину от 3 символов до 31 символа.)

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Вся введенная информация защищена.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=Web-архитектура, XML
ArticleID=342696
ArticleTitle=Освоение Ajax: Часть 11. JSON на стороне сервера
publish-date=10012008