Вячеславович Фролов, Григорий Вячеславович Фролов в Интернете практическое руководство по созданию Web-приложений с базами данных Издание исправленное УДК 004.7 ББК 32.973.202 Фролов А. В., Фролов Г. ...
-- [ Страница 5 ] --В случае успеха функция TRUE, а при ошибке Ч значе ние FALSE. Код ошибки можно получить посредством функции что после данных функция WriteClient записывает в пе ременную, адрес которой был ей передан через параметр IpdwBytes, количество успешно байт данных. В отличие от ReadClient, функция WriteClient посылает данные за один прием, поэтому нет необходимости вызы вать ее в цикле. Если же эта функция смогла передать только часть данных, то это означает, что произошла ошибка.
Функция Прототип функции ServerSupportFuncti on, определенный в структуре типа приведен ниже:
BOOL (WINAPI hConn, DWORD LPVOID LPDWORD IpdwSize, LPDWORD 320 Базы данных в Интернете. Практическое руководство Через параметр передается идентифи катор канала, через поле структуры Параметр позволит задать из нескольких кодов запроса, определяющих операцию, выполняемую этой Через параметр передается размер буфера, который при выполнении операции. Размер этого буфера должен быть записан в перемен ной типа DWORD, адрес которой передается через параметр После выпол нения операции передачи данных в эту переменную будет записан размер успеш но переданного данных.
Параметр IpdwDataType для указания дополнительной строки заголовка или дополнительных данных, которые будут добавлены к заголовку, удаленному Если для параметра IpdwDataType указать значение NULL (что допустимо), к заголовку будут добавлены символы конца строки Какие операции допустимо при помощи функции ServerSupport Function?
Ниже мы привели список возможных значений параметра dwHSERRequest, оп ределяющего код выполняемой операции.
Эта операция для пересылки удаленному пользователю стан дартного заголовка HTTP. Если надо добавить другие следует вос пользоваться параметром IpdwDataType. В качестве дополнительного заголов ка Вы можете указать любую строку, закрытую символами конца строки и двоичным нулем.
Если Ваше расширение ISAPI динамически формирует документ HTML и отправляет его пользователю, то ей не нужно вызывать функцию WriteClient.
Все необходимые для этого действия можно сделать средствами одной толь ко функции Ниже мы показали фрагмент в ко тором эта функция используется для посылки документа HTML, ленного заранее в буфере CHAR from ISAPI strcat(szBuff, NULL, NULL, Заметим, что функция ServerSupportFunction не позволяет посылать двоичные данные. Для отправки двоичных данных Вы обязательно должны применить функцию WriteCl ient.
Глава 7. Расширения CG! и 1SAPI сервера Web Используя операцию расширение ISAPI может послать удаленному пользователю данные, хранящиеся по определенному адресу URL, как будто бы эти данные были непосредственно пользова телем по этому адресу URL. Это удобно для отправки либо динамически со зданных данных, либо предварительно подготовленных данных.
Адрес URL должен быть указан в виде текстовой строки, двоичным через Размер строки задают в параметре IpdwSize.
Что же касается параметра то выполнении данной опера ции этот параметр игнорируется.
Отправка сообщения с номером 302 (URL Redirect). Адрес URL указывает ся аналогично тому, как это делается выполнении операции Х Преобразование логического адреса URL в физический. Адрес логического пути передается через параметр IpvBuffer. По этому же адресу записывает ся результат преобразования. Размер буфера при вызове функции задается, как обычно, с помощью параметра IpdwSize.
После выполнения преобразования в переменную типа DWORD, адрес которой указан параметром IpdwSize, будет записана длина строки результата преоб разования.
В том случае, когда расширение ISAPI оставляет канал открытым для выпол длительной обработки данных, этой командой сообщить серве ру о завершении обработки. Все параметры функции при указании этой команды игнорируются.
Приложение ISHELLO В качестве нашего первого расширения 1SAPI мы предлагаем приложение ISHELLO, выполняющее простейшие функции.
Вызов расширения ishello.dll выполняется из формы, исходный текст кото рой приведен в листинге 7-9.
Листинг 7-9 Вы найдете в файле на прилагаемом к книге компакт-диске.
Расширение вызывается в параметре ACTION тега аналогично тому, как это делается для программ CGI:
После вызова наше динамически создает на рис. 7-7.
Базы данных в Практическое Hello from Extension!
POST D image fe-xbrtmap, 5.0. NT, deflate I Local Рис. 7-7. Документ HTML, динамически расширением В части этого отображается содержимое некоторых полей структуры а в нижней Ч содержимое переменной ALL_HTTP, полученное с помощью функции GetServerVariable.
Исходный текст расширения ishello.dll представлен в листинге 7-10.
Листинг 7-10 Вы найдете в файле на прилагаемом к кни ге компакт-диске.
Наряду с обычным для приложений Windows файлом мы в исходный текст файл в котором определены все необходи мые константы, структуры данных и прототипы функций:
ffinclude Этот файл поставляется в Microsoft Visual C++.
В определена Ч ее мы уже рас сматривали ранее. Она записывает ISAPI и текстовую стро ку описания расширения в поля структуры типа HSE_VERSION_INFO с именами и соответственно. Адрес структуры передается функции GetExtensionVersion параметр.
Функция обращается к буферу для подготовки динамически создаваемого документа HTML, который будет послан удаленно му в результате работы В качестве вспомо гательного буфера применяется буфер CHAR CHAR Глава 7. CGI и ISAPI Web Прежде всего мы в нулевое значение:
0;
Потом в это поле мы результат выполнения команды.
Далее в буфер szBuff копируется заголовок HTTP и начальный фрагмент документа HTML, для чего используется функция "Content-Type:
ISAPI from ISAPI После этого к буферу szBuff с функции strcat добавляются дру гие строки документа. Например, разделительная линия:
После первой разделительной линии в документ вставляются несколько строк со значениями некоторых полей структуры типа В фрагменте кода показана строка версии интерфейса ISAPI:
Version:
Далее в документ выводятся строка с названием метода данных (иоле строка параметров запуска расширения ISAPI (поле физический путь к программному файлу библиотеки DLL расши рения (поле полный размер данных, которые нужно про читать (поле а также тип данных (поле st После этого в документ снова добавляется разделительная линия и отобра жается переменных сервера с префиксом имени HTTP, для используется рассмотренная ранее функция = 4096;
(см. стр.) 324 Базы данных в Практическое В завершение в документ записывается финальная таким образом документ отправляется посетителю серве ра функцией как это показано NULL, NULL, { return = 200;
return HSE_STATUS_SUCCESS;
Если при пересылке данных ошибка, завершает свою работу с кодом В случае успеха в ноле состояния записывается код 200. этим расширение завершает свою рабо ту с кодом HSE_STATUS_SUCCESS.
Создавая проект расширения ISAPI, Вы должны файл опреде ления модуля для соответствующей библиотеки DLL (листинг 7-И).
Листинг хранится в файле на прилагаемом к кни ге В разделе EXORT этого файла нужно имена Version и LIBRARY DESCRIPTION ISAPI EXPORTS HttpExtensionProc Вызов функций ODBC из ISAPI Ранее мы рассказывали, как обращаться к базе данных из программы CGI с при менением объектного ADO. В этом разделе мы приведем исходные тексты расширения ISAPI, которое тоже работает с базой данных, но с приме программного интерфейса ODBC.
Для этого приложения (с мы использу ем форму, показанную на 7-8.
С этой формы нашего магазина сможет просмотреть свои права. Для этого ему придется ввести в ней свой идентифи катор и пароль, а затем щелкнуть кнопку Submit.
Расширение ISFORM обращается к базе данных BookStore, запуская на вы полнение хранимую процедуру Если пользователь зарегистриро ван в ISFORM отправляет ему динамически со зданный документ HTML, в котором отображается идентификатор пользовате ля, его пароль и права, из этой таблицы (рис. 7-9).
Глава 7. CGI и ISAP1 сервера Web Book. < E Book Просмотр прав сотрудника Пароль Рис. Форма ввода идентификатора и пароля 3 - Ь сотрудника User: frolw word.
Рис. 7-9. Перечень прав сотрудника магазина, извлеченный из данных Похожие действия выполняла консольная программа рас смотренная нами в главе. Именно эта программа и была в основу расширения А опишем исходные тексты ISFORM.
Исходный текст документа HTML, предназначенного для запуска этого рас ширения, Вы найдете в листинге Листинг 7-12 хранится в файле на прилагаемом к книге компакт-диске.
В этом документе имеется ссылающаяся на файл расши рения isform.dll:
После щелчка кнопки Вход управление передается странице с именем Book StoreLogin.asp, указанным в параметре ACTION тега
Листинг 8-2 Вы найдете в файле на прилагаемом к книге Глава 8. Создание серверных элементов управления AcliveX строка в файле задаст язык серверного сценария JScript:
LANGUAGE = "JScript" Далее в расположен фрагмент серверного сценария, показанный ниже:
var var culogin = = sPassword);
Здесь мы вначале извлекаем параметры с именами и формой, и сохраняем эти параметры в переменных и sPassword соответ Далее с помощью метода встроенного объекта ASP с именем мы объект с идентификатором BookStore.BookStoreLogin. Это тот самый идентификатор, мы определяли при создании проекта в панели, на рис. 8-5.
Объект будет записан в culogin, при помощи которой сценарий обращается к свойствам и методам объекта. Строкой ниже мы читаем свойство передавая ему в качестве параметров идентификатор посетителя и его пароль.
Значение, из свойства, в Далее эта переменная используется при формировании текста докумен та HTML, создаваемого сценарием:
ввели (идентификатор: пароль) - sResult Определения методов элемента Исходный текст метода CheckResult, а также двух других созданных мастером проекта, находится в файле BookStoreLogin.cpp (листинг 8-3).
Листинг 8-3 Вы найдете в файле на прилагаемом к книге компакт-диске.
Рассмотрим его содержимое.
Помимо файла stdafx.h мастер проекта включает в файл BookStoreLogin.cpp файлы и tfinclude Первый из них создается автоматически и содержит определения интерфей сов. Вам не нужно его редактировать, так как это сделает мастер проекта при добавлении новых методов и свойств.
Второй файл содержит определение класса CBookStoreLogin, который пред ставляет собой класс нашего объекта. Опять же, при добавлении в оп ределение этого класса новых полей мастер проекта произведет все изменения в файле автоматически.
342 Базы данных в Интернете. Практическое Методы OnStartPage и генерируются автоматически, если при со здании проекта отметить на вкладке ASP (рис. 8-7).
Когда посетитель страницу ASP, управление получаст метод OnStartPage. Ему передается на интерфейс с помощью кото рого получит на нужные для связи нашего элемента со встроенными элементами ASP:
pUnk) I Вначале метод OnStartPage получает указатель на интерфейс Context:
= (void Далее, пользуясь этим метод извлекает указатели на объекты Request, Response, и Application:
= = = = = Метод OnEndPage освобождает полученные указатели при завершении обра ботки серверного расположенного на странице:
Кроме методов и OnEndPage в файле находится определение созданного нами метода STDMETHODIMP BSTR *bsName, BSTR return S_OK;
Автоматическая обработка кредитных карточек Создавая Интернет-магазин, Вы должны продумать способ оплаты товара. Наи более современный способ оплаты Ч с кредитных карточек. Мы уже рассказывали о том, как организовать такую оплату с выполняющих обработку кредиток через Как Вам известно, такие компании предоставляют всем желающим интер фейс в виде библиотеки DLL или автономной программы. Модуль интерфейса Глава 8. серверных ActiveX необходимо на Web Вашего магазина, причем вызов этого модуля должен выполняться из программного обеспечения магазина.
Если магазин создан с применением технологии ASP, нужно придумать способ вызова интерфейсного модуля из серверных сценариев, написанных на или VBScript.
В этом разделе мы расскажем о том, как создать управ ления ActiveX, вызывающий функции из библиотеки имитирующей часть интерфейса обработки карточек.
Библиотека для имитации интерфейса демонстрационный интерфейс обработки кредитных карточек состоит все го из одной функции с именем nSendPayData. Ее задача Ч отправить информа цию о платеже на сервер компании. Напомним, что при созда нии реального магазина Вы интерфейсный модуль от процессинговой компании.
Прототип функции f nSendPayData показан ниже:
extern "С" int LPSTR DWORD LPSTR szSuccessURL, LPSTR LPSTR Так как предполагается, что мы вызываем из программы, написан на C++, для отключения механизма функции (name используется определение extern Чтобы функция fnSendPayData попала в список экспортируемых функций, определим ее как Это позволит нам не создавать def-файл определения модуля библиотеки DLL.
При вызове функции необходимо передать шесть параметров.
Через первые два параметра szAmount и передается величина суммы и название валюты. И тот, и другой параметр задается виде текстовой строки.
Третий dwMerchantID Ч идентификатор покупателя, назначенный ему при регистрации и зарегистрированный в процессинговой компании. По этому идентификатору компания сможет определить, кто выполняет платеж.
Через последние три интерфейсный модуль серверу ма газина адреса URL-страниц, на которые попадает посетитель в зависимости от результата выполнения платежа. Если результат успешный, посетитель попада ет на страницу, адрес которой задан параметром szSuccessURL, если нет Ч па стра ницу с адресом szErrorURL, а если при выполнении операции появилась допол нительная информация Ч на страницу с адресом Функция код выполнения Если этот код нулю, операция выполнена успешно, а если нет, то это означает, что ошибки.
Рассмотрим действия, выполняемые функцией Ее исходный текст Вы найдете в листинге 8-4.
Листинг 8-4 хранится в файле на прилагаемом к книге компакт-диске.
Прежде всего эта функция проверяет идентификатор покупателя:
l= return 1;
344 Базы данных в Интернете. Практическое руководство Мы разрешаем выполнение платежа только посетителя с ром 12345. При ошибке значение 1. компания этот идентификатор своей базе данных.
Далее функция убеждается, что параметры szAmount и не нулевых значений:
== 0 strlen(szCurrency) == 0) return 2;
В случае функция возвращает значение 2.
Если указаны правильно, функция fnSendPayData имена файлов по хранящимся в параметрах szSuccessURL, szErrorURL и szNoyificationURL:
NULL) != NULL) NULL) Далее функция возвращает нулевой значение в качестве признака го завершения своей работы.
Помимо функции fnSendPayData в исходном тексте нашей библиотеки DLL определена стандартная функция BOOL APIENTRY DllMain(HANDLE hModule, LPVOID { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH:
case case case DLL_PROCESS_DETACH;
break;
!
return TRUE;
Она вызывается, когда или поток обращается к библиотеке. Эта функция была создана мастером Microsoft Visual C++ и не выполняет никаких Тестовая программа для вызова имитатора интерфейса Прежде чем только что описанный модуль из серверного сценария ASP, его тестирование. Для этого мы подготовили небольшую кон программу, исходный текст которой Вы найдете в листинге 8-5.
Листинг 8-5 хранится в файле на прилагаемом к книге компакт-диске.
Глава 8. Создание серверных элементов управления ActiveX В области глобальных переменных этой программы мы подготовили ление типа (* DLLFN)(LPSTR LPSTR DWORD LPSTR szErrorURL, LPSTR Как этот тип представляет собой указатель на fnSend PayData, описанную ранее.
Тестовая программа функцию предварительно вы полняя динамическую загрузку библиотеки DLL с именем face.dll.
Библиотека DLL функцией LoadLibrary, как это показано ниже:
HINSTANCE = Идентификатор загруженной библиотеки сохраняется в локальной перемен ной hCreditCardlnterfaceDLL.
Если загрузка прошла успешно, тестовая программа вызывает функцию предварительно получив на нее указатель с помощью функции DLLFN fn;
char char != NULL) { fn = (DLLFN)GetProcAddress( != NULL) int = 12345, szSuccessURL, szErrorURL, szNoyificationURL);
Здесь мы передаем функции сумму 123, название валюты Ч иденти фикатор покупателя 12345. Адреса функция запишет в переменные szErrorURL и szNoyificationURL.
Убедившись с тестовой программы и отладчика, что интерфейсная библиотека DLL работает мы переходим к серверного эле мента ActiveX, доступного из страниц ASP и предназначенного для вызова f nSendPayData, Элемент В начале этой главы мы подробно рассмотрели создания серверного элемента ActiveX с применением библиотеки шаблонов ATL. Поэто му сейчас мы не будем вдаваться в детали.
346 данных в Интернете. Практическое руководство Нам создать модуль уп равления должен быть как Исходный текст главного модуля управления, созданный мастером и дополненный Вы найдете в листинге 8-6.
Листинг хранится в файле на мом к книге компакт-диске.
Рассмотрим определения свойств и добавленных нами к объекту CreditCard.
Для свойства Amount, предназначенного для хранения суммы денег, мы пре дусмотрели две функции с именами и < return STDMETHODIMP newVal) return S_OK;
Обе эти функции обращаются полю типа CComBSTR:
CComBSTR Мы добавили эту переменную в класс пользуясь мастером класса.
Функция записывает в поле значение, полученное через параметр newVal.
Что же касается функции то она извлекает значение поля и возвращает его, вызывая метод Сору.
Аналогичным образом устроены функции для работы со свойствами Currency, и Для них в классе CreditCard мы опре делили следующие поля:
CComBSTR CComBSTR CComBSTR Функции для работы со MerchantID, хранящим численное значе ние, определены так:
STDMETHODIMP { return STDMETHODIMP newVal) return Глава 8. серверных управления ActiveX Эти функции к полю типа long.
Теперь мы займемся методом SendPayData, для на шей библиотеки DLL, имитирующей интерфейс Так же как и в тестовой программе, мы определили тип DLLFN, необходимый для вызова функции через (* DLLFN)(LPSTR LPSTR szCurrency, DWORD szSuccessURL, LPSTR LPSTR В самом начале метода SendPayData, эту функцию, мы распо макрокоманду необходимую для работы с макрокоман дами перекодировки OLE2A и A20LE:
I В области локальных переменных метода SendPayData мы определили пере менную для хранения идентификатора библиотека переменную для хранения указатель на функцию с именем три массива для хранения адресов URL с именами szSuccessURL, s zEr r or URL и а также рабочую переменную типа HINSTANCE DLLFN char char bstrTemp;
В начале своей работы метод SendPayData загружает интерфейсную библио теку DLL из файла и получает указатель на функцию fnSendPayData:
hCreditCardlnterfaceDLL = != NULL) fn = :
Если библиотека загрузилась, а указатель получен без ошибок и равен NULL, метод преобразует значения из полей и в текстовые строки ANSI:
= = OLE2A(m_Currency);
Соответствующие указатели и pszCurrency Вы должны определить в классе CreditCard:
char* pszCurrency;
char* pszAmount;
Базы данных в Интернете. Практическое Теперь можно вызывать f m_Result = Ее код мы записываем в поле определенное в классе как long.
Если функции без ошибок, метод иден тификатор библиотеки DLL, а затем преобразует полученные строки адресов записывая их в соответствующие поля класса CreditCard:
= = При ошибке в записывается значение -1:
= -1;
Сценарий определяет результат вызова с свойства Result, доступного только для чтения. Для этого свойства мы подготовили только функцию с именем return S_OK;
Вызов элемента управления CreditCard Для вызова элемента управления CreditCard мы подготовили документ HTML с формой, позволяющей идентификатор платежа, сумму и выбрать валюту (рис. 8-12).
3 Х Введите сведения о платеже Идентифйкатср Валюта I Рис. 8-12. Форма для вызова элемента управления CreditCard Полный исходный текст этого документа расположен в листинге 8-7.
Листинг 8-7 Вы найдете в файле на прилагаемом к книге компакт-диске.
Глава 8. Создание серверных элементов управления ActiveX Этот документ содержит форму, ссылающуюся па страницу ASP с именем dopay.asp: