Практически ежегодно появляется очередная переработанная или серьезно дополненная версия Delphi — в прошлом году была выпущена уже пятая. Количество книг по программированию в среде Delphi, вышедших у нас за последние три-четыре года, свидетельствует о том, что этот продукт наиболее популярен среди аналогичных средств разработки ПО. Его можно использовать для создания различных программ, в том числе и Web-приложений, процесс разработки которых благодаря применению Web-компонентов и Web-классов значительно упростился.

Кстати, для тех программистов, которые работают на Си и не хотят переходить на Паскаль, но желали бы пользоваться всеми возможностями и преимуществами Delphi, фирма Inprise выпустила инструментальный аналог этого пакета — C++ Builder. Он обладает всеми достоинствами Delphi и обновляется одновременно с ним. Однако пока пакет не вызывает столь же большого интереса, поскольку выбор соответствующего инструментария при работе на Си шире, чем при использовании Паскаля.

Delphi пятой версии существенно отличается от предыдущей. Так, в палитре VCL этого инструментального пакета появилась страница InternetExpress, на которой представлены TWebConnection и TmidasPageProducer. Они подходят для разработки динамических Internet-клиентов с помощью сценариев, написанных на JavaScript, HTML 4 и XML.

Delphi 5.0 поставляется в трех вариантах: Standard, Professional и Enterprise, различающихся назначением и составом дополнительных инструментальных средств. В Standard наличествует лишь базовый набор средств разработки, Professional можно дополнительно оснащать Internet-компонентами из специального пакета WebBroker, а Enterprise включает весь доступный Internet-инструментарий и поддерживает новую технологию Microsoft — ASP (Active Server Pages). Для этого в Enterprise также включен специализированный эксперт, с помощью которого можно создавать активные серверные страницы. Такие решения, поддерживаемые Web-сервером MS IIS (Microsoft Internet Information Server), позволяют создавать динамические Web-узлы. Кроме того, для разработки Web-приложений используются элементы, находящиеся на Internet-странице палитры компонентов. Эта страница в Delphi 5.0 существенно отличается от соответствующей в версии 4.0 и внешне (другие значки), и по наполнению (рис. 1).

Рис. 1

На ней остались лишь те компоненты, которые нужны непосредственно для проектирования Web-приложений. Наряду с пятью невизуальными там имеются ClientSocket и ServerSocket (два первых), а также WebBrowser (последний).

Информацию, касающуюся комплектации и обновления Delphi, можно получить на узлах Inprise.ru (соm), interface.ru, demo.ru и др.

Web-приложения

В качестве клиентских Web-приложений могут быть использованы современные браузеры, среди которых лидируют MS Internet Explorer и Netscape Navigator. Альтернативой является разработка собственной программы с помощью Delphi. Этот путь может показаться более трудоемким и затратным, но в результате зачастую получается такой продукт, который максимально соответствует решаемой задаче.

Если в качестве клиентского приложения все же используется универсальный Web-браузер, то при создании интересных динамических Web-страниц на профессиональном уровне уже не обойтись без программирования хотя бы на элементарном уровне. Тогда придется разрабатывать продукты на уровне CGI- или API-приложений, и инструментарий Delphi 5.0 окажется как раз к месту.

Технология WebBroker

Для проектирования серверных Web-приложений в Delphi разработана специальная технология — WebBroker. С ее помощью можно создавать сложные программы, в том числе и работающие с базами данных как локальными, так и хранящимися на наиболее популярных серверах — InterBase, Oracle, Informix, Sybase, MS SQL. В последнем случае связь серверного приложения с источником данных обеспечивается с помощью одного из двух механизмов — BDE (Borland Data Engine) или ODBC.

Технология WebBroker реализована на основе Web-компонента — TWebModule. Для обеспечения комфортности работы и ускорения процесса проектирования предусмотрены два мастера — Web Server Application и Database Web Application Wizard. Использование TWebModule позволяет создавать программы, которые будут работать под управлением серверов, поддерживающих интерфейсы расширения — ISAPI (Internet Server API, разработанный корпорацией Microsoft), NSAPI (Netscape API, предложенный компанией Netscape), а также CGI и WinCGI.

Особенности каждого из указанных стандартов учитываются в технологии WebBroker. При этом предусматривается выполнение программы непосредственно на сервере. Но Delphi также позволяет создавать приложения типа ActiveX, запускаемых на компьютере клиента. Следует отметить, что каждое Web-приложение может иметь лишь один компонент TWebModule.

