Java Примеры программирования Информатика начало

Аплет Form

Назад Вперед

На примере аплета Form мы покажем, как приложения Java могут взаимодействовать с расширениями сервера Web, такими как программы CGI или приложения ISAPI.

В окне нашего аплета находится форма, содержащая два однострочных поля редактирования, кнопку и многострочное поле редактирования (рис. 5).

 

 

 

pic05.gif (4332 bytes)

Рис. 5. Окно аплета Form

Эта форма предназначена для добавления записей в базу данных, содержащую электронные почтовые адреса. Заполнив поля имени и адреса E-Mail, пользователь должен нажать кнопку Send. При этом введенная информация будет передана расширению сервера CGI, который запишет ее в базу данных, а затем отправит обратно аплету. Сохраненные записи, полученные от программы CGI, аплет FORM отобразит в многострочном поле редактирования, как это показано на рис. 5.

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

Исходные тексты аплета Form представлены в листинге 5.

Листинг 5. Файл Form.java

import 
java.applet.*; import java.awt.*; import java.net.*; import java.io.*; import 
java.util.*;
public class Form extends 
Applet implements Runnable { private Thread m_store = null;
 
TextField txtName; TextField txtEMail; TextArea txta; Button btnGetText;
 
public void init() { Label lbName; Label lbEMail; Label lbPress; 
 
lbName = new Label("Enter your name:"); lbEMail = new Label( "Enter your E-Mail 
address:"); 
 add(lbName);
 
txtName = new TextField("Your name", 40); add(txtName);
 
add(lbEMail);
 txtEMail = new TextField("your@email", 
40); add(txtEMail);
 btnGetText = new Button("Send!"); 
add(btnGetText);
 txta = new TextArea(8, 
65); add(txta);
 setBackground(Color.yellow); 
}
 public void paint(Graphics g) { setBackground(Color.yellow); 
 Dimension dimAppWndDimension = getSize(); 
g.setColor(Color.black); g.drawRect(0, 0, dimAppWndDimension.width - 1, dimAppWndDimension.height 
- 1); }
 public boolean action(Event evt, 
Object obj) { Button btn;
 if(evt.target 
instanceof Button) { btn = (Button)evt.target;
 
if(evt.target.equals(btnGetText)) { startTransaction(); } else return false; return 
true; } return false; }
 void startTransaction() 
{ m_store = new Thread(this); m_store.start(); } 
 
public void stop() { if (m_store != null) { m_store.stop(); m_store = null; } 
}
 public void run() { URL u; URLConnection 
c; PrintStream ps; DataInputStream is; 
 
try { String szSourceStr = txtName.getText() + ", " + txtEMail.getText(); 
 
String szReceived; String szURL = "http://frolov/scripts/store.exe";
 
u = new URL(szURL); c = u.openConnection();
 
ps = new PrintStream( c.getOutputStream()); ps.println(szSourceStr); ps.close();
 
is = new DataInputStream( c.getInputStream());
 
szReceived = is.readLine(); is.close();
 
txta.appendText(szReceived + "\r\n"); repaint(); } catch (Exception ioe) { showStatus(ioe.toString()); 
stop(); } } }

Исходный текст документа HTML, который был подготовлен для нас системой Java Workshop, мы немного отредактировали, изменив параметр CODEBASE (листинг 6).

Листинг 6. Файл Form.tmp.html

<applet 
name="Form" code="Form.class" codebase="http://frolov/" width="500" height="200" 
align="Top" alt="If you had a java-enabled browser, you would see an applet here."> 
<hr>If your browser recognized the applet tag, you would see an applet here.<hr> 
</applet>

В этом параметре следует указать путь к каталогу, в котором располагается байт-код аплета.

Описание исходныех текстов аплета Form

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

Когда пользователь заполняет форму и нажимает кнопку Send, обработчик соответствующего события вызывает метод startTransaction, запускающий процесс обмена данными с расширением сервера Web:

if(evt.target.equals(btnGetText)) 
{ startTransaction(); }

Метод startTransaction, определенный в нашем приложении, создает и запускает на выполнение поток, который и будет взаимодействовать с программой CGI:

void 
startTransaction() { m_store = new Thread(this); m_store.start(); } 

При этом в качестве отдельного потока, работающего одновременно с кодом аплета, выступает метод run. Именно в нем сосредоточена вся логика обмена данными с сервером Web.

Так как в процессе взаимодействия могут возникать различные исключения, мы предусмотрели их обработку при помощи блока try-catch:

URL u; 
URLConnection c; PrintStream ps; DataInputStream is; 
try 
{ . . . } catch (Exception ioe) { showStatus(ioe.toString()); stop(); }

Название возникшего исключения будет отображено в строке состояния браузера.

Теперь о том, что делает метод run после получения управления.

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

String 
szSourceStr = txtName.getText() + ", " + txtEMail.getText();

В строке szURL находится адрес URL программы CGI:

String 
szURL = "http://frolov/scripts/store.exe";

В реальном приложении этот адрес необходимо передавать аплету через параметр. Мы использовали непосредственное кодирование только для упрощения исходного текста.

На следующем этапе метод run создает для программы CGI объект класса URL и открывает с ним соединение:

u 
= new URL(szURL); c = u.openConnection();

Пользуясь этим соединением, метод run создает форматированный поток вывода, записывает в него строку имени и электронного адреса, а затем закрывает поток:

ps 
= new PrintStream(c.getOutputStream()); ps.println(szSourceStr); ps.close();

Переданные таким образом данные попадут в стандартный поток ввода программы CGI, откуда она их и прочитает.

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

is 
= new DataInputStream(c.getInputStream()); String szReceived; szReceived = is.readLine(); 
is.close();

Сразу после этого программа CGI завершит свою работу и будет готова к обработке новых запросов на добавление записей. Что же касается метода run, то он добавит полученную от расширения сервера текстовую строку в многострочное окно редактирования, как это показано ниже, а затем инициирует перерисовку окна аплета:

txta.appendText(szReceived + "\r\n"); 
repaint();

Заметим, что использованный нами способ передачи данных подходит только для латинских символов. Если вам нужно передавать символы кириллицы, следует преобразовывать их из кодировки UNICODE, например, в гексадецимальную кодировку, а в программе CGI выполнять обратное преобразование. Аналогичную методику можно применять и для передачи произвольных двоичных данных.

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

Исходный текст программы CGI store.exe очень прост и показан в листинге 7.

Листинг 7. Файл store.c

#include <windows.h> 
#include <tchar.h> #include <wchar.h> #include <stdio.h> #include 
<stdlib.h> #include <string.h>
void 
main(int argc, char *argv[]) { int nInDatasize; char * szMethod; char szBuf[2000];
 
FILE *fDatabase; CRITICAL_SECTION csAddRecord;
 
szMethod = getenv("REQUEST_METHOD"); if(!strcmp(szMethod, "POST")); { nInDatasize 
= atoi( getenv("CONTENT_LENGTH"));
 fread(szBuf, 
nInDatasize, 1, stdin); szBuf[nInDatasize] = '\0';
 
InitializeCriticalSection(&csAddRecord); EnterCriticalSection(&csAddRecord);
 
fDatabase = fopen("c:\\EMAIL.DAT", "a+"); if(fDatabase != NULL) { fputs(szBuf, 
fDatabase); fclose(fDatabase); }
 LeaveCriticalSection(&csAddRecord); 
DeleteCriticalSection(&csAddRecord);
 
printf( "Content-type: text/plain\r\n\r\n"); printf("Stored information: %s", 
szBuf); } }

Этот текст подготовлен для работы в среде  Windows 95 или Windows NT, так как для синхронизации доступа к файлу мы использовали специфические для этих операционных систем функции работы с критическими секциями.

Свою работу программа CGI начинает с анализа переменной среды REQUEST_METHOD. Убедившись, что при запуске программы ей передали данные методом POST, программа определяет размер этих данных исходя из содержимого переменной среды CONTENT_LENGTH.

Далее программа считывает соответствующее количество байт данных из стандартного потока ввода, записывает их в файл. Затем, после добавления заголовка "Stored information:", программа CGI записывает полученную строку в стандартный выходной поток, передавая ее таким образом аплету Form.

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

Еще одно замечание касается пути к файлу, который в нашем случае создается в корневом каталоге диска C:. При установке программы CGI на сервер вам необходимо обеспечить доступ на запись к каталогу, в котором располагается файл, для удаленных пользователей. О том, как это сделать, вы можете узнать из документации на ваш сервер Web.

Назад Вперед
Машиностроительное черчение, инженерная графика, начертательная геометрия. Выполнение контрольной