}

catch (IOException e)

{

System. out. println("Ошибка ввода или вывода\n");

}

catch(ClassNotFoundException e)

{

System. out. println

("Ошибка при преобразовании типа\n");

}

При выполнении процесса сериализации требуется обрабатывать исключительные ситуации, связанные с ошибками ввода-вывода (например, задание некорректного имени файла) и ошибками класса (не удается осуществить преобразование типа). Поэтому должны быть перехвачены исключительные ситуации IOException и ClassNotFoundException.

Работа с базами данных

Как Java-приложения, так и Java-апплеты могут работать с базами данных. Для работы с базами данных:

§  или подключают специализированную библиотеку классов для конкретной СУБД – ORACLE, MySQL и т. п.;

§  или используют интерфейс ODBC.

В обоих случаях применяется технология JDBC (Java Database Connectivity), представляющий собой программный интерфейс для выполнения SQL-запросов к реляционным базам данных из Java-программ. Библиотека классов JDBC находится в пакете java. sql. Рассмотрим оба способа более подробно.

Работа с базой данных MySQL

Мы будем использовать пакет классов для MySQL, который называется mysql-connector-java-3.0.8-stable-bin. jar. Существуют два подхода:

·  этот файл нужно поместить в каталог расширений JRE, т. е., в C:\j2sdk1.4.0\jre\lib\ext;

·  или же этот файл можно поместить в любой каталог, и подключить в свойствах Kawa-проекта. Для подключения этого пакета в Kawa выбирайте меню "Project" – "Classpath...". Нажмите кнопку "New", затем кнопку "Add file...", выберите нужный jar-файл, и не забудьте нажать кнопку "Add", для того, чтобы выбранный файл появился в верхнем списке.

НЕ нашли? Не то? Что вы ищете?

Рассмотрим простой пример работы с СУБД MySQL. Консольное приложение печатает все фамилии из таблицы "Сотрудники". Сначала подключим нужные пакеты. Из пакета MySQL достаточно подключить единственный класс - Driver.

import java. sql.* ;

import com. mysql. jdbc. Driver ;

import java. io.*;

В функции main определим переменную типа Connection. Объект Connection нужен для создания соединения с базой данных.

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

Регистрируем драйвер с помощью статического метода registerDriver класса DriverManager.

DriverManager. registerDriver(new com. mysql. jdbc. Driver());

Создаем соединение с базой данных. Обратите внимание, мы не создаем объект с помощью операции new. Метод getConnection сам создает объект и возвращает ссылку на него.

c = DriverManager. getConnection

("jdbc:mysql://localhost/mycross", "root", "");

Параметры метода getConnection:

1.  cтрока подключения:

·  jdbc:mysql - имя протокола подключения,

·  localhost - имя хоста,

·  mycross - имя базы данных;

2.  логин для подключения к базе данных;

3.  пароль для подключения к базе данных.

После успешного подключения создаем объект Statement, который будет использоваться для выполнения запросов к базе данных (здесь тоже не используем new):

Statement s = c. createStatement();

Объявляем переменную ResultSet для получения результата запроса:

ResultSet rs = null;

Выполняем запрос:

rs = s. executeQuery("SELECT * FROM personal");

Заметим, что для выполнения различных запросов, связанных с изменением данных (INSERT, UPDATE, DELETE и пр.) следует применять метод executeUpdate, например,

s. executeUpdate("DELETE FROM personal");

Затем в цикле последовательно перебираем и печатаем строки результата:

while( rs. next() )

{

str=rs. getString("name");

System. out. println(str);

}

Перед выходом из программы закрываем объекты ResultSet и Connection.

rs. close();

rs=null;

c. close();

И, наконец, посмотрим, как выглядит обработка исключений, которые могут здесь возникнуть.

catch (SQLException ex)

{

System. out. println("SQLException caught");

System. out. println("---");

while ( ex!= null ){

System. out. println("Message : " + ex. getMessage());

System. out. println("SQLState : " + ex. getSQLState());

System. out. println("ErrorCode : " + ex. getErrorCode());

System. out. println("---");

ex = ex. getNextException();

}

}

catch (Exception ex)

{ System. out. println("Other Error in Main."); }

Примечание: Для того, чтобы из базы данных MySQL корректно читались русские буквы, в файл my. ini, который находится в каталоге C:\WINDOWS, нужно добавить строки:

[mysqld]

default-character-set=win1251

Использование интерфейса ODBC

Интерфейс ODBC, по существу, является посредником между приложением и базой данных. Ниже рассматривается пример таблицы “гостевая книга”. В качестве "моста" здесь используется ODBC-JDBC Bridge Driver от Sun Microsystems, загружаемый с помощью метода forName класса Class:

try

{

Class. forName("sun. jdbc. odbc. JdbcOdbcDriver");

}

catch(ClassNotFoundException e)

{

System. out. println("Sorry! Class Class is not found!");

}

Теперь нужно указать источник данных (в нашем примере он называется guest):

String mySource="jdbc:odbc:guest";

и создать соединение:

Connection databaseConnection=

DriverManager. getConnection(mySource);

Теперь, когда соединение уже создано, нам, как и в первом примере, нужно создать объект Statement для выполнения запросов к таблицам базы данных. Результат выполнения запроса сохраним в переменной ResultSet.

Statement mystatement=databaseConnection. createStatement();

String mySQL="SELECT * FROM guest";

ResultSet rec=mystatement. executeQuery(mySQL);

Заметим, что выполнив SQL-запрос к таблице, мы можем получить так называемые метаданные, т. е. сведения о самой таблице, такие как ее имя, количество столбцов, их названия и тип, количество знаков после запятой в данных и т. д. В нашем примере мы делаем это так:

ResultSetMetaData mymetadata=rec. getMetaData();

String mytable=mymetadata. getTableName(1);

System. out. println("The table is "+mytable+".");

int mycolumns=mymetadata. getColumnCount();

System. out. println("The number of columns is "+mycolumns+".");

System. out. println("They are: ");

for(int i=1;i<=mycolumns;i++)

{

String mycurColName=mymetadata. getColumnLabel(i);

// название столбца

int mycurColType=mymetadata. getColumnType(i);

// тип столбца

int mycurColScale=mymetadata. getScale(i);

// размер столбца

System. out. println(mycurColName+" (type: "+

mycurColType+", scale: "+mycurColScale+" )");

}

Наконец, мы организуем цикл для вывода содержимого таблицы в выходной поток:

while (rec. next())

{

String myrow="\n";

for(int i=1;i<=mycolumns;i++)

{

myrow+=rec. getString(i)+" ";

}

System. out. println(myrow);

}

Задание для самостоятельной работы

Рассмотрите более подробно классы Connection, Statement и ResultSet.

Создание оконных приложений

Для создания оконных приложений удобнее всего использовать класс Frame. В иерархии классов он выглядит следующим образом:

java. lang. Object

|

+----java. ponent

|

+----java. awt. Container

|

+----java. awt. Window

|

+----java. awt. Frame

По своей природе этот класс похож на классы Applet и Panel. В объекте класса Frame можно размещать элементы управления. Класс, производный от Frame, может раскрывать интерфейсы ActionListener и ItemListener.

Простейшее оконное приложение имеет вид:

// Простое оконное приложение

import java. awt. event.*;

import java. awt.*;

class SimpleFrame extends Frame

{

public static void main(String[] args)

{

SimpleFrame a= new SimpleFrame();

}

SimpleFrame()

{

setTitle("Оконное приложение");

setSize(400,200);

show();

}

}

На первый взгляд структура программы не совсем привычна – в функции main создается объект того же класса, к которому принадлежит функция main. Зато при создании объекта можно вызвать конструктор с параметрами.

Если вы запустите это приложение, то сразу же обратите внимание, что кнопка закрытия окна не работает. Для обработки событий окна нужно писать специальный код. Он может выглядеть, например, так (код располагается в конструкторе)

addWindowListener(

new WindowAdapter()

{ public void windowClosing(WindowEvent e)

{

dispose();

System. exit(0);

}

});

Это пример определения безымянного класса. Рассмотрим его подробнее. Мы вызываем метод addWindowListener для того, чтобы назначить слушателя оконных событий. В качестве параметра создаем и используем объект класса WindowAdapter. Но этот класс является абстрактным! Поэтому мы неявно создаем производный от него класс и переопределяем нужные нам методы – в данном случае обработку события закрытия окна (метод dispose уничтожает объект Frame). После этого останавливаем виртуальную машину Java вызовом метода System. exit(0). При компиляции будет создан класс с именем SimpleFrame$1.class.

Важным преимуществом объектов класса Frame и его производных является то, что они могут содержать строку меню. Для создания меню используются классы MenuBar, Menu и MenuItem (операции по созданию меню удобно выполнять в конструкторе). Приведем пример простого оконного приложения с меню:

// Простое оконное приложение с меню

import java. awt. event.*;

import java. awt.*;

class WinApp2 extends Frame

implements ActionListener, ItemListener

{

MenuBar mb;

Menu m1;

MenuItem ID_OPEN;

MenuItem ID_SAVE;

MenuItem delim1;

MenuItem ID_EXIT;

Menu m2;

MenuItem ID_NEW;

MenuItem ID_CASCADE;

MenuItem ID_TILE;

Menu m3;

CheckboxMenuItem ID_CHECK;

String status="";

Label l = new Label("");

public static void main(String[] args)

{

WinApp2 wapp= new WinApp2();

}

WinApp2()

{

mb=new MenuBar();

setMenuBar(mb);

setTitle("Оконное приложение");

m1=new Menu("File");

mb. add(m1);

m2=new Menu("Window");

mb. add(m2);

m3=new Menu("Tools");

mb. add(m3);

ID_OPEN=new MenuItem("Open");

ID_OPEN. addActionListener(this);

m1.add(ID_OPEN);

ID_SAVE=new MenuItem("Save");

ID_SAVE. addActionListener(this);

m1.add(ID_SAVE);

delim1=new MenuItem("-");

m1.add(delim1);

ID_EXIT=new MenuItem("Exit");

ID_EXIT. addActionListener(this);

m1.add(ID_EXIT);

ID_NEW=new MenuItem("New window");

ID_NEW. addActionListener(this);

m2.add(ID_NEW);

ID_CASCADE=new MenuItem("Cascade");

ID_CASCADE. addActionListener(this);

m2.add(ID_CASCADE);

ID_TILE=new MenuItem("Tile");

ID_TILE. addActionListener(this);

m2.add(ID_TILE);

ID_CHECK=new CheckboxMenuItem ("Check spelling");

ID_CHECK. addItemListener(this);

m3.add(ID_CHECK);

add(l);

addWindowListener(

new WindowAdapter()

{ public void windowClosing(WindowEvent e)

{

dispose();

System. exit(0);

}

});

setSize(400,200);

setBackground(new Color(200,200,220));

setLocation(200,200);

show();

}

public void actionPerformed(ActionEvent e)

{

l. setText(e. getActionCommand());

if(e. getActionCommand().equals("Exit"))

{

dispose();

System. exit(0);

}

}

public void itemStateChanged(ItemEvent e)

{

if (e. getStateChange()==ItemEvent. SELECTED)

l. setText(""+e. getItem()+" включен");

else

l. setText(""+e. getItem()+" выключен");

}

}

Линейка меню задается с помощью объекта MenuBar. Этот объект нужно сначала создать, а потом назначить объекту Frame с помощью метода setMenuBar.

Пункты меню (имеющие подчиненные меню) – это объекты класса Menu. Их нужно сначала создать, а потом добавить в объект MenuBar с помощью метода add.

Конечные пункты меню – это объекты класса MenuItem. Они конструируются в три шага. Такой объект сначала нужно создать, потом назначить ему слушателя методом addActionListener, а затем добавить в объект Menu с помощью метода add.

Для обработки событий меню класс, производный от Frame, должен раскрывать интерфейс ActionListener. Принципы работы те же, что и при обработке событий от элементов управления.

Кроме простых пунктов меню можно использовать пункты меню с "галочками" – подобие элементов управления-переключателей. Для этого есть специальный класс CheckboxMenuItem. Для обработки событий от таких пунктов меню класс, производный от Frame, должен раскрывать интерфейс ItemListener.

Задание для самостоятельной работы

Рассмотрите более подробно классы MenuBar, MenuItem и Menu.

Сетевые приложения

Для создания сетевых приложений используются стандартные классы пакета . Рассмотрим применение некоторых из них.

Пример 1. Приложение, которое запрашивает и печатает файл по заданному URL (строки файла нумеруются).

/* Из книги J. M. Bishop 'Java jently' */

import java. io.*;

import .*;

import java. util.*;

class Lister {

public static void main(String[] args) throws IOException {

try {

// создаем объекты URL и URLConnection

URL resource = new URL(args[0]);

URLConnection c = resource. openConnection();

// печатаем имя файла и дату создания,

//а также некоторые заголовки

System. out. println(args[0]+" created "+

new Date(c. getDate()));

System. out. println("ContentType: " +c. getContentType());

System. out. println("ContentEncoding: " +

c. getContentEncoding());

System. out. println("ContentLength: " +

c. getContentLength());

System. out. println("LastModifed: " +

new Date(c. getLastModified()));

for (int i=0; i<args[0].length()+32; i++)

System. out. print('-');

System. out. println("\n");

// создаем поток вывода и печатаем все строки

BufferedReader in = new BufferedReader

(new InputStreamReader(c. getInputStream()));

for (int i=1; ; i++) {

String line = in. readLine ();

if (line == null) break;

System. out. println(i+" "+line);

}

}

catch (MalformedURLException e) {

System. out. println("Неверный URL."+

"Не забудьте, что адрес начинается "+

"с http:// или file:///");

}

}

}

Это приложение получает URL как аргумент командной строки. В Kawa это можно сделать так: В меню проекта нужно выбрать ProjectCompiler options... и на закладке Interpreter включить переключатель Command Line Arguments и написать какой-нибудь адрес, например,

http://kek. *****/EOS/Java/default. html.

Теперь рассмотрим основные действия, выполняемые в программе. Сначала создадим объект URL:

URL resource = new URL(args[0]);

Затем для чтения данных создадим объект URLConnection на основе объекта URL:

URLConnection c = resource. openConnection();

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

BufferedReader in = new BufferedReader

(new InputStreamReader(c. getInputStream()));

Данные из этого потока можно читать, например, построчно, с помощью метода getLine.

Наконец, отметим, что конструктор URL может генерировать исключение MalformedURLException, а метод openConnection и методы объектов-потоков ввода-вывода могут генерировать исключение IOException. Следовательно, эти исключения нужно обрабатывать.

В предыдущем примере мы рассмотрели, как устанавливается соединение с web-ресурсами на высоком уровне, т. е., через URL. Java предоставляет возможность работать с соединениями и на более низком уровне – через порты и сокеты.

Порт – это абстрактный физический объект, через который осуществляется коммуникация между клиентом и сервером. При этом сервер предоставляет порт, а клиент с ним соединяется.

В операционных системах имеются процессы, назначенные конкретным портам. Программное обеспечение сервера непрерывно прослушивает эти порты на предмет обнаружения сообщений определенного вида. Как правило, порты идентифицируются с помощью номеров. Например, известные нам Web-серверы (IIS, Apache) по умолчанию используют порт 80, CУБД MySQL по умолчанию запускается на порте 3306, и т. п. Однако есть много незадействованных портов, которые мы можем применять для создаваемых нами служб.

Примером такой службы может быть многопотоковая Java-программа, обеспечивающая сокеты для данного порта. Сокет (в переводе с английского – гнездо, патрон) – это абстракция сетевого программного обеспечения, которая дает возможность осуществлять соединения с сетевой программой и обмениваться с ней входными и выходными данными. Простейшим методом организации обмена является установление обычных потоков ввода-вывода от сервера клиенту и наоборот. Для одного порта можно создать несколько клиентских сокетов, что позволяет нескольким пользователям получать доступ к данной службе.

Если клиентом является Java-программа, то она также должна иметь сокет и потоки, соответствующие аналогичным потокам сервера. Клиентом может быть и служебная программа, такая, как telnet.

Пример 2. ATM (automated teller machine) – банкомат. Эта программа имитирует соединение с банком и проверку достоверности вводимого клиентом личного идентификациоонного номера (PIN-кода). В качестве клиентской программы используется telnet подключение нужно проводить к серверу localhost и порту 8190.

import java. io.*;

import .*;

class ATMServer {

/* Простая серверная программа, J M Bishop Декабрь 1996

* =======================

* Java 1.1 обновлено Январь 1998

* Java 1.2 B Worrall Август 2000

* Позволяет выполнять много одновременных подключений.

* Иллюстрирует использование сокетов и работу в сети. */

static final String magicPIN = "5678";

static int port = 8190;

InetAddress serverAddress = null;

private boolean done = false;

public static void main(String[] args) {

// Получает номер порта из строки параметров

// или назначает значение по умолчанию 8190

if (args. length > 0)

port =Integer. parseInt(args[0]);

new ATMServer (port);

}

ATMServer (int port) {

try {

serverAddress = InetAddress. getLocalHost();

} catch (UnknownHostException e) {}

// Информация при запуске сервера

System. out. println("****** Саванна банк ");

System. out. println("Имитирует сеанс ATM "

+ "для клиентов, подключающихся через telnet к серверу ");

System. out. println(serverAddress. getHostName() +

"к порту "+port);

System. out. println("от любого количества компьютеров или ");

System. out. println("из любого количества окон.");

// Инициализирует ServerSocket

try {

ServerSocket listener = new ServerSocket(port);

int c = 0;

while (!done) {

// Создается пауза ожидания клиентских подключений

Socket client = listener. accept( );

c ++;

System. out. println("Кредитная карточка вставлениа в " +

client. getInetAddress().getHostName());

System. out. println("Начало обслуживания "+

"нового клиента под номером "+c);

new handler(client, c).start();

}

listener. close();

}

catch (IOException e) {

System. out. println("Порт "+port+

", возможно, занят. Попробуйте еще раз.");

}

}

void closeDown () {

done = true;

}

class handler extends Thread {

private Socket toClient;

private int id;

handler(Socket s, int i) {

// Запоминает номер сокета и клиентский ID

toClient = s;

id = i;

}

public void run() {

try {

DataInputStream conin =

new DataInputStream (toClient. getInputStream());

PrintWriter conout = new

PrintWriter(toClient. getOutputStream(),true);

conout. println( "Welcome to Savanna bank");

for (int tries = 0; tries < 3; tries++) {

conout. println("Please, enter your PIN-code "+

"or CANCEL");

String s = conin. readLine();

System. out. println("Клиент "+id+":"+s);

if (s. equals("SHUTDOWN")) closeDown();

else if (s. equals("CANCEL")) {

conout. println("Transaction is complete. Goodbye.");

break;

}

else if (s. equals(magicPIN)) {

conout. println("You can begin a transaction");

break;

}

else

conout. println("Incorrect PIN-code."+

"Try again.");

}

System. out. println("Имитация завершена. Спасибо.");

conout. println("---");

conout. println("Imitation is complete. Thanks.");

}

catch (IOException e) {System. out. println("IO Error");}

}

}

}

Номер порта программа получает из командной строки или назначает по умолчанию порт 8190.

В конструкторе с помощью метода getLocalHost() класса InetAddress получаем локальный адрес (обычно это "localhost"):

serverAddress = InetAddress. getLocalHost();

Основную работу выполняет объект класса ServerSocket. Этот объект создается на заданном порте и выполняет функции "слушателя":

ServerSocket listener = new ServerSocket(port);

При успешном создании объекта в бесконечном цикле устанавливается режим ожидания подключений со стороны клиентов. Метод accept создает паузу, которая заканчивается при поступлении нового подключения от очередного клиента. При этом создается новый объект класса Socket:

Socket client = listener. accept( );

Сообщения от клиентов могут поступать с различными скоростями, поэтому для параллельной обработки в данной программе предусмотрен класс handler, производный от класса Thread. Объект этого класса создается и запускается на выполнение командой

new handler(client, c).start();

В методе run этого потока происходит обмен информацией с клиентом. Для этого создаются два объекта – входной и выходной поток:

DataInputStream conin =

new DataInputStream (toClient. getInputStream());

PrintWriter conout =

new PrintWriter(toClient. getOutputStream(),true);

У клиента есть три попытки набора правильного PIN-кода. Кроме того, клиент может набрать команду CANCEL для завершения сеанса и команду SHUTDOWN для остановки сервера (разумеется, последняя возможность не слишком правдоподобна).

Таким образом, в данном примере рассмотрена только авторизация клиента. Получение информации о счете, возможность снятия денег со счета и т. п. не предусмотрены.

Пример 3. Простейший клиент. Он подключается к порту 8190 хоста localhost, принимает одно сообщение (строку) и отправляет одно сообщение (строку), и на этом прекращает работу.

Основные действия, которые выполняются в этой программе:

1) создание клиентского сокета

Socket mySock = new Socket("localhost",8190);

2) создание входного потока для сокета

BufferedReader in =

new BufferedReader(

new InputStreamReader(mySock. getInputStream()));

3) создание выходного потока для сокета

PrintWriter out =

new PrintWriter(mySock. getOutputStream(), true);

4) чтение строки из входного потока

str=in. readLine();

5) запись строки в выходной поток

out. println("Done");

Задание для самостоятельной работы

1. Рассмотрите более подробно классы Socket и ServerSocket.

2. Рассмотрите самостоятельно пример реализации чат-сервера. Чат-сервер – это программа, которая запущена на некотором порте некоторого хоста и находится в режиме ожидания подключений со стороны клиентов. Клиент может подключиться к серверу и посылать сообщения, которые сервер перенаправляет всем клиентам. Код программы приведен в примере 3 приложения 5.

Глава 5. Немного о сервлетах и Java Server Pages

Сервлеты и JSP представляют собой Java-технологии, предназначенные для разработки серверных web-сценариев.

Сервлеты - это программы, которые выполняются на web-сервере, действуя в качестве посредника между запросом, поступающим от web-браузера или другого HTTP-клиента, и приложениями на HTTP-сервере (базами данных и др.)

Технология Java Server Pages позволяет смешивать обычный, статический HTML-код с динамически сгенерированным содержимым сервлетов (подобно технологиям PHP и ASP).

Что нужно для разработки сервлетов и JSP?

Для работы с сервлетами и JSP требуется установить Web-сервер, поддерживающий Java. Некоторые серверы специально разработаны c поддержкой Java, другие позволяют устанавливать для этой цели дополнительные модули (plug-ins).

Рассмотрим известный Web-сервер Apache Tomcat. Для его установки нужно просто распаковать архив в некоторый каталог, например, C:\TomCat. По умолчанию этот сервер использует нестандартный порт 8080, поэтому для просмотра страниц из браузера нужно использовать адрес

http://localhost:8080

Для запуска сервера используется пакетный файл startup. bat из каталога BIN.

Сервер TomCat работает на Java-платформе, поэтому на компьютере также должен быть установлен JDK. Чтобы указать серверу, где именно установлен JDK, в файле startup. bat нужно инициализировать переменную JAVA_HOME, например, так (если JDK установлен в каталог C:\jdk1.4):

set JAVA_HOME=C:\jdk1.4

Если вы работаете в ОС Win98, то, вероятно, вам потребуется изменить объем памяти для переменных среды. Запустите окно DOS, щелкните на пиктограмме "Параметры" и выберите закладку "Память". Измените значение параметра "Переменные среды" c Auto на 2816. Эта настройка производится только один раз.

Корневым каталогом для TomCat является

C:\TOMCAT\WEBAPPS\ROOT

Наберите в адресной строке браузера

http://localhost:8080

Браузер загрузит страницу index. html из этого каталога.

Примеры сервлетов

Рассмотрим любимый пример "Hello, World!".

import java. io.*;

import javax. servlet.*;

import javax. servlet. http.*;

public class HelloWorld extends HttpServlet {

public void doGet(HttpServletRequest request,

HttpServletResponse response)

throws ServletException, IOException {

response. setContentType("text/html");

PrintWriter out = response. getWriter();

String docType =

"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 " +

"Transitional//EN\">\n";

out. println(docType +

"<HTML>\n" +

"<HEAD><TITLE>Hello, World!”+

”</TITLE></HEAD>\n" +

"<BODY>\n" +

"<H1>Hello, World!</H1>\n" +

"</BODY></HTML>");

}

}

Сначала в этом примере импортируются дополнительные библиотеки классов для сервлетов. Эти библиотеки находятся в архиве servlet. jar, расположенном в каталоге LIB сервера TomCat. Для подключения этого архива используйте настройку Classpath вашего проекта, если вы работаете в Kawa, или установку SET СLASSPATH в переменных среды.

Любой сервлет является производным от класса HttpServlet. Обычно в нем переопределяется метод doGet, или doPost, или оба эти метода (можно переопределить один из них и вызвать его из другого). Эти методы могут получать параметры запроса (с помощью своего первого параметра – объекта request), а затем формируют ответ сервера (с помощью второго параметра – объекта response).

Первой строкой ответа должно быть формирование заголовка Content-Type:

response. setContentType("text/html");

Затем получаем ссылку на выходной поток сервлета:

PrintWriter out = response. getWriter();

и выводим любую информацию в этот выходной поток (в данном случае - простой HTML-код).

Теперь этот сервлет нужно откомпилировать. Полученный файл HelloWorld. class следует поместить в специальный каталог сервера TomCat для сервлетов, в нашей версии это

C:\TOMCAT\WEBAPPS\ROOT\WEB-INF\CLASSES

Для запуска сервлета в адресной строке браузера наберите

http://localhost:8080/servlet/HelloWorld

В том случае, когда сервлету передаются параметры, получить их можно с помощью метода getParameter объекта request типа HttpServletRequest. Например, для получения параметра с именем klient можно использовать следующую команду:

String customer=request. getParameter("klient");

Пример JSP

Простой пример JSP-сценария получает название цвета фона в качестве параметра и формирует страницу с заданным цветом фона.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<HTML>

<HEAD>

<TITLE>Color Testing</TITLE>

</HEAD>

<%

String bgColor = request. getParameter("bgColor");

boolean hasExplicitColor;

if (bgColor!= null) {

hasExplicitColor = true;

} else {

hasExplicitColor = false;

bgColor = "WHITE";

}

%>

<BODY BGCOLOR="<%= bgColor %>">

<H2 ALIGN="CENTER">Color Testing</H2>

<%

if (hasExplicitColor) {

out. println("Вы явно задали цвет фона: " +

bgColor + ".");

} else {

out. println("Цвет фона по умолчанию: WHITE." +

"Задавайте значения параметру bgColor " +

"в виде имени цвета, или в формате RRGGBB");

}

%>

</BODY>

</HTML>

Как видим, в JSP-сценарии могут быть перемешаны HTML-теги и операторы языка Java. Серверные команды следует помещать в теги <% %>, как в ASP.

В серверном коде используются те же самые объекты response и request, как и в сервлетах.

И вообще, на основе JSP-страницы Java-сервер в любом случае (невидимо для нас) создает и выполняет сервлет.

Для тестирования нужно сохранить этот сценарий с расширением jsp в корневом каталоге TomCat и запускать, например, так:

http://localhost:8080/BGColor. jsp? bgColor=lightblue

Если в JSP-сценарии требуется подключение к серверу баз данных (например, к mySQL), то в начале JSP-страницы следует импортировать нужные пакеты:

<%@ page import="java. sql.*" %>

<%@ page import="com. mysql. jdbc. Driver" %>

Соответственно, для работы с файлами в начале JSP-страницы следует импортировать пакет:

<%@ page import="java. io.*" %>

Задание для самостоятельной работы

Рассмотрите самостоятельно более сложный пример, который касается передачи параметров сервлету из формы. Он состоит из двух файлов: HTML-формы, передающей параметры сервлету и сервлета, получающего параметры из HTML-формы. Этот пример под номером 4 приведен в приложении 5.

Передача файла из HTML-формы сервлету

Иногда требуется отправлять данные в виде файла сервлету (или JSP-сценарию) на обработку. В этом случае HTML-форма, отправляющая данные должна иметь атрибут

enctype="multipart/form-data"

Форма должна иметь поле типа file для выбора файла из файловой системы локального компьютера.

Получение данных, которые передаются сервлету, можно произвести с помощью одного из двух видов потоков – байтового (двоичного) или символьного.

Байтовый поток имеет тип ServletInputStream и ссылку на него можно получить с помощью метода getInputStream объекта request. Для чтения из этого потока используется метод со следующим прототипом:

int readLine(byte[] buf, int offset, int length)

Этот метод позволяет читать в buf данные из входного потока, начиная с байта с номером offset длиной length. Метод возвращает число прочитанных байт из входного потока или -1, если входной поток уже исчерпан.

Символьный поток имеет тип BufferedReader и ссылку на него можно получить с помощью метода getReader объекта request.

Заметим, что данные из HTML-формы передаются в сопровождении HTTP-заголовков. Например, если форма содержит текстовое поле с именем klient и поле передачи файла myfile, передаваемые данные могли быть такими:

------7d62711f901f81

Content-Disposition: form-data; name="klient"

Значение, введенное в текстовое поле

------7d62711f901f81

Content-Disposition: form-data; name="myfile"; filename="локальные путь и имя передаваемого файла"

Content-Type: text/plain

Содержимое файла

------7d62711f901f81

Последовательность символов "------7d62711f901f81" представляет собой так называемую границу (для каждого запроса такая последовательность генерируется заново). Эта граница разделяет текст передаваемых данных на части. Естественно, что для правильной трактовки содержимого передаваемых данных требуется разделить извлекаемые из потока заголовки и данные.

Разумеется, вручную анализировать данные потоков довольно сложно. К счастью, существуют разные пакеты классов, использование которых позволяет сделать этот анализ более высокоуровневым. Рассмотрим пример применения одного из таких пакетов – com. ibm. useful. http.

import javax. servlet.*;

import javax. servlet. http.*;

import java. io.*;

import com. ibm. useful. http.*;

public class ReceiverServlet

extends javax. servlet. http. HttpServlet

{

public void doPost(javax. servlet. http. HttpServletRequest req,

Из за большого объема этот материал размещен на нескольких страницах:
1 2 3 4 5 6 7