СТАТЬЯ |
10.08.01
|
Создание Web-приложений с помощью C++Builder 5
Наталия Елманова
КомпьютерПресс #2 2001
Статья была опубликована в КомпьютерПресс (www.cpress.ru)
Данная статья посвящена одной из неплохо зарекомендовавших себя технологий создания динамических интерактивных Web-сайтов — разработке CGI- и ISAPI-приложений. Будучи далеко не единственной технологией создания таких Web-сайтов, она тем не менее остается довольно популярной. В данной статье мы рассмотрим примеры создания CGI- и ISAPI-приложений, выполняемых под управлением Microsoft Internet Information Services, с помощью C++Builder 5. О других способах создания динамических Web-сайтов, например разработке ASP-приложений, вы можете прочитать в статье Сергея Трепалина «Создание серверных компонентов для ASP-приложений» на этом же CD-ROM.
Web-приложения (называемые также скриптами) представляют собой исполняемые файлы или библиотеки, выполняемые под управлением Web-сервера. Их назначение — в ответ на запросы пользователя динамически генерировать HTML-страницы, которые будут интерпретироваться Web-браузером.
Применение Интернета в широком смысле означает доступ к ресурсам, содержащимся в Сети. Любой ресурс Интернета однозначно идентифицируется с помощью адреса URL (Uniform Resource Locators), который можно ввести в соответствующем поле браузера либо выбрать, щелкнув мышью на гипертекстовой ссылке Web-страницы или другого документа. Примерами Интернет-ресурсов являются HTML-страницы, документы различных форматов, Java-аплеты, элементы управления ActiveX и другие файлы. Результат выполнения какого-либо приложения, управляемого Web-сервером, также является ресурсом Интернета, и если настройки уровня безопасности браузера позволяют использовать этот ресурс, он также будет интерпретирован браузером. Отметим, что приложения, выполняемые под управлением Web-серверов и являющиеся источником подобных ресурсов, способны обрабатывать параметры, содержащиеся в запросе пользователя, и результат их работы может зависеть от этих параметров.
Создать Web-приложение, динамически генерирующее подобные ресурсы (обычно HTML-документы), можно с помощью практически любого средства разработки — лишь бы оно позволяло создавать приложения для той операционной системы, в которой работает Web-сервер. Однако если вы хотите снизить трудозатраты, связанные с созданием таких приложений, то имеет смысл обратить внимание на средства разработки, позволяющие их минимизировать. С этой точки зрения довольно удачным выбором являются Borland Delphi 5 и Borland C++Builder 5 (редакции Enterprise и Professional), а также Delphi 4 и C++Builder 4 Enterprise, так как эти средства разработки содержат неплохие визуальные инструменты и компоненты для создания подобных приложений.
Рассматриваемые в настоящей статье примеры или их аналоги, если это особо не оговорено, можно создавать с помощью любого из перечисленных выше средств разработки. Сами примеры созданы с помощью C++Builder 5 Enterprise, но, думаю, пользователям Delphi не составит особого труда перенести их код на Object Pascal.
Изучение разработки Web-приложений мы начнем с создания простейшего примера.
Для создания простейшего Web-приложения из главного меню среды разработки C++Builder выберем пункт File | New и в репозитарии объектов выберем пиктограмму Web Server Application (рис. 1).
Далее нужно выбрать тип приложения (исполняемый файл CGI или Win-CGI либо динамически загружаемая библиотека ISAPI/NSAPI DLL, представляющая собой функциональное расширение для Microsoft Internet Information Services или Netscape FastTrack). CGI-скрипт (CGI-Common Gateway Interface), будучи исполняемым файлом, запускается в отдельном процессе, в то время как ISAPI/NSAPI DLL (динамически загружаемая библиотека — выполняется в адресном пространстве Web-сервера. Поэтому ISAPI/NSAPI DLL требуют меньше ресурсов, чем CGI-скрипты. К тому же такие библиотеки после загрузки остаются в памяти сервера, что уменьшает время их отклика на последующие обращения к ним. Однако это мешает их отладке: после внесения в библиотеку каких-либо изменений необходим перезапуск Web-сервера. В связи с этим при разработке Web-приложений нередко сначала создается CGI-скрипт, который затем отлаживается, после чего на основе имеющихся модулей создается ISAPI/NSAPI DLL. Так мы и поступим: выберем опцию CGI Stand-alone executable и создадим Win32-консольное приложение для генерации HTML-документов. В результате получим объект TWebModule, напоминающий обычный модуль данных(рис. 2).
Рассмотрим, как работает Web-приложение. Если Web-сервер получает от браузера запрос, соответствующий спецификации CGI, он инициирует запуск CGI-приложения для его выполнения. Если запрос корректен, CGI-приложение обрабатывает его и генерирует HTML-документ, который отсылается Web-сервером обратно в браузер. Для обмена данными между браузером и сервером используется протокол HTTP (HyperText Transfer Protocol).
Когда Web-приложение получает HTTP-запрос, оно создает объект TWebRequest для представления запроса и объект TWebResponce для представления отклика, отправляемого в браузер пользователя. Затем оба объекта передаются объекту TWebModule (рис. 3).
Объект TWebModule содержит набор объектов TWebActionItems, хранящих информацию о том, как обрабатывать различные пользовательские запросы. Опознав запрос, он выбирает нужный из них и выполняет соответствующий обработчик события OnAction, обрабатывающий запрос и динамически генерирующий ответ, который передается Web-сервером в браузер пользователя.
Для того чтобы приложение было работоспособным, создадим хотя бы один объект TWebActionItem, реализующий отклик на пользовательский запрос. С этой целью из контекстного меню объекта TWebModule надо выбрать пункт Action Editor и нажать кнопку Add в появившейся форме. Далее можно установить свойства PathInfo и Default объекта WebActionItem1. Первое свойство является частью URL (Uniform Resource Locator) — полного описания доступа к ресурсу (рис. 4).
Свойство Default указывает, выполняется ли данный отклик, если параметр PathInfo в пользовательском запросе остался пустым (рис. 5).
Теперь создадим обработчик события OnAction компонента TWebActionItem:
void __fastcall TWebModule1::WebModule1WebActionItem1Action( TObject *Sender, TWebRequest *Request, TWebResponse *Response, bool &Handled) { AnsiString cont = AnsiString("<HTML><BODY><H3>Hello!</H3>"); cont = cont + AnsiString("<BR>"); cont = cont + AnsiString("<H2>Now is ") + TimeToStr(Time()) + AnsiString(" </H2>"); cont = cont + AnsiString("</BODY></HTML>"); Response->Content = cont; }
В этом обработчике события генерируется содержащая текущее время HTML-страница примерно следующего вида (рис. 6):
Сделаем одно небольшое, но важное замечание. Перед компиляцией такого приложения в С++Builder в опциях проекта следует отключить опцию Use dynamic RTL на странице Linker. Кроме того, стоит отключить и опцию Build with runtime packages на странице Packages либо поместить все эти библиотеки в тот же каталог, что и само приложение (рис. 7).
Дело в том, что запустить такое приложение из командной строки можно без проблем, при этом оно обращается к RTL и «пакетам», находящимся за пределами каталогов Web-сервера. Однако запустить его с помощью Web-сервера скорее всего не удастся — все эти файлы окажутся недоступны. В этом случае вместо ожидаемого результата выполнения приложения будет получено сообщение об ошибке примерно следующего вида:
CGI Error
The specified CGI application misbehaved by not returning a complete set of HTTP headers. The headers
it did return are: ...
Отметим, что при создании ISAPI DLL с использованием Delphi 4 или C++Builder 4 в такой библиотеке не должно быть «пакетов» — она обязательно должна состоять из одного файла.
После компиляции приложения можно сохранить полученный исполняемый файл в каталоге, предназначенном для Web-приложений (в случае MS Internet Information Services по умолчанию это каталог C:\Inetpub\scripts). Затем можно обратиться к приложению через Web-браузер, указав URL-приложения. Обратите внимание: внешнему пользователю, обращающемуся к созданному приложению через браузер, не видна (и не должна быть видна) структура каталогов компьютера, содержащего Web-сервер, — вместо этого ему следует вводить их псевдонимы. Такой подход к использованию каталогов Web-сервера необходим для обеспечения безопасности — внешний пользователь ничего не должен знать о файлах и каталогах компьютера, содержащего Web-сервер, кроме того что ему положено.
Запустив приложение, можно нажать кнопку Reload и убедиться, что текст в браузере меняется. Это значит, что страница генерируется динамически (рис. 8).
Из этого CGI-скрипта мы можем создать ISAPI DLL. Для этого следует создать новое Web-приложение в виде ISAPI DLL, удалить из него объект TWebModule, а вместо него добавить другой объект TWebModule из предыдущего проекта.
Создание форм и обработка пользовательского ввода
Отметим, что объект TWebModule существенно облегчает создание CGI-приложений, связанных с обработкой пользовательского ввода (например, в HTML-формах), заключающегося в изменении или добавлении данных. Типичными примерами таких приложений являются анкеты, которые в изобилии встречаются на многих Web-серверах. Дополним наше приложение такой анкетой.
Для отображения в браузере формы ввода данных пользователем создадим еще один компонент TWebActionItem (рис. 9):
Установим свойство Default вновь созданного объекта TWebAction равным True. Теперь добавим в WebModule1 компонент TPageProducer, назначение которого — генерировать HTML-документ на основе заранее заданного шаблона (рис. 10).
Для создания шаблона документа можно воспользоваться любым HTML-редактором, поддерживающим создание форм, например Microsoft FrontPage (рис. 11).
Исходный текст формы, представленной на рис. 11, имеет вид:
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=windows-1251"> <meta name="GENERATOR" content="Microsoft FrontPage 2.0"> <title>Untitled Normal Page</title></head> <body bgcolor="#FFFFFF"> <p> </p> <form method="GET"> <p>What is Your name?<font size="4"> <input type="text" size="20" name="T1"></font></p> <p>What is Your e-mail?<font size="4"> <input type="text" size="20" name="T2"></font></p> <p><font size="4"><input type="submit" name="B1" value="Submit"><input type="reset" name="B2" value="Reset"></font></p> </form> </body> </html>
Созданный документ можно сохранить в виде файла (и указать его имя в качестве свойства HTMLFile компонента TPageProducer). Можно также скопировать HTML-текст в буфер обмена и поместить его в редактор свойства HTMLDoc этого компонента.
Теперь создадим обработчик события OnAction сгенерированного нами компонента TWebActionItem2:
void __fastcall TWebModule1::WebModule1WebActionItem2Action( TObject *Sender, TWebRequest *Request, TWebResponse *Response, bool &Handled) { Response->Content=PageProducer1->Content(); }
Отметим, что в Delphi 5 и C++Builder 5 компонент TWebAction имеет свойство Producer, позволяющее непосредственно указать, какую именно HTML-страницу нужно генерировать при обращении. Это во многих случаях избавляет от необходимости создавать обработчик события OnAction данного компонента.
Сохранив проект, можно снова обратиться к нему с помощью браузера, указав значение PathInfo в URL (рис. 12):
Теперь осталось обработать пользовательский ввод, например, динамически сгенерировав страницу с введенными пользователем значениями. С этой целью добавим еще один компонент — TPageProducer (рис. 13): страницы, содержащей результаты обработки пользовательского ввода
В качестве значения свойства HTMLDoc вновь созданного компонента PageProducer2 введем следующий текст:
<html> <head> <title>Thank You!</title> </head> <body > <p>Dear <#T1>!</p> <p>Thank you for completing this form. We have included your e-mail address <#T2> in our mailing list. You will receive a lot of spam from us!</p> </body> </html>
Данный текст представляет собой шаблон документа. Он содержит специальные тэги, заменяемые в процессе формирования HTML-страницы строками, которые, в свою очередь, могут быть введены пользователем в созданную выше форму. В нашем случае это тэги <#T1> и <#T2>. Они представляют собой имена полей ввода в созданной ранее форме, в чем можно убедиться, просмотрев HTML-текст формы.
Для замены специальных тэгов следует создать обработчик события OnHTMLTag компонента PageProducer2:
void __fastcall TWebModule1::PageProducer2HTMLTag( TObject *Sender, TTag Tag, const AnsiString TagString, TStrings *TagParams, AnsiString &ReplaceText) { ReplaceText = Request->QueryFields->Values[TagString] + Request->ContentFields->Values[TagString]; }
Здесь Request — объект TWebRequest, сгенерированный приложением в результате пользовательского запроса. В свойстве QueryFields (объект TStrings) этого объекта содержатся имена параметров и значения, введенные пользователем, в виде Name=Value (реально они содержатся в переменной окружения QUERY_STRING, созданной Web-сервером, в виде Name1=Value1&Name2=Value2&…). Параметр TagString — строка, содержащаяся в тэге, подлежащем замене. Cвойство Values объекта TStrings используется, если строки, содержащиеся в этом объекте, представимы в виде Name=Value (что и происходит в данном случае).
Отметим, что если в тэге <form>, содержащемся в тексте формы, вместо метода GET указан метод POST, то вместо свойства QueryFields следует использовать свойство ContentField.
Теперь создадим еще один компонент TWebAction (со значением свойства PathInfo, равным /test3) для отображения страницы, сгенерированной с помощью PageProducer2, и добавим еще один обработчик события OnAction:
void __fastcall TWebModule1::WebModule1WebActionItem3Action( TObject *Sender, TWebRequest *Request, TWebResponse *Response, bool &Handled) { Response->Content=PageProducer2->Content(); }
Возникает вопрос: каким образом можно инициировать генерацию этой страницы после нажатия пользователем кнопки Submit в форме ввода? С этой целью следует описать реакцию на ее нажатие в HTML-тексте формы, то есть отредактировать свойство HTMLDoc компонента PageProducer1:
<form method="POST" action="http://mywebserver/scripts/formproc.exe/t3">
В параметре action указывается URL ресурса, предоставляемого при нажатии кнопки Submit. В данном случае это наше приложение со значением PathInfo, равным /test3 (естественно, имя Web-сервера, так же как и другие части URL, может быть другим).
Теперь можно снова скомпилировать и сохранить приложение. Обратившись к нему с помощью браузера и заполнив форму, нажмем на кнопку Submit. В результате получим страницу, сгенерированную динамически на основе введенных в форму данных (рис. 14):
Из этого CGI-скрипта, как и в предыдущем случае, можно создать ISAPI DLL.
Дополнительную информацию Вы можете получить в компании Interface Ltd.
Отправить
ссылку на страницу по e-mail
Обсудить на форуме Inprise/Borland
Interface Ltd. Отправить E-Mail http://www.interface.ru |
|
Ваши замечания и предложения
отправляйте автору По техническим вопросам обращайтесь к вебмастеру Документ опубликован: 10.08.01 |