Электронная библиотека книг Александра Фролова и Григория Фролова.
Shop2You.ru Создайте свой интернет-магазин
Библиотека
Братьев
Фроловых
[Назад]

Библиотека примеров приложений Java

Оглавление
Работа с классом InetAddress
Работа с классом URL
Просмотр файлов сервера Web
Копирование файлов сервера Web
Контрольная сумма аплета
Потоковые сокеты - сервер
Потоковые сокеты - клиент
Общение в реальном времени
Широковещатель-
ные сообщения

Аплет и расширение сервера Web

Назад

8.10. Связь аплета с расширением сервера Web

Приведен и описан исходный текст аплета, способного обмениваться данными с расширением сервера Web в виде программы CGI. Аплет посылает расширению текстовую строку и принимает строку ответа. Полученная строка отображается в окне аплета.

Исходный текст аплета

Исходный текст программы CGI

Архив проекта для Java WorkShop 2.0

Немного теории

Библиотеки классов Java позволяют организовать взаимодействие между приложением Java и расширениями сервера Web, такими как CGI или ISAPI. В этом случае приложения или аплеты Java могли бы посылать произвольные данные расширению сервера Web для обработки, а затем получать результат этой обработки.

Методика организации взаимодействия приложений Java и расширений сервера Web основана на применении классов URL и URLConnection.

Приложение Java, желающее работать с расширением сервера Web, создает объект класса URL для программы расширения (то есть для исполняемого модуля расширения CGI или библиотеки динамической компоновки DLL расширения ISAPI).

Далее приложение получает ссылку на канал передачи данных с этим расширением как объекта класса URLConnection. Затем, пользуясь методами getOutputStream и getInputStream из класса URLConnection, приложение создает с расширением сервера Web выходной и входной канал передачи данных.

Когда данные передаются приложением в выходной канал, созданный подобным образом, они попадают в стандартный поток ввода приложения CGI. Все выглядит так, как будто бы данные пришли методом POST из формы, определенной в документе HTML.

Обработав полученные данные, расширение CGI записывает их в свой стандартный выходной поток. После этого данные становятся доступны приложению Java через входной поток, открытый методом getInputStream класса URLConnection.

Описание примера

На рис. 1 показано окно аплета CallCGI, взаимодействующее с расширением сервера Web.

pic1.gif (2265 bytes)

Рис. 1. Окно аплета CallCGI

Когда пользователь нажимает кнопку Connect, аплет в отдельном потоке исполнения посылает расширению сервера Web (программе CGI) строку "MyPrivateInfo". Программа расширения сервера формирует строку ответа из принятой строки, добавляя к ней текущую дату и время. Результат отправляется обратно аплету, который и отображает его в своем окне (рис. 1).

Исходный текст аплета

Рассмотрим исходный текст аплета.

Главный класс создан на базе класса Applet:

import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
import java.net.*;
import java.io.*;

public class CallCGI extends Applet
  implements ActionListener, Runnable
{
  . . .
}

В классе мы определили три поля:

TextArea ta;
Button btnConnect;
private Thread thrConnect = null;

Поле ta хранит ссылку на многострочный редактор текста, в окне которого отображаются строки, принятые от расширения сервера Web.

Поле btnConnect предназначено для хранения ссылки на кнопку Connect, а поле thrConnect - для хранения ссылки на поток выполнения, в котором происходит обмен данными с сервером Web.

Метод init

При инициализации аплета метод init создает кнопку и редактор текста, а затем добавляет их в окно:

public void init()
{
  btnConnect = new Button("Connect");
  ta = new TextArea(5, 40);
  btnConnect.addActionListener(this);
    
  add(ta);
  add(btnConnect);

  setBackground(Color.white);
  setForeground(Color.black);
}

Далее для кнопки задается обработчик событий. Метод init также устанавливает цвет фона и текста для окна аплета.

Метод actionPerformed

Когда пользователь нажимает кнопку Connect, метод actionPerformed создает поток класса Thread и запускает его на выполнение:

public void actionPerformed(ActionEvent e)
{
  if(e.getSource().equals(btnConnect))
  {
    thrConnect = new Thread(this);
    thrConnect.start();
  }
}

В рамках этого потока будет работать метод run, определенный в главном классе аплета.

Метод run

Получив управление, метод run создает объект класса URL для файла программы CGI, играющей роль расширения сервера Web:

URL u;
String szURL = 
  "http://frolov/scripts/infocgi.exe";
try
{
  u = new URL(szURL);
  . . .
}
catch (Exception ioe)
{
  showStatus(ioe.toString());
  stop();
}

Обратите внимание на то что здесь мы указали адрес расширения явным образом. Когда вы будете проверять работу аплета, этот адрес необходимо изменить.

Файл программы infocgi.exe необходимо разместить на вашем сервере Web в каталоге, для которого разрешено выполнение программ. В переменную szURL вы должны записать полный адрес файла с учетом доменного имени своего сервера и названия каталога с программами CGI.

Следующий шаг - установка соединения с сервером:

URLConnection c;
c = u.openConnection();

В случае успешного соединения метод run создает объект класса URLConnection.

Пользуясь этим объектом, метод run получает выходной поток, пригодный для передачи данных расширению сервера Web:

PrintStream ps;
ps = new PrintStream(c.getOutputStream());

Далее через этот поток мы передаем текстовую строку, а сам поток закрываем:

String szPrivateInfo = 
  URLEncoder.encode("MyPrivateInfo");
ps.println(szPrivateInfo);
ps.close();

Перед передачей мы выполняем кодирование строки методом encode из класса URLEncoder. Этот метод заменяет специальные символы на последовательность символов, пригодную для передачи серверу Web.

Следующий этап - прием ответа от расширения сервера Web.

Вначале мы открываем входной поток, вызывая метод getInputStream:

DataInputStream is;
is = new DataInputStream(c.getInputStream());

Пользуясь этим потоком, мы принимаем строку ответа от расширения сервера и сохраняем ее в переменной szReceived:

String szReceived;
szReceived = is.readLine();
is.close();

После приема данных входной поток необходимо закрыть.

Далее полученная строка отображается в окне многострочного редактора текста, расположенного в окне аплета:

ta.append(szReceived + "\n");

Исходный текст программы CGI

Для работы с аплетом CallCGI мы подготовили программу CGI, отладив ее на сервере Internet Information Server в среде Windows NT. Создавая проект, вы должны указать тип программы как 32-разрядное консольное приложение (не путайте с программой DOS - это разные вещи).

Рассмотрим исходный текст программы.

Программа рассчитана на использование метода передачи POST, поэтому в начале своей работы она выполняет необходимую проверку:

char * szMethod;
szMethod = getenv("REQUEST_METHOD");
if(!strcmp(szMethod, "POST"));
{
  . . .
}

Далее программа получает размер данных, переданных аплетом:

int  nInDatasize;
nInDatasize = atoi(
  getenv("CONTENT_LENGTH"));

Эти данные необходимо считать из стандартного потока ввода.

Данные считываются функцией fread в буфер szBuf, который затем закрывается нулем:

char szBuf[200];
fread(szBuf, nInDatasize, 1, stdin);
szBuf[nInDatasize - 1] = '\0';

В буфере szBuf1 мы готовим ответ для аплета:

char tmbuf[9];
char datbuf[9];
char szBuf1[200];

sprintf(szBuf1, "Server date: %s %s ",
_strdate(datbuf), _strtime(tmbuf));
strcat(szBuf1, szBuf);

Здесь к строке, принятой через стандартный поток ввода, добавляется строка даты и времени, полученные на сервере. Таким образом, аплет позволяет пользователю узнать дату и время, установленные на сервере Web (разумеется. не на любом, а только на том, где находится наша программа CGI).

Ответ снабжается стандартным заголовком для текстовых документов без элементов оформления и отправляется аплету через стандартный поток вывода:

printf(
  "Content-type: text/plain\r\n\r\n");
printf(szBuf1);

Далее аплет принимает содержимое буфера szBuf1 и отображает его в своем окне.


Назад

[Назад]