![](/user_photo/8997_nLds_.jpg)
Хомоненко А.Д., Цыганков В.М., Мальцев М.Г. - Базы данных. Учебник для высших учебных заведений (6-е изд.) - 2009
.pdf16. Интерфейсы программирования Web-приложения |
643 |
Для извлечения данных из объекта Recordset организован цикл, в котором последовательно просматривается каждая строка результирующего набора данных. В теле цикла анализируются ноля из набора данных, соответствующие текущей строке. Для этого используется указатель на текущую строку набора данных. С помощью строки
r e s - > M o v e N e x t ( ) ;
выполняется переход к следующей записи набора данных.
Для выхода из цикла используется переменная ado_EOF, которой присваивают значение логической переменной с помощью метода g e t _ E O F ( & a d o _ E O F ) , принадлежащего объекту R e c o r d s e t . Выход из цикла осуществляется при достижении конца набора данных, то есть при невыполнении следующего условия
a d o _ E O F = = V A R I A N T _ F A L S E
Здесь V A R I A N T _ F A L S E — константа, значение которой функция g e t _ E O F ( ) возвращает при успешном перемещении указателя на следующую запись в наборе данных.
Для извлечения данных текущей записи выполняются следующие действия:
•получение указателя на объект F i e l d s для текущей записи;
•получение указателей на объекты Field для объекта Fields;
•получение данных из объекта Field .
Для получения указателя на объект F i e l d s для текущей записи используется метод объекта R e c o r d s e t
g e t _ F i e l d s ( & a d o F i e l d s )
где a d o F i e l d s — переменная типа A D O F i e l d s .
Для получения указателей на объекты F i e l d используется следующий код:
h r e s _ o k = a d o F i e l d s - > g e t _ l t e m ( C O I e V a r i a n t ( " A u J D " ) , & i d ) ;
h r e s _ o k = a d o F i e l d s - > g e t _ l t e m ( C O I e V a r i a n t ( " a u t h o r " ) , & n a m e ) ;
h r e s _ o k = a d o F i e l d s - > g e t _ l t e m ( C O I e V a r i a n t ( " Y e a r B o m " ) , & y e a r B o r n ) ;
Здесь переменные id, n a m e , y e a r B o r n получают указатели на объекты Field, в которых содержатся данные для соответствующего столбца и текущей записи из набора данных и определены следующим образом:
A D O F i e l d * id = N U L L ;
A D O F i e l d * n a m e = N U L L ;
A D O F i e l d * y e a r B o r n = N U L L ;
Для получения данных из объекта Field используется метод g e t _ V a l u e ( )
объекта Fields:
h r e s _ o k = n a m e - > g e t _ V a l u e ( & s _ n a m e ) ;
h r e s _ o k = y e a r B o r n - > g e t _ V a l u e ( & s _ y e a r B o r n ) ; h r e s _ o k = i d - > g e t _ V a l u e ( & s _ i d ) ;
644 Часть 4. Публикация баз данных в Интернете
Формирование строки таблицы выполняет следующий код:
s 1 = V _ B S T R ( & s _ n a m e ) ;
8 . Р о г т а 1 ( " < Т В Х Т О > % 1 5 с 1 < Я О > < Т О > % 2 5 8 < Я О > < Т О > % 1 0 с 1 < Д О > , , 1 V _14( & s _ i d ) , s 1,V _ I4( & s _ y e a r B o r n ) ) ;
c o u t « ( L P C T S T R ) s « " \ n " ;
Здесь метод F o r m a t ( ) используется для преобразования целочисленных переменных в строковые переменные, а системные функции V _ B S T R ( ) и V J 4 Q используются для приведения типов.
16.2. Интерфейс программирования серверных
приложений |
ISAPI |
Общая характеристика |
интерфейса |
Перспективным направлением развития технологий создания моделей расширения сервера является интерфейс (протокол) программирования серверных приложений ISAPI. Этот интерфейс разработан для преодоления ограничений и недостатков интерфейса CGI. В отличие от общего интерфейса CGI интерфейс ISAPI предусматривает реализацию модулей расширения сервера в виде динамической библиотеки. При этом для обработки каждого
запроса обозревателя к модулю расширения сервера ISAPI не создается отдельный процесс, а для обработки запроса вызываются функции модуля ISAPI и один раз загружаются в память при первом обращении.
Существует несколько вариантов реализации интерфейсов серверных расширений. Наибольшее распространение получили два из них — NSAPI компании Netscape и ISAPI фирмы Microsoft. Из-за ограниченности объема мы рассмотрим возможности интерфейса ISAPI. Приложения, построенные с использованием интерфейса ISAPI, имеют в основе аналогичные принципы взаимодействия с сервером, что и CGI-модули. Отличия этих интерфейсов заключаются в реализации обмена данными между модулем и сервером.
Модули расширения ISAPI, как и модули CGI, получают от сервера данные, которые передает модулю обозреватель, обрабатывают эти данные и динамически формируют НТМ L-документ. Однако вместо чтения содержимого переменных окружения и стандартного потока ввода модуль расширения ISAPI получает данные при помощи предназначенных для этого функций. Аналогично, вместо записи выходных данных в стандартный поток вывода модуль расширения ISAPI вызывает специальные функции.
Модули ISAPI в зависимости от назначения подразделяютя на две группы: обычные модули расширения ISAPI и фильтры ISAPI. Первая группа аналогично, как и CGI-модули расширения сервера, предназначена для динамического формирования НТМ L-документов. Фильтры ISAPI предназначены для
646 Часть 4. Публикация баз данных в Интернете
Функция HttpExtensionProc() выполняет основную работу ISAPI-моду-
ля и используется для обмена данными между ISAPI-модулем и сервером. Функция H t t p E x t e n s i o n P r o c Q имеет следующий прототип:
e x t e r n " С " D W O R D W I N A P I H t t p E x t e n s i o n P r o c ( E X T E N S I O N C O N T R O L J 3 L O C K * р Е С В ) ;
где переменная р Е С В является указателем на управляющую структуру (блок) E X T E N S I O N J D O N T R O L B L O C K , определенную в файле httpext.h следующим образом:
t y p e d e f s t r u c t E X T E N S I O N _ C O N T R O L _ B L O C K { D W O R D c b S i z e ; / / р а з м е р б л о к а в б а й т а х
D W O R D d w V e r s i o n ; / / в е р с и я с п е ц и ф и к а ц и и и н т е р ф е й с а ISAPI H C O N N C o n n I D ; / / и д е н т и ф и к а т о р с о е д и н е н и я
D W O R D d w H t t p S t a t u s C o d e ; / / к о д с о с т о я н и я H T T P
C H A R L p s z L o g D a t a [ H S E _ L O G _ B U F F E R _ L E N ] ; / / т е к с т о в а я с т р о к а , / / с о д е р ж а щ а я д а н н ы е п р о т о к о л и р о в а н и я
L P S T R L p s z M e t h o d ; / / п е р е м е н н а я о к р у ж е н и я R E Q U E S T _ M E T H O D L P S T R L p s z Q u e r y S t r i n g ; / / п е р е м е н н а я о к р у ж е н и я Q U E R Y _ S T R I N G L P S T R L p s z P a t h l n f o ; / / п е р е м е н н а я о к р у ж е н и я P A T H J N F O
LPSTR LpszPathTranslated; / / п е р е м е н н а я о к р у ж е н и я PATH _ TRANSLATED D W O R D cbTotalBytes; / / п о л н ы й р а з м е р данных, полученных от обозревателя D W O R D c b A v a i l a b l e ; / / р а з м е р д о с т у п н о г о б л о к а д а н н ы х
L P B Y T E L p b D a t a ; / / у к а з а т е л ь н а д о с т у п н ы й б л о к д а н н ы х / / р а з м е р о м c b A v a i l a b l e б а й т
L P S T R L p s z C o n t e n t T y p e ; / / т и п п р и н я т ы х д а н н ы х
/ / Ф у н к ц и я GetServerVariable для получения значения п е р е м е н н ы х окружения B O O L ( W I N A P I * G e t S e r v e r V a r l a b l e ) ( H C O N N h C o n n , L P S T R
L p s z V a r l a b l e N a m e , L P V O I D L p v B u f f e r , LP D W O R D L p d w S i z e ) ; / / ф у н к ц и я W r i t e C l i e n t д л я п о с ы л к и д а н н ы х о б з р е в а т е л ю
B O O L ( W I N A P I * W r i t e C l l e n t ) ( H C O N N C o n n I D , L P V O I D B u f f e r , L P D W O R D L p d w B y t e s , D W O R D d w R e s e r v e d ) ;
/ / ф у н к ц и я R e a d C l i e n t д л я п о л у ч е н и я д а н н ы х о т п о с е т и т е л я
B O O L ( W I N A P I * R e a d C l i e n t ) ( H C O N N C o n n I D , L P V O I D L p v B u f f e r , L P D W O R D L p d w S i z e ) ;
/ / С л у ж е б н а я ф у н к ц и я
S e r v e r S u p p o r t F u n c t i o n B O O L ( W I N A P I * S e r v e r S u p p o r t F u n c t i o n ) ( H C O N N h C o n n , D W O R D d w H S E R R e q u e s t , L P V O I D L p v B u f f e r , L P D W O R D
L p d w S i z e , L P D W O R D L p d w D a t a T y p e ) ;
} E X T E N S I O N J D O N T R O L _ B L O C K , * L P E X T E N S I O N _ C O N T R O L _ B L O C K ;
Поясним особенности использования основных полей этой структуры данных.
16. Интерфейсы программирования Web-приложения |
647 |
Поле c b T o t a l B y t e s предназначено для записи суммарного количество байт данных, получаемых от обозревателя. Блок данных размером не более 48 кб считывается сервером автоматически. Эти данные становятся доступны при вызове функции H t t p E x t e n s i o n P r o c ( ) . Но полностью данные дочитываются в цикле при помощи функции ReadClient().
Поле cbAvallable предназначено для записи размера блока данных, полученных автоматически от обозревателя (размером не более 48 кб).
Поле L p b D a t a содержит указатель на область памяти, в которую сервером записан полученный от обозревателя блок данных размером c b A v a i l a b l e байтов.
В управляющем блоке, кроме данных, находятся следующие указатели на методы:
Поле G e t S e r v e r V a r i a b l e содержит указатель на функцию, средствами которой ISAPI-модуль определяет значения переменных среды.
Поле W r i t e C l i e n t содержит указатель на функцию, используемую для отправки данных обозревателю, в отличие от интерфейса CGI, при котором модуль расширения помещает результат в стандартный поток вывода.
Поле R e a d C l i e n t содержит указатель на функцию, предназначенную для считывания данных в буфер предварительного чтения, имеющий адрес LpbData и размер, не превышающий 48 кб.
Поле S e r v e r S u p p o r t F u n c t i o n содержит указатель на функцию, предназначен- |
|
ную для пересылки стандартного заголовка протокола HTTP и других действий. |
|
Структуры данных для разработки |
ISAPI-модуля |
В системе программирования VisualC++6.0 для создания ISAPI-модуля
разработаны следующие классы: |
|
• |
C H t m l S t r e a m — класс потока, используемый для управления выходным |
|
потоком, в который помещается HTML-доку мент; |
• |
C H t t p S e r v e r C o n t e x t — вспомогательный класс контекста для обмена дан- |
|
ными модуля с сервером; |
• |
C H t t p S e r v e r — базовый класс для создания модуля ISAPI. |
Эти классы определены в файле "asfisapi.h". |
|
Основные методы и свойства класса C H t t p S e r v e r C o n t e x t определены сле- |
|
дующим образом: |
c l a s s C H t t p S e r v e r C o n t e x t
{
p u b l i c :
C H t t p S e r v e r C o n t e x t ( E X T E N S I O N _ C O N T R O L _ B L O C K * р Е С В ) ; / / К о н с т р у к т о р
v i r t u a l ~ C H t t p S e r v e r C o n t e x t ( ) ; |
/ / Д е с т р у к т о р |
/ / ф у н к ц и и , и с п о л ь з у е м ы е д л я о б м е н а д а н н ы м и с с е р в е р о м |
B O O L G e t S e r v e r V a r i a b l e ( L P T S T R |
I p s z V a r i a b l e N a m e , L P V O I D I p v B u f f e r , |
L P D W O R D l p d w S i z e ) ; / / O y H K U H f l |
д л я п о л у ч е н и я п е р е м е н н ы х о к р у ж е н и я |
648 Часть 4. Публикация баз данных в Интернете
B O O L W r i t e C l i e n t ( L P V O I D I p v B u f f e r , L P D W O R D I p d w B y t e s , D W O R D d w R e s e r v e d = 0 ) ; / / Ф у н к ц и я д л я з а п и с и о т в е т а о б о з р е в а т е л ю
B O O L R e a d C l i e n t ( L P V O I D I p v B u f f e r , L P D W O R D l p d w S i z e ) ; / / 0 y H K u n f l
/ / д л я ч т е н и я и з п о т о к а д а н н ы х , п е р е д а в а е м ы х о б о з р е в а т е л е м с е р в е р у B O O L S e r v e r S u p p o r t F u n c t i o n ( D W O R D d w H S E R R e q u e s t , L P V O I D
IpvBuffer, L P D W O R D I p d w S i z e , L P D W O R D I p d w D a t a T y p e ) ; / / Ф у н к ц и я
/ / д л я п е р е с ы л к и с т а н д а р т н о г о з а г о л о в к а п р о т о к о л а HTTP и д р у г и х д е й с т в и й
C H t t p S e r v e r C o n t e x t & o p e r a t o r « ( L P C T S T R p s z ) ^ / П е р е о п р е д е л е н и е / / о п е р а т о р а " « " , используемого для з а п и с и строки в выходной поток данных
/ / О с н о в н ы е с в о й с т в а p u b l i c :
D W O R D m _ d w S t a t u s C o d e ; / / K o f l в о з в р а т а
E X T E N S I O N C O N T R O L B L O C K * c o n s t m _ p E C В ; / / У к а з а т е л ь н а б л о к / / у п р а в л е н и я м о д у л е м
C H t m l S t r e a m * т _ р 5 1 г е а т ; / / У к а з а т е л ь н а п о т о к };
c l a s s C H t t p S e r v e r
{
p u b l i c :
C H t t p S e r v e r ( T C H A R c D e l i m i t e r = ' & ' ) ; / / К о н с т р у к т о р
v i r t u a l ~ C H t t p S e r v e r ( ) ; |
/ / Д е с т р у к т о р |
|||
/ / ф у н к ц и и д л я в ы в о д а ф р а г м е н т о в H T M L - д о к у м е н т а в в ы х о д н о й п о т о к |
||||
virtual |
v o i d E n d C o n t e n t ( C H t t p S e r v e r C o n t e x t * |
p C t x t ) |
с о п 8 Ъ / / Ф у н к ц и я , |
|
/ / з а к а н ч и в а ю щ а я в ы в о д H T M L - д о к у м е н т а |
|
|
||
virtual |
v o i d S t a r t C o n t e n t ( C H t t p S e r v e r C o n t e x t * |
p C t x t ) |
c o n s t ; / / Ф у н к ц и я , |
/ / и с п о л ь з у е м а я д л я в ы в о д а з а г о л о в к а о т и п е д а н н ы х и д р у г и х д е й с т в и й v i r t u a l v o i d W r i t e T i t l e ( C H t t p S e r v e r C o n t e x t * p C t x t ) c o n s t ; / / Ф у н к ц и я
/ / д л я в ы в о д а з а г о л о в к а H T M L - д о к у м е н т а
v i r t u a l L P C T S T R G e t T i t l e ( ) с о п 5 ^ / / Ф у н к ц и я ,
/ / в о з в р а щ а ю щ а я з а г о л о в о к Н Т М L - д о к у м е н т а
v o i d A d d H e a d e r ( C H t t p S e r v e r C o n t e x t * p C t x t , L P C T S T R p s z S t r i n g ) c o n s t ; / / Ф у н к ц и я , в ы в о д я щ а я з а г о л о в о ч н у ю ч а с т ь H T M L - д о к у м е н т а
v i r t u a l B O O L T e r m i n a t e E x t e n s i o n ( D W O R D d w F l a g s ) ; / / Ф у н к ц и я , / / о с в о б о ж д а ю щ а я р е с у р с ы , и с п о л ь з у е м ы е I S A P I - м о д у л е м
virtual D W O R D H t t p E x t e n s i o n P r o c ( E X T E N S I O N _ C O N T R O L _ B L O C K * p E C B ) ; / / Г л а в н а я ф у н к ц и я , в к о т о р о й ф о р м и р у е т с я H T M L - д о к у м е н т
v i r t u a l B O O L G e t E x t e n s i o n V e r s i o n ( H S E _ V E R S I O N _ I N F O * p V e r ) ;
16. Интерфейсы программирования Web-приложения |
649 |
/ / Ф у н к ц и я , з а п и с ы в а ю щ а я в е р с и ю с п е ц и ф и к а ц и и I S A P I - и н т е р ф е й с а / / и с т р о к у о п и с а н и я I S A P I - м о д у л я
};
На основе этих классов Мастера, используемые в среде Visual С + + 6 Д фор- мируют разрабатываемый ISAPI-модуль, в котором создается собственный
класс, наследующий класс C H t t p S e r v e r . Объект этого класса объединяет все свойства и методы, используемые для обмена информацией между сервером и модулем. Кроме того, с помощью функций этого объекта подменяются основные функции, которые должен экспортировать ISAPI-модуль —
G e t E x t e n s i o n V e r s i o n ( ) и H t t p E x t e n s i o n P r o c Q .
Получение данных ISAPI-модулем
ISAPI-модуль имеет более сложную организацию чем модуль CGI. Для получения переданных от обозревателя данных ISAPI-модуль использует свойства и методы специальных объектов типа S e r v e r C o n t e x t и E X T E N S I O N _ C O N T R O L _ B L O C K , имеющих аналогичные поля и методы для извлечения данных. В полях этих объектов находятся значения переменных окружения. Кроме того, с помощью методов этих объектов можно получить данные непосредственно от обозревателя. Например, для получения значений переменных окружения применяется следующий код, использующий
функцию GetServerVarlableQ:
c h a r p a r [ 1 0 ] ; d w S i z e = 10;
p C t x t - > m _ p E C B - > G e t S e r v e r V a r i a b l e ( p C t x t - > m _ p E C B - > C o n n l D , ( L P S T R ) " P A T H J N F O " , ( L P V O I D ) p a r , & d w S i z e ) ;
где p C t x t — |
указатель на контекст сервера типа C H t t p S e r v e r C o n t e x t , |
m _ p E C B - |
указатель на блок типа E X T E N S I O N _ C O N T R O L _ B L O C K . |
Через параметр C o n n I D передается идентификатор соединения, извлекае-
мый из объекта E X T E N S I O N C O N T R O L B L O C K .
Второй параметр содержит указатель на строку имени переменной окружения. Третий параметр содержит указатель на буфер — par, в который помещается значение соответствующей переменной окружения а размер этой перемен-
ной помещается в параметр d w S i z e .
Приведем значения имен основных переменных окружения, которые можно получить с помощью этой функции:
• A U T H _ T Y P E — содержит тип идентификации, используемый сервером;
•НТТР_АССЕРТ — типы данных MIME, поддерживаемые обозревателем;
•CONTENT_LENGTH — количество байтов данных, передаваемых обозревателем;
•C O N T E N T _ T Y P E — тип данных, передаваемых обозревателем;
650 |
Часть 4. Публикация баз данных в Интернете |
•PATHJNFO — данные, находящиеся в URL после имени модуля (разделенные символом "/") либо путь к виртуальному каталогу, в котором находится ISAPI-модуль;
•PATH_TRANSLATED — физический путь ISAPI-модулю;
•QUERY_STRING — данные, передаваемые обозревателем, и находящиеся после адреса URL ISAPI-модуля после символа "?";
•REMOTE_ADDR — адрес IP-узла обозревателя;
•REHOTE_HOST — доменное имя узла обозревателя или адрес IP;
•R E M O T E _ U S E R — имя пользователя, используемое обозревателем для аутентификации;
•REQUEST_HETHOD — используемый метод передачи данных от обозревателя к серверу;
•SCRIPT_NAME — путь к виртуальному каталогу и имя ISAPI-модуля;
•SERVER NAME — доменное имя Web-сервера или адрес IP Web-cepBepa, если доменное имя недоступно или не определено;
•SERVER PROTOCOL — название и версия протокола выполнения запроса к ISAPI-модулю;
•SERVER_PORT — номер порта, с которого обозреватель посылает запросы Web-серверу;
•SERVER_SOFTWARE — название и версия программного обеспечения Web-cepBepa;
•ALL_HTTP — значения всех переменных, относящихся к протоколу HTTP и отделенных друг от друга символом двоеточия ":", а сами переменные разделены символом перевода строки. Сюда относят переменные, HTTP ACCEPT, HTTP CONNЕСТЮN, HTTP_SER_AGENT и т. д.
Для отделения значений переменных могут использоваться функции, приведенные в случае использования CGI-модулей в разделе 16.1.
Заметим, что названия этих строк почти совпадают с названиями переменных среды, создаваемых для программ CGI, однако совпадение все же не полное.
Еще одна функция R e a d C l l e n t Q используется для чтения данных, передаваемых обозревателем через поток:
B O O L ( W I N A P I * R e a d C l i e n t ) ( H C O N N C o n n I D , L P V O I D I p v B u f f e r , L P D W O R D L p d w S i z e ) ;
где C o n n I D — идентификатор канала, который можно получить через струк-
туру E X T E N S I O N _ C O N T R O L _ B L O C K , |
L p v B u f f e r - адрес буфера, в который |
помещаются данные. |
|
Отправка данных |
ISAPI-модулем |
ISAPI-модуль записывает выходные данные методов не через стандартный поток вывода, как в случае с CGI-модулем, а с использованием методов объектов типа и E X T E N S I O N _ C O N T R O L _ B L O C K : W r i t e C l i e n t ( ) ,
16. Интерфейсы программирования Web-приложения |
651 |
S e r v e r S u p p o r t F u n c t i o n ( ) либо с помощью переопределенной операции "<<" вывода в поток для разных типов данных.
Прототип функции W r i t e C l i e n t ( ) имеет следующий вид:
B O O L ( W I N A P I * W r i t e C l i e n t ) ( H C O N N C o n n l D . L P V O I D B u f f e r , LP D W O R D L p d w B y t e s , D W O R D d w R e s e r v e d ) ;
Функция W r i t e C l i e n t ( ) выводит данные из буфера B u f f e r , размер которого должен быть записан в переменную L p d w B y t e s . Параметр d w R e s e r v e d зарезервирован для расширений возможностей функции. В параметре C o n n ID находится идентификатор соединения.
Функция имеет следующий прототип:
S e r v e r S u p p o r t F u n c t i o n B O O L ( W I N A P I *
S e r v e r S u p p o r t F u n c t i o n ) ( H C O N N h C o n n , D W O R D d w H S E R R e q u e s t , L P V O I D L p v B u f f e r , L P D W O R D L p d w S i z e , L P D W O R D L p d w D a t a T y p e ) ;
где h C o n n — идентификатор соединения (канала); d w H S E R R e q u e s t — код запроса, задающий тип выполняемой функцией операции; L p v B u f f e r — адрес буфера; L p d w S i z e — размер буфера; L p d w D a t a T y p e — дополнительные данные, добавляемые к заголовку HTTP-документа.
Поясним основные способы использования этой функции, определяемые значением параметра d w H S E R R e q u e s t .
• H S E _ R E Q _ S E N D _ R E S P O N S E _ H E A D E R - пересылка обозревателю за-
головка HTTP, определяемого параметром L p d w D a t a T y p e . Отметим, что функция S e r v e r S u p p o r t F u n c t i o n ( ) пересылает текстовые данные, а функция W r i t e C l i e n t ( ) может использоваться и для пересылки двоичных данных.
• H S E _ R E Q _ S E N D _ U R L — пересылка обозревателю данных, находящихся по другому адресу URL, задаваемому в виде текстовой строки, через параметр L p v B u f f e r . Параметр L p d w D a t a T y p e в этом случае не используется.
• H S E _ R E Q _ S E N D _ U R L _ R E D I R E C T _ R E S P - отправка сообщения с номе-
ром 302 (URL Redirect) по адресу URL, задаваемому в виде текстовой строки, через параметр L p v B u f f e r .
• H S E _ R E Q _ M A P _ U R L _ T O _ P A T H — преобразование логического адреса URL в физический. При этом логический адрес передается через параметр L p v B u f f e r , в который и записывается физический адрес. В переменную L p d w S i z e заносится размер строки результата преобразования.
• H S E _ R E Q _ D O N E _ W I T H _ S E S S I O N — указание серверу о завершении обработки в случае, если ISAPI-модуль оставляет соединение открытым для выполнения длительной обработки данных. При этом все параметры функции игнорируются.