ISAPI- и NSAPI-приложения — это библиотеки DLL, которые Web-сервер загружает по запросу клиента, поступающему от браузера через Internet по протоколу TCP/IP. Клиентская информация передается из запроса в dll-файл в структурированном виде и обрабатывается компонентом TISAPIApplication. Каждый поток управляется отдельным запросом. Как только dll-файл загрузится, сервер может отвечать на клиентские запросы внутри основного процесса.

Поскольку обмен информацией между клиентом и Web-приложением происходит в оперативной памяти сервера, то программы на базе ISAPI/NSAPI работают гораздо быстрее, чем приложения на основе CGI/WinCGI. CGI-приложения являются консольными и не отличаются эффективностью, так как каждый раз при поступлении соответствующего запроса от клиента сначала происходит их запуск, а по окончании работы — полное завершение. Поэтому количество клиентов, подключающихся к Web-серверу с CGI-приложениями, ограничено объемом его оперативной памяти и быстродействием.

Однако подобные приложения обладают универсальностью, обусловленной совместимостью с различными платформами, поскольку стандарт CGI был разработан и широко использовался на Unix, а затем был реализован и для других ОС, в том числе для Windows. Данные от клиента, поступающие в командной строке запроса, который организован в этом стандарте, передаются на сервер после обработки компонентом TCGIApplication.

WinCGI — модификация стандарта CGI, рассчитанная на работу под управлением ОС Windows. Программы, разработанные на базе этих двух стандартов, будут работать и на Web-серверах — MS IIS 4.0 или Netscape, поддерживающих стандарты ISAPI и NSAPI соответственно. Несомненное достоинство технологии WebBroker — возможность представления конечного программного продукта в любом из указанных стандартов простой перекомпиляцией исходных текстов, что существенно облегчает работу.

Для разработки серверных Web-приложений в палитре компонентов Delphi 5 программисту предлагается Internet-страница, на которой расположено пять невизуальных Web-компонентов: TWebDispatcher, TPageProducer, TDataSetPageProducer, TDataSetTableProducer и TQueryTableProducer. Шестой невизуальный компонент — TwebModule — автоматически включается в проект при создании Web-приложения с помощью мастера Web Server Application. Он — основа любого серверного Web-приложения, а также служит репозитaрием (своеобразным «контейнером») для остальных невизуальных компонентов, чем напоминает Data-модуль, применяемый для работы с БД при обычном проектировании клиентских приложений.

Чтобы выбрать Web Server Application, следует обратиться к меню File?New?New. После подключения этого мастера открывается подменю, где нужно указать стандарт (ISAPI, NSAPI, CGI или WinCGI), с которым будет работать создаваемое Web-приложение (рис. 2). Это позволит разработать новый проект на основе автоматически определенного Web-модуля. В его единственном окне и будут размещаться Internet-компоненты. Они, как и сам модуль, имеют статус невизуальных, т. е. доступных лишь в режиме проектирования (design-time). Все видимые элементы и компоненты серверного Web-приложения станут отображаться в окне браузера клиента, обращающегося к серверу, а во время разработки, отладки и тестирования Web-программы сам Web-сервер и браузер могут находиться на одном компьютере, выполняющем одновременно функции как клиента, так и сервера.

Рис. 2

Когда разрабатывается ISAPI/ NSAPI-приложение, в заголовок файла проекта добавляется директива library, а в список под директивой uses заносятся необходимые записи. Затем создается сам файл проекта (листинг 1).

Листинг 1

Файл проекта ISAPI/NSAPI-приложения

library IServer;
uses
  WebBroker,
  HTTPApp,
  ISAPIApp,
  main in ?main.pas? {CustomerInfoModule: 
  TDataModule};
{$R *.RES}
exports
  GetExtensionVersion,
  HttpExtensionProc,
  TerminateExtension;
begin
  Application.Initialize;
  Application.CreateForm(TCustomerInfoModule, 
  CustomerInfoModule);
  Application.Run;
end.
Кстати, в Delphi 5.0 при формировании Web-проекта появился новый модуль WebBroker. Поэтому при переходе на нее в готовом (или разрабатываемом) проекте серверного Web-приложения нужно перед его перекомпилированием приписать в ?library? название этого нового модуля в разделе ?uses?. И наоборот, при возврате к версии 4.0 следует (с помощью комментария) убрать это имя.

Классы TWebRequest и TWebResponse

TWebModule предоставляет серверному Web-приложению возможность сформировать ответы на клиентские HTTP-запросы. Обмен между серверным и клиентским приложениями происходит в объектной форме. Запросы представляются в виде объектов в соответствии с выбранными условиями в списке свойств action items. На рис. 3 приведен пример определения списка свойств actions из демонстрационной программы Iserver.dpr, находящейся в каталоге ...Program FilesBorland Delphi5(4)DemosWebServ.

Рис. 3

В модуле HTTPAPP.pas как абстрактные базовые классы объявлены TWebRequest и TWebResponse. Они инкапсулируют протокол HTTP, по которому происходит обмен информацией между Web-сервером и клиентскими браузерами. Класс TWebRequest предоставляет доступ ко всей информации, поступающей от клиентов на Web-сервер через свои свойства и методы. Класс же TWebResponse, наоборот, с помощью своих свойств и методов позволяет переслать клиенту данные в форме ответа на отправленный ранее запрос по протоколу HTTP. Причем данные от Web-сервера можно переслать любым из возможных для протокола HTTP способов.

В действительности взаимодействие между Web-сервером и клиентами обеспечивают классы TISAPIResponse и TISAPIRequest, объявляемые в модуле ISAPIAPP.pas и учитывающие специфику интерфейсов ISAPI и NSAPI. Они являются прямыми потомками абстрактных классов TWebRequest и TWebResponse. Полиморфизм, свойственный Delphi, позволяет организовать их передачу в виде параметров TWebRequest и TWebResponse через обработчик события OnAction в компонент TwebModule (листинг 2).

Листинг 2

Обработчик события OnAction

procedure TWebModule1
.WebModule1WebActionItem1Action(Sender: 
TObject;  Request: TWebRequest; Response: 
TWebResponse;
var Handled: Boolean);
begin
//обработчик события
end;

Свойства класса TISAPIRequest, содержащего информацию запроса от клиентского браузера, позволяют получить разнообразную и достаточно полную информацию о самом клиенте, хотя ряд параметров в передаваемом запросе может быть не определен. Этот класс имеет около 30 ненаследуемых свойств. Так, свойства RemoteHost и RemoteAddr включают Internet-адрес клиентского компьютера. Данные о браузере, установленном на клиентском месте, заключены в свойстве UserAgent. Из свойства Accept можно извлечь список типов графических файлов, с которыми может работать браузер клиента. Свойство Refere содержит URL Web-страницы, где можно получить ссылку на этот Web-сервер, а данные Cookie содержатся только в свойстве Cookie в виде строк. С помощью свойства CookieFields через массивы полей можно сразу же получить доступ к значениям нескольких клиентских рабочих мест.

Подробные данные клиентского URL-запроса можно извлечь из свойства Query. Например, если в URL-запросе ?http://www.TSite.com/art/gallery.dll/ mammals?animal=dog&color=black? часть ?/gallery.dll? представляет собой имя Web-приложения, то свойство Query будет включать animal=dog&color=black. В этом свойстве информация неотделима от URL. Причем Query может включать множественные поля, разделенные знаками логического «И» (&). При передаче параметров через URL они обычно следуют за знаком вопроса (?). Пробелы заменяются плюсом (+), а последний наряду с некоторыми другими передается в кодированном виде: %хх, где хх — шестнадцатеричное представление символа.

Чтобы ознакомиться с функциями, свойствами и методами класса TISAPIRequest, целесообразно провести тестирование. Для этого нужно сформировать HTML-страницу в обработчике события OnAction и отобразить на ней значения всех многообразных свойств класса или хотя бы некоторых наиболее важных (листинг 3).

Листинг 3

Вывод информации о сервере и клиенте

procedure TWebModule1
.WebModule1WebActionItem2Action(Sender: 
TObject;  Request: TWebRequest; Response: 
TWebResponse;
var Handled: Boolean);
begin
  Pg := TstringList.Create;
  Pg.Add(?
?); Pg.Add(??); Pg.Add(??); Pg.Add(??); Pg.Add(??); Pg.Add(??); Pg.Add(?
?); Pg.Add(?Динамическая страница, созданная в Delphi

?); Pg.Add(?как Web-расширение

?); Pg.Add(?Method = ? + Request.Method + ?

?); with Pg do begin Add(?ProtocolVersion = ? + Request .ProtocolVersion + ?

?); Add(?URL = ? + Request.URL + ?

?); Add(?Query = ? + Request.Query + ?

?); Add(?PathInfo = ? + Request.PathInfo + ?

?); Add(?PathTranslated = ? + Request.PathTranslated + ?

?); Add(?Authorization = ? + Request.Authorization + ?

?); Add(?CacheControl = ? + Request.CacheControl + ?

?); Add(?Cookie = ? + Request.Cookie + ?

?); Add(?Accept = ? + Request.Accept + ?

?); Add(?From = ? + Request.From + ?

?); Add(?Host = ? + Request.Host + ?

?); Add(?Referer = ? + Request.Referer + ?

?); Add(?UserAgent = ? + Request.UserAgent + ?

?); Add(?ContentEncoding = ? + Request .ContentEncoding + ?

?); Add(?ContentType = ? + Request.ContentType + ?

?); Add(?ContentLength = ? + IntToStr(Request .ContentLength) + ?

?); Add(?ContentVersion = ? + Request.ContentVersion + ?

?); Add(?Content = ? + Request.Content + ?

?); Add(?Connection = ? + Request.Connection + ?

?); Add(?DerivedFrom = ? + Request.DerivedFrom + ?

?); Add(?Title = ? + Request.Title + ?

?); Add(?RemoteAddr = ? + Request.RemoteAddr + ?

?); Add(?RemoteHost = ? + Request.RemoteHost + ?

?); Add(?ScriptName = ? + Request.ScriptName + ?

?); Add(?ServerPort = ? + IntToStr(Request .ServerPort) + ?

?); end; Pg.Add(?


?); Pg.Add(?

?); Pg.Add(??); Response.Content := Pg.Text; Pg.Free; end;

Эта страница отсылается через Response.Content на клиентский браузер для тестирования системы (рис. 4). Конечно, не нужно отправлять подобную информацию клиенту, пользующемуся услугами Web-сервера, ее целесообразно использовать для подготовки эффективного и даже «интеллектуального» ответа клиенту. В частности, информация о версии и функциональных возможностях браузера позволит выдать клиенту Web-страницу в требующемся виде, например без графических файлов, в том формате, который его браузер не воспринимает. А анализ запросов (например, по свойству Query) позволяет выявить «полезного» и даже «нужного» клиента. Если запомнить его URL-адрес, то при следующем обращении на Web-сервер можно персонально его поприветствовать, сразу открыть ему нужную страницу либо раздел, предоставить доступ к дополнительной информации. Этот же способ помогает регистрировать данные о посетителях на Web-сервере и, если необходимо, избавляться от нежелательных «визитов» и т. п.

Рис. 4

Данные пересылаются клиенту с Web-сервера в форме ответа через свойство Content класса TISAPIResponse. Этот класс имеет 23 свойства, из них 19 — ненаследуемые. В Content должен содержаться HTML-код, отображаемый клиентским браузером в виде Web-страницы. В другом важном свойстве — Version — указывается версия HTTP-протокола. Значение Version берется из ProtocolVersion свойства HTTPRequest. Для получения дополнительной информации по спецификации HTTP-протокола необходимо ознакомиться с соответствующей документацией, имеющейся, например, по адресу http://www.w3.org.

Большое влияние на работу с классом TISAPIResponse оказывают методы. Например, вызвав после установки свойств объекта HTTP-ответа метод SendResponse, можно послать клиенту сообщение еще до окончания действия обработчика OnAction. Метод SendRedirect поможет перенаправить клиента на другой Web-сервер с соответствующим URL. Метод SendStream обеспечивает передачу данных любого типа. Однако перед его вызовом нужно затребовать SendResponse, который формирует заголовок сообщения HTTP-ответа, базирующийся на свойствах объекта TISAPIResponse. Вместо метода SendResponse перед вызовом SendStream нужно установить свойство ContentStream в значении AStream.

Наибольший интерес, пожалуй, представляет использование технологии WebBroker при построении динамических Web-страниц для работы с базами данных. Однако здесь не обойтись без языка HTML, ранее не применявшегося в Delphi. Специальные компоненты TPageProducer, TDataSetPageProducer, TDataSetTableProducer и TQueryTableProducer помогают программисту эффективно решать подобные задачи, которые далеко не всегда тривиальны, что существенно экономит его время и силы.

TPageProducer

Компонент TPageProducer позволяет создавать динамические Web-страницы и манипулировать ими с помощью шаблонов, т. е. клиенту предоставляется нужная HTML-страница в соответствии с определенными условиями, которые анализируются в обработчике события OnHTMLTag. Само это событие будет инициироваться в момент прочтения специального дескриптора, начинающегося со знака #, который включает имя и параметры с соответствующими значениями, например <#TagName Param1=Value1 Param2=Value2 ...>. Имя должно быть допустимым идентификатором языка Паскаль, а параметры с пробелами заключаются в двойные кавычки. В Delphi имеется семь предопределенных дескрипторов.

В TPageProducer предусмотрены свойства — HTMLDoc и HTMLFile. С помощью первого можно определить шаблон, который в дальнейшем будет использоваться для формирования страницы, возвращаемой клиенту при обращении к методу Content (в ответ на запрос). Установив TPageProducer в окне TWebModule и открыв редактор списка строк HTMLDoc, можно построчно набрать там шаблон HTML-страницы. Такой шаблон не будет отличаться от обычной страницы, написанной на стандартном HTML-языке. Метод Content преобразует код, находящийся в свойстве HTMLDoc (где могут присутствовать и ссылки в виде дескрипторов), в окончательную строку в формате HTML. При входе в каждый дескриптор вызывается событие OnHTMLTag, обработчиком которого и выполняется это преобразование (листинг 4).

Листинг 4

Замена дескрипторов в обработчике события OnHTMLTag

procedure TMyModule.ImageHTMLTag(Sender: 
TObject; Tag: TTag;
const TagString: String; TagParams: TStrings;
var ReplaceText: String);
var
  ImageID: integer;
begin
case Tag of
tgImage:
 begin
ImageID := StrToInt(TagParams.Values[?ImageID?])
if ImageTable.FindKey([ImageID]) then
ReplaceText := ???
    else
    ReplaceText := ?(Изображение отсутствует)?
    end;
    tgTable:
    begin
 ReplaceText := DataSetTableProducer1.Content;
      end;
  end;
end;

Предопределенный дескриптор tgImage предназначен для описания изображения, а tgTable — для установки HTML-таблицы. Кроме того, в Delphi 5.0 есть предопределенные теги tgCustom, tgLink, tgImageMap, tgObject и tgEmbed. С помощью tgLink описывается гипертекстовая ссылка, tgObject используется для встраивания ActiveX в HTML-страницу, tgImageMap заменяется картой изображения (контекстно-сенсорными зонами), tgEmbed содержит ссылку на DLL-расширение, совместимое с Netscape, tgCustom присваивается свойству Tag тогда, когда в HTML-тексте встречается неопределенный дескриптор, заменяемый любым значением, которое задает пользователь. Например, если в свойстве HTMLDoc HTML-текста имеется также непредопределенный тег <#DATE>, то Tag будет присвоено значение tgCustom. В обработчике OnHTMLTag этот дескриптор может быть заменен командой, выводящей текущую дату на HTML-страницу.

Установка HTMLDoc не допускает использования альтернативного HTMLFile, которое предусматривает применение внешнего файла для хранения аналогичного шаблона на языке HTML. А такой способ позволяет еще более расширить функциональные возможности Web-приложения путем замены и манипулирования HTML-страницами в нескольких шаблонах без изменения текста основной программы.

TDataSetTableProducer и TQueryTableProducer

Компоненты, находящиеся на странице DataControl и предназначенные для управления данными и для их вывода, в том числе и в табличной форме, не могут быть использованы в Web-приложении. Вместо них можно применить TDataSetTableProducer и TQueryTableProducer, информация для которых берется из TTable и TQuery соответственно, включенные в компонент TWebModule. Причем источники данных и компоненты управления непосредственно связаны между собой, потому и не требуется промежуточного компонента типа TDataSource. Компонент TDataSetTableProducer, аналогичный TDBGrid, позволяет переслать на клиентский браузер отчет в табличной форме в формате HTML. Его можно настроить на отображение любых столбцов выбранного набора данных.

Свойства Header и Footer позволяют вставить текст на HTML и до таблицы, и после нее. С помощью свойств Columns, RowAttributes и TableAttributes можно форматировать строки, столбцы и отдельные ячейки таблицы. В свойстве Dispatcher должен быть указан компонент-диспетчер, предоставляющий доступ к объектам TWebRequest и TWebResponse для получения запросов и передачи ответов.

Рис. 5

Аналогично функционирует и TQueryTableProducer, за исключением режима доступа к данным. Этот компонент помогает сформировать HTML-таблицу на основе параметров, указанных в HTTP-запросе. Если последний основан на методе GET, то параметры определяются свойством QueryFields объекта запроса TWebRequest, а если на методе POST — свойством ContentFields того же объекта. В приведенной демонстрационной программе Iserver.dpr представлен пример использования TPageProducer, TDataSetTableProducer и TQueryTableProducer (рис.5), а результат применения последнего из этих компонентов показан на рис. 6.

Рис. 6

* * *

Окончание в следующем номере.