§2.5. Протокольные компоненты
часть 1. TidHTTP и JSON
Часть I. Теория
2.1 Подключение ЯД к Windows
2.2 Создание папки приложения
2.3 Indy и HTTPS
2.4 Скрипач как прокси
2.5 Протокольные компоненты, часть 1. TidHTTP и JSON
2.5 Протокольные компоненты, часть 2. TREST~ и TDataSet
Чтобы работать с REST API у нас имеется множество специальных компонентов. Но в принципе достаточно иметь и не специальные, лишь бы по http(s) отправить параметры и получить текст в виде JSON, парсить который ещё проще, чем XML - у нас для этого есть прекрасный модуль (начиная с XE6) System.JSON с его TJSONObject, TJSONValue и TJSONArray. Так что же выбрать? Будем мы сосать молочко из сосочки или станем глотать молоко прямо из пакета? А если пить из пакета через трубочку?
Давайте попробуем для начала через компоненты HTTP запросить у Яндекс-Диска количество элементов в папке. Дело в том, что ЯД по-умолчанию выдаёт список содержания пачками по 20 штук. Разумеется, мы можем попросить выдать нам не 20, а какое-то другое количество элементов. Например - всё сразу. Но, поскольку ЯД не понимает (или я не знаю как дать ему понять), что такое "всё сразу", ему нужно сказать сколько это будет конкретно. И хорошо бы действительно знать это число, а не заказывать в параметре limit наобум 100-500 элементов.
function TForm2.GetFolderCount(const AFolder: String): Integer; var LAnswer : String; begin Result := 0; // with TIdHTTP.Create do try {$ifdef MSWindows} with ProxyParams do begin ProxyPort := 8888; ProxyServer := '127.0.0.1'; end; {$endif} Request.CustomHeaders.AddValue( 'Authorization', FAuthorization ); LAnswer := Get( 'https://cloud-api.yandex.net/v1/disk/resources?limit=0&path=' + HTTPEncode( AFolder ) ); if ResponseCode <> 200 then Exit; finally Free end; // with TJSONObject.ParseJSONValue( LAnswer ) as TJSONObject do try Result := (( GetValue( '_embedded' ) as TJSONObject ). GetValue( 'total' ) as TJSONNumber ).AsInt; finally Free; end; end; ... // calling of GetFolderCount const LFolder = 'app:/'; begin ShowMessage( Format( '%d record(s) in folder %s',
[GetFolderCount( LFolder ), LFolder] ) ); ...
Рассмотрим некоторые особенности кода, приведённого выше. Он делится на две части. Первая - получение информации от ЯД, вторая - обработка полученного результата. Какие замечания можно сделать по первой части?
Поскольку TIdHTTP мы создаём вручную, а не ищем его в палитре компонентов, то не забываем добавить в uses модуль IdHTTP. Если кто не знает (ну вдруг!), то можно найти компонент в палитре, кинуть на форму, всё сохранить, и удалить его - в uses будет уже всё добавлено. Работу с прокси-сервером мы как раз обсуждали чуть ранее. Думаю, очевидно, что в FAuthorization хранится наш OAuth-токен. А вот что касается HTTPEncode, то для неё следует подключить модуль Web.HTTPApp. Надеюсь, вы заметили, что делая запрос мы указали в параметрах limit=0, чтобы не получать неинтересующий нас на данный момент список файлов внутри папки, а только информацию о ней самой.
Результат запроса выглядит примерно так:
Выделенный на рисунке элемент Items - это массив записей содержимого папки. Естественно, сейчас он пуст. Итак, пора перейти ко второй части кода, где мы вытаскиваем из JSON количество файлов в папке.
Парсинг выглядит довольно просто. Однако, надо понимать следующее: память под объекты выделяется один раз - классовой функцией ParseJSONValue. Метод GetValue возвращает только ссылку на элемент в коллекции. И второе: хотя ввиду неизменности интерфейса ЯД проверять успешность получения элементов структуры особой нужды нет, в общем случае не грех завести переменную для проверки наличия результата GetValue. Имейте в виду особый порядок обработки аппаратных исключений на мобильных платформах.
to be continued...
Часть I. Теория
2.1 Подключение ЯД к Windows
2.2 Создание папки приложения
2.3 Indy и HTTPS
2.4 Скрипач как прокси
2.5 Протокольные компоненты, часть 1. TidHTTP и JSON
2.5 Протокольные компоненты, часть 2. TREST~ и TDataSet
Комментариев нет:
Отправить комментарий