|
2000 г
Доступ к базам данных из Java-программ и проблемы русификации
С. Б. Дунаев
Статья написана автором в октябре 1997 г и опубликована в ж-ле СУБД №1-1 1998
Введение
Разумеется, что организовать доступ к базам данных из современного языка программирования в наше время не представляет никакой сложности. Более того, и сами языки программирования более всего оцениваются разработчиками по типу и возможностям заложенных в них средств доступа к базам данных, удобству и полноте интерфейсов. В этом смысле Java не представляет исключения. Уже в версии JDK1.1 появился пакет классов java.sql, обеспечивающий больщинство функций, известных к тому времени разработчикам ODBC-приложений. В этом пакете содержится ряд замечательных классов, например Пример рассматривается в риторике чаще всего в контексте доказательств и аргументов. Для Квинтилиана пример является одним из дополняющих, наглядных доводов к высказыванию, либо упоминанием полезного, настоящего или якобы существующего образца убеждения того, что определено тобой одним. Правда, в отличие от доказательств, связь с предметом обсуждения должна быть установлена прежде автором или оратором.: java.sql.CallableStatement, который обеспечивает выполнение на Java хранимых процедур; java.sql.DatabaseMetaData, который исследует базу данных на предмет ее реляционной полноты и целостности с получением самых разнообразных данных о типах и содержимом таблиц, колонок Колонок, или сибирский колонок (лат.Mustela sibirica) — вид хищных млекопитающих из рода ласок и хорей. По генетическим признакам этот вид ближе всего к европейской норке, поэтому иногда их объединяют в один подрод. Некоторые ученые выделяют сахалинского колонка в самостоятельный вид, называемый итатси — Mustela itatsi. Сейчас там осталось лишь 200—300 итатси, обитающих, в основном, в поймах рек., индексов, ключей и т.д.; наконец, - java.sql.ResultSetMetaData, с помощью которого можно выводить в удобном виде всю необходимую информацию из таблиц базы данных или печатать сами метаданные в виде названий таблиц и колонок.
Однако, коренное отличие Java от других традиционных языков программирования заключается в том, что одни и те же функции доступа к базам данных, с помощью универсальности и кроссплатформенности Java, можно организовать чрезвычайно гибко, используя все преимущества современных объектно-ориентированных технологий, WWW и Intranet/Internet. Рассмотрим по порядку все варианты использования Java-программ при взаимодействии с базами данных.
1. Java-программы и апплеты с интерфейсом JDBC-ODBC
JDBC (Java Database Connectivity) является не протоколом, а интерфейсом и основан на спецификациях SAG CLI (SQL Access Group Call Level Interface - интерфейс уровня вызова группы доступа SQL).
Сам по себе JDBC работать не может и использует основные абстракции и методы ODBC. Хотя в стандарте JDBC API и предусмотрена возможность работы не только через ODBC, а и через использование прямых линков к базам данных по двух- или трех-звенной схеме (см. Рис.1), эту схему используют гораздо реже, чем повсеместно используемый JDBC-ODBC-Bridge занимающий центральное место в общей схеме взаимодействия интерфейсов (см. Рис. 2)
Рис. 1. Непосредственный доступ к базе данных по 3-х-звенной схеме.
Рис. 2. Схема взаимодействия интерфейсов.
Даже беглого взгляда на Рис. 2 вполне достаточно, чтобы понять - общая схема взаимодействия интерфейсов в Java удивительным образом напоминает столь всем знакомую схему ODBC с ее гениальным изобретением драйвер-менеджера к различным СУБД и единого универсального пользовательского интерфейса. JDBC Driver Manager - это основной ствол JDBC-архитектуры. Его первичные функции очень просты - соединить Java-программу и соответствующий JDBC драйвер и затем выйти из игры. Естественно, что ODBC был взят в качестве основы JDBC из-за его популярности среди независимых поставщиков программного обеспечения и пользователей. Но тогда возникает законный вопрос - а зачем вообще нужен JDBC и не легче ли было организовать интерфейсный доступ к ODBC-драйверам непосредственно из Java? Ответом на этот вопрос может быть только однозначное нет. Путь через JDBC-ODBC-Bridge, как ни странно, может оказаться гораздо короче.
- ODBC нельзя использовать непосредственно из Java, поскольку он основан на C-интерфейсе. Вызов из Java C-кода нарушает целостную концепцию Java, пробивает брешь в защите и делает программу трудно-переносимой.
- Перенос ODBC C-API в Java-API нежелателен. К примеру, Java не имеет указателей, в то время как в ODBC они используются.
- ODBC слишком сложен для понимания. В нем смешаны простые и сложные вещи, причем сложные опции иногда применяются для самых простых запросов.
- Java-API необходим, чтобы добиться абсолютно
Абсолютный (лат.absolutus — законченный, неограниченный, безусловный, совершенный) — абсолютный означает то, что рассматривается само по себе, без отношения к чему-либо другому, противопоставляется относительному. чистых Java решений. Когда ODBC используется, то ODBC-драйвер и ODBC менеджер должны быть инсталлированы на каждой клиентской машине. В то же время, JDBC драйвер написан полностью на Java и может быть легко переносим на любые платформы от сетевых компьютеров до мэйнфреймов.
JDBC API - это естественный Java-интерфейс к базовым SQL абстракциям и, восприняв дух и основные абстракции концепции ODBC, он реализован, все-таки, как настоящий Java-интерфейс, согласующийся с остальными частями системы Java.
В отличие от интерфейса ODBC, JDBC организован намного проще. Главной его частью является драйвер, поставляемый фирмой JavaSoft для доступа из JDBC к источникам данных. Этот драйвер является самым верхним в иерархии классов JDBC и называется DriverManager. Согласно, установившимся правилам Internet, база данных и средства ее обслуживания идентифируются при помощи URL.
jdbc::
где под понимается имя конкретного драйвера, или некоего механизма установления соединения с базой данных, например, ODBC. В случае применения ODBC, в URL-строку подставляется именно эта аббревиатура Аббревиатура (итал.abbreviatura от лат.brevis— краткий). В старинных рукописях и книгах сокращённое написание слова или группы слов. В современных изданиях любое сокращённое слово или словосочетание., а в качестве используется обычный DSN (Data Source Valve Source Engine, сокращенно Source («источник»)— игровой движок, разработанный корпорацией Valve. Его особенностями считаются модульная основа и гибкость, синхронизация движения губ с речью, технология выражения эмоций и система физики, работающая по сети. Использует общий для продуктов Valve формат моделей движка .mdl. Физическая часть движка Source включает в себя часть переработанного кода физического движка Havok и принципы физики «тряпичной куклы». Движок может работать с видеокартой, поддерживающей DirectX 8-11. Name), т.е. имя ODBC-источника из ODBC.INI файла. Например:
jdbc:odbc:dBase
В некоторых случаях вместо ODBC может быть использовано имя прямого сетевого сервис Сервис (от лат.servio— быть рабом (невольником), быть порабощённым, в рабстве; лат.а к базе данных, например:
jdbc:dcenaming:accounts-payable,
или
jdbc:dbnet://ultra1:1789/state
В последнем случае часть URL //ultra1:1789/state представляет собой и описывает имя хоста, порт и соответствующий идентификатор для доступа к соответствующей базе данных.
Однако, как уже говорилось выше, чаще всего, все-таки используется механизм ODBC благодаря его универсальности и доступности. Программа Программа - (от греч. — пред, греч. — запись) термин, в переводе означающий «предписание», т.е. взаимодействия между драйвером JDBC и ODBC разработана фирмой JavaSoft в сотрудничестве с InterSolv и называется JDBC-ODBC-Bridge. Она реализована в виде JdbcOdbc.class (для платформы Windows JdbcOdbc.dll) и входит в поставку JDK1.1. Помимо JdbcOdbc-библиотек должны существовать специальные драйвера (библиотеки), которые реализуют непосредственный доступ к базам данных через стандартный интерфейс ODBC. Как правило эти библиотеки описываются в файле ODBC.INI. На внутреннем уровне JDBC-ODBC-Bridge отображает медоды Java в вызовы ODBC и тем самым позволяет использовать любые существующие драйверы ODBC, которых к настоящему времени накоплено в изобилии.
Рассмотрим типичное приложение на Java c доступом к типичному реляционному серверу или даже к обычной dBase-таблице.
// Следующий код на Java используется как пример. Простой подстановкой
// соответствующих значений url, login, и password, и, затем подстановкой
// SQL операторов вы можете посылать их в базу данных.
//--
//
// Module: SimpleSelect.java
//
// Описание: Эта программа для ODBC API интерфейса. Java-приложение
// будет присоединяться к JDBC драйверу, посылать select оператор
// и показывать результаты в таблице
//
// Продукт: JDBC к ODBC Мост
//
// Автор: Karl Moss (С.Дунаев модификация Мод (сокр. от «модификация») — модификация или дополнение к компьютерной игре, написанное, как правило, сторонними разработчиками или любителями с помощью SDK, прилагающегося к игре или специальных, разработанных для модифицирования игр любительских программ. В отличие от адд-она, при его разработке часто радикально изменяет баланс сил (в стратегических играх) или набор оружия и возможности героя (в 3D-шутерах). для работы с кириллицей)
//
// Дата: Апрель 1997
//
// Copyright: 1990-1996
INTERSOLV, Inc.
// This software Программное обеспечение (допустимо также произношение обеспечение), ПО— совокупность программ системы обработки информации и программных документов, необходимых для эксплуатации этих программ (ГОСТ 19781-90). contains
confidential and proprietary
// information of INTERSOLV, Inc.
//--
import java.net.URL;
import java.sql.*;
import java.io.*;
class SimpleSelect {
public static void main (String args[]) {
String url = _jdbc:odbc:dBase_;
String query = _SELECT * FROM my_table_;
try {
// Загрузка jdbc-odbc-bridge драйвера
Class.forName (_sun.jdbc.odbc.JdbcOdbcDriver_);
DriverManager.setLogStream(System.out);
// Попытка соединения с драйвером. Каждый из
// зарегистрированных драйверов будет загружаться, пока
// не будет найден тот, который сможет обработать этот URL
Connection con = DriverManager.getConnection (
url, __, __);
// Если не можете соединиться, то произойдет exception
// (исключительная ситуация). Однако, если вы попадете
// в следующую строку программы, значит вы успешно соединились с URL
// Проверки и печать сообщения об успешном соединении
//
checkForWarning (con.getWarnings ());
// Получить DatabaseMetaData объект и показать
// информацию о соединении
DatabaseMetaData dma = con.getMetaData ();
//System.out.println(_\nConnected to _ + dma.getURL());
//System.out.println(_Driver _ +
//dma.getDriverName());
//System.out.println(_Version _ +
//dma.getDriverVersion());
//System.out.println(__);
// Создать Оператор-объект для посылки
// SQL операторов в драйвер
Statement stmt = con.createStatement ();
// Образовать запрос, путем создания ResultSet объекта
ResultSet rs = stmt.executeQuery (query);
// Показать все колонки и ряды из набора результатов
dispResultSet (rs);
// Закрыть результирующий набор
rs.close();
// Закрыть оператор
stmt.close();
// Закрыть соединение
con.close();
}
catch (SQLException ex) {
// Случилось SQLException. Перехватим и
// покажем информацию об ошибке. Заметим, что это
// может быть множество ошибок, связанных вместе
//
//System.out.println (_\n*** SQLException caught ***\n_);
while (ex != null) {
//System.out.println (_SQLState: _ +
// ex.getSQLState ());
//System.out.println (_Message: _ + ex.getMessage ());
//System.out.println (_Vendor: _ +
//ex.getErrorCode ());
ex = ex.getNextException ();
//System.out.println (__);
}
}
catch (java.lang.Exception ex) {
// Получив некоторые другие типы exception, распечатаем их.
ex.printStackTrace ();
}
}
//-------
// checkForWarning
// Проверка и распечатка предупреждений. Возврат true если
// предупреждение существует
//-------
private static boolean checkForWarning (SQLWarning warn)
throws SQLException {
boolean rc = false;
// Если SQLWarning объект был получен, показать
// предупреждающее сообщение.
if (warn != null) {
System.out.println (_\n *** Warning ***\n_);
rc = true;
while (warn != null) {
//System.out.println (_SQLState: _ +
//warn.getSQLState ());
//System.out.println (_Message: _ +
//warn.getMessage ());
//System.out.println (_Vendor: _ +
//warn.getErrorCode ());
//System.out.println (__);
warn = warn.getNextWarning ();
}
}
return rc;
}
//-------
// dispResultSet
// Показать таблицу полученных результатов
//-------
private static void dispResultSet (ResultSet rs)
throws SQLException, IOException
{
// Объявление необходимых переменных и
// константы для желаемой таблицы перекодировки данных
int i, length, j;
String cp1 = new String(_Cp1251_);
// Получить the ResultSetMetaData. Они будут использованы
// для печати заголовков
ResultSetMetaData rsmd = rs.getMetaData ();
// Получить номер столбца в результирующем наборе
int numCols = rsmd.getColumnCount ();
// Показать заголовок столбца
for (i=1; i<=numCols; i++) {
if (i > 1) System.out.print(_,_);
//System.out.print(rsmd.getColumnLabel(i));
}
System.out.println(__);
// Показать данные, загружая их до тех пор, пока не исчерпается
// результирующий набор
boolean more = rs.next ();
while (more) {
// Цикл по столбцам
for (i=1; i<=numCols; i++) {
// Следующая группа операторов реализует функции перекодировки
// строк из таблиц Богуслав Таблиц (словацк. Bohuslav Tablic (Tablicz); 6 сентября 1769, Ческе Брезово, Словакия — 21 января 1832, Костолне Моравце, Словакия) — чешско-словацкий писатель, священник, деятель возрождения словаков-лютеран, подобно тому как Бернолак является деятелем возрождения словаков-католиков. Таблиц учредил в Пресбурге «Общество чешско-словацкой литературы и языка» с целью издавать на понятном народу чешском языке простонародные и школьные книги. Учреждение этого общества было причиной если не процветания словацкой литературы, то появления в пресбургском лицее кафедры словацкого языка, для чего общество собрало большой капитал. Занять кафедру приглашен был Юрай Палкович. Общество скоро распалось, но кафедра продолжала существовать. Молодёжь имела возможность слушать историю своего народа на родном языке. В 1812 г. Таблиц был одним из основателей нового «Литературного общества Горных Городов» (Bergstdte), задававшегося прежней целью; результатом было открытие кафедры словацкого языка и в Банской Штьявнице. Это общество также скоро распалось. Таблиц писал очень много и по различным специальностям. Первое место занимают его «Poesie» (Вацов, 1806-1812). К ним приложены биографии известных словацких деятелей. Его «Sloventi verovci» (Вацов, 1805-1809) — отрывки из произведений древних словацких писателей, в то время почти уже позабытых. Перу Таблица принадлежит также много книг для народа, изданных двумя упомянутыми обществами.ы базы данных в желаемый формат, потому что в
// различных базах символы могут быть закодированы произвольным
// образом. Если использовать стандартный метод - getString - на выходе
// получается абракадабра. Строки нужно сначала перевести в Unicode,
// затем конвертировать в строку Windows и убрать лидирующие нули
InputStream str1 = rs.getUnicodeStream(i);
byte str2[];
byte str3[];
int sizeCol = rsmd.getColumnDisplaySize(i);
str2 = new byte[sizeCol+sizeCol];
str3 = new byte[sizeCol+sizeCol];
length = str1.read(str2);
// Здесь нужно убрать нули из строки Строки (укр. Строки) — село в Теофипольском районе Хмельницкой области Украины., которые предваряют каждый
// перекодированный символ
k=1;
for (j=1; j<sizeCol*2; j++) {
if (str2[j] != 0) {
str3[k]=str2[j]; k=k+1; } }
String str = new String(str3,cp1);
System.out.print(str);
}
System.out.println(__);
// Загрузка следующего ряда в наборе
more = rs.next ();
}
}
}
В этой простой программе, приводимой во множестве руководств, мною произведено одно небольшое изменение, позволяющее использовать ее для работы с различными базами данных, содержащих таблицы с полями в кириллической кодировке. Дело в том, что хотя Java автоматически производит преобразования из Unicode и обратно в соответствии с установленными на вашей машине языковыми спецификациями (так называемые locale), эти преобразования не всегда действуют по отношению к кириллическим фонтам, особенно, когда кириллические строки прописаны не непосредственно в Java-программе, а передаются из внешних источников, например из баз данных через несколько промежуточных слоев. Та же проблема, как мы увидим далее, возникает и при использовании сервлетов, работающих в тесной взаимоувязке с Web-серверами.
2. Спец-ориентированные Java-приложения
2.1 RMI-приложения
Вызов удаленных методов (RMI - Remote Method Invocation) обеспечивает средства коммуникации между Java программами, даже если они выполняются на разных компьютерах, находящихся в противоположных точках земного шара.
Важная особенность Особенность, или сингулярность в математике - это точка, в которой математический объект (обычно функция) не определён или имеет нерегулярное поведение (например, точка, в которой функция недифференцируема). RMI заключается в том, что он представляет программируемый интерфейс для работы с сетями в отличие от сокетов TCP. Главное преимущество его в том, что он предлагает вам интерфейс более высокого уровеня, основанный на вызовах методов, так, как если бы удаленный объект обрабатывался локально. RMI более удобен и более естественен, чем интерфейс, основанный на сокетах, но он требует выполнения Java-программ на обоих концах соединения. Сетевое соединение, тем не менеее, достигается использованием все того же TCP/IP протокола.
Рассмотрим основные шаги для построения работающего RMI-приложения:
- Разработка удаленных объектов и кодов для сервера и клиента
- Java-компиляция
- RMI-компиляция
- Перемещение .class-файлов в соответствующие директории
- Регистрация
- Старт сервера
- Старт клиента
Следующий ниже пример разработан для клиента и сервера, выполняющихся на одной и той же машине, однако, заложенные здесь принципы Принципы (от лат.princeps — первый) — в армии Древнего Рима — воины тяжёлой пехоты римского легиона в IV—II вв. до н. э. Первоначально из второго имущественного класса, имели защитное вооружение (без поножей), длинные копья и мечи, составляли первую линию в боевом порядке: отсюда название; с III в. до н. э. — воины 30-40 лет, вооруженные мечами и пилумами (короткие метательные копья) и располагавшиеся во второй линии; после второй Пунической войны ставились снова в первой линии. можно с успехом применить для программ, выполняющихся на разных машинах и даже с различной архитектурой. Программа клиента ищет имена и номера телефонов в центральной базе, постоянно резидентной на сервере.
Как работает RMI
Вы определяете Java-интерфейс, чтобы описать каждый объект, который будет дистанционно разделяем, и перечисляeте общие методы, которые могут быть вызваны для объекта. Сервер будет использовать RMI-интерфейс и создаст объекты для вызова, специальным образом зарегистрированные и доступные для вызова по URL-основанной схеме, например:
rmi://localhost/LookupServer
Клиент, используя эту запись, будет пытаться отыскать объект с данным именем, и получить удаленную ссылку к нему. Затем вызванный метод будет обработан с помощью RMI компилятора и преобразован из пользовательского кода в последовательную форму объекта, который передается пользователю с помощью TCP/IP.
Разработка удаленного объектного кода
RMI поддерживает объекты Java, осуществляющие связь через их методы, независимо от того, где эти объекты размещены. Первый шаг для создания класса, к которому можно обратиться дистанционно, - это определение интерфейса, описывающего методы, которые являются дистанционно-разделяемыми.
// Lookup.java
import java.rmi.*;
public interface Lookup extends Remote {
public String findInfo(String info) throws RemoteException;
}
Java.rmi.Remote - пустой интерфейс, который указывает, что это удаленный объект, - так объекты класса, выполняющие Поиск(_Lookup_) отмечены удаленными ссылками. Все методы в удаленном интерфейсе должны быть объявлены через исключение типа Java.rmi.RemoteException, которое активизируется всякий раз, когда метод удаленного вызова дает сбои.
Разработка серверного кода
После того как вы определили интерфейс к удаленному объекту, нужно выполнить следующий шаг - разработать код сервера. Сервер осуществляет объектный интерфейс и создает образцы Образцы — посёлок во Фроловском районе Волгоградской области России. Административный центр Арчединского сельского поселения объекта, который будет дистанционно-разделяем.
Для нашего примера это будет выглядеть следующим образом:
// LookupServer.java
import java.io.*;
import java.util.*;
import java.rmi.*;
import java.rmi.server.*;
public class LookupServer extends UnicastRemote Apple Remote— малогабаритный инфракрасный пульт дистанционного управления (ПДУ) от Apple.Object
implements Lookup {
private Vector save = new Vector();
public LookupServer(String db) throws RemoteException
{
try {
FileReader fr = new FileReader(db);
BufferedReader br = new BufferedReader(fr);
String s = null;
while ((s = br.readLine()) != null)
save.addElement(s);
fr.close();
}
catch (Throwable e) {
System.err.println(_exception_);
System.exit(1);
}
}
public String findInfo(String info)
{
if (info == null)
return null;
info = info.toLowerCase();
int n = save.size();
for (int i = 0; i < n; i++) {
String dbs = (String)save.elementAt(i);
if (dbs.toLowerCase().indexOf(info) != -1)
return dbs;
}
return null;
}
public static void main(String args[])
{
try {
RMISecurityManager security =
new RMISecurityManager();
System.setSecurityManager(security);
String db = args[0];
LookupServer server = new LookupServer(db);
Naming.rebind(_LookupServer_, server);
System.err.println(_LookupServer ready..._);
}
catch (Throwable e) {
System.err.println(_exception: _ + e);
System.exit(1);
}
}
}
Сервер читает в текстовой базе номера телефонов и имена и сохраняет их внутренне. Метод findInfo ищет затем нужное имя и телефон Телефон («дальнозвук» от греч. — далеко и — голос, звук)— устройство для передачи и приёма звука на расстояние. Современные телефоны осуществляют передачу посредством электрических сигналов..
Пример базы данных:
Ivanov, Ivan 295-0083
Petrov, Peter 775-9958
Romanov, Alexander 555-7779
Заметим, что LookupServer является расширением стандартного класса java.rmi.server.UnicastRemoteObject и выполняет Lookup. Один из этих классов обеспечивает некоторые базисные реквизиты, необходимые для удаленных объектов, а другой определяет методы, которые будут вызваны дистанционно.
Установка службы безопасности
Наиболее сложная часть этого кода - то, что происходит в процедуре main(). Первым делом нужно установить защиту. RMI принужден загружать удаленные .class файлы и в этом смысле напоминает какой-нибудь web-браузер с его операциями по загрузке апплетов, что само по себе всегда небезопасно. Если вы не установили защиту, то по умолчанию должны загружаться только локальные файлы, и RMI по определению не может работать с такими ограничениями. Так что вы должны установить security manager, чтобы сделать возможной загрузку удаленных .class файлов.
Образец LookupServer затем регистрируется с помощью службы Naming.rebind и становится доступным клиенту по имени.
Вы могли бы задаться вопросом, как удаленный метод фактически становится вызываемым, если сервер не содержит никакого сетевого кода и никаких TCP/IP примитивов? Это происходит за сценой, поскольку сервер и клиент используют так называемые скелетоны и стабы для коммуникации между собой. Соответствующие .class файлы генерируются из серверного .class файла через RMI транслятор Транслятор— программа или техническое средство, выполняющее трансляцию программы., описанный ниже.
Концептуально, класс stub(заглушка) выглядит так:
public class LookupServer_Stub extends java.rmi.server.RemoteStub
implements Lookup, java.rmi.Remote { ... }
и скелетон - так:
public class LookupServer_Skel implements
java.rmi.server.Skeleton { ... }
Использование команды:
Javap -c LookupServer_Stub
будет показывать байт-код и иллюстрировать то, что происходит за сценой.
Стаб(stub) -это суррогат для удаленного объекта, и скелетон - некая сущность Сущность (лат.Essentia) — то постоянное, что сохраняется в явлении при различных его вариациях, в том числе и временных, сердцевина бытия. Сущность обычно трактуется либо в метафизической, либо в логической плоскости. В метафизике, особенно в томистской, сущность (эссенция) есть источник или основание существования (экзистенции). Синонимами слова сущность часто являются слова идея, назначение, функция. В логике сущность (как существенный признак — лат.essentialia constitutiva) — это неотъемлемое качество, без которого предмет невозможно мыслить. Сущность предмета выражается в его определении. на сервере, которая обрабатывает удаленные вызовы.
Стаб обеспечивает функции приема передачи на стороне клиента, а скелетон - на стороне сервера. При этом производится преобразование объектов в последовательную форму, а проще говоря, в поток байтов Николай Владимирович Байтов (настоящая фамилия Гоманьков, псевдоним произведён от термина байт; род. 23 мая 1951)— российский поэт, прозаик, бук-артист., передаваемых с помощью протокола TCP/IP
Разработка клиентского кода
// LookupClient.java
import java.rmi.*;
import java.rmi.server.*;
public class LookupClient {
public static void main(String args[])
{
try {
RMISecurityManager security =
new RMISecurityManager();
System.setSecurityManager(security);
String host = _localhost_;
String server = _LookupServer_;
String name = _rmi://_ + host + _/_ + server;
Lookup look_obj = (Lookup)Naming.lookup(name);
String results = look_obj.findInfo(args[0]);
if (results == null)
System.err.println(_** not found **_);
else
System.out.println(results);
}
catch (Throwable e) {
System.err.println(_exception: _ + e);
System.exit(1);
}
}
}
Если вы активизируете сервер, выполняя прямой клиентский запрос, то защита для пользователя определяется такая же как и на сервере. URL при этом определяется как:
Rmi://localhost/LookupServer
где localhost - имя локального компьютера (IP, адрес = 127.0.0.1), используемого как сервер. Клиент располагается на той же самой машине. Вы можете также использовать и удаленную главную ЭВМ. Когда вызов к нужному методу сделан, результаты незамедлительно передаются клиенту.
Компиляция кода
Три файла - Lookup.java, LookupServer.java, и LookupClient.java компилируются как и обычно в Java:
javac Lookup.java
javac LookupServer.java
javac LookupClient.java
Выполнение RMI компилятора
После того, как вы откомпилируете эти файлы, выполните RMI Compiler (rmic):
rmic LookupServer
чтобы получить LookupServer_Skel.class и LookupServer_Stub.class файлы.
Вы должны переместить клиентские файлы (Lookup.class, LookupClient.class, и LookupServer_Stub.class) в директорию, откуда вы их желаете выполнять как клиент.
Вы должны переместить серверные файлы (Lookup.class, LookupServer.class, LookupServer_Skel.class, и LookupServer_Stub.class) в директорию, где они станут доступными для публичного доступа.
Регистрация
Объект Объект (лат.objectum— предмет)— философская категория, если определять её в пределах эпистемологии, выражающая нечто, существующее в реальной действительности (то есть независимо от сознания)— предмет, явление или процесс, на которые направлена предметно-практическая и познавательная деятельность субъекта (наблюдателя). В качестве объекта может выступать и сам субъект, в качестве субъекта выступает личность, социальная группа или всё общество., к которому обращаются дистанционно, должен быть введен в регистр объектов, т.е. зарегистрирован. В JDK 1.1 имеется специальная программа
Rmiregistry
Rmiregistry может выполняться или в отдельном окне или как фоновый процесс на сервере.
Старт сервера
Вы должны стартовать сервер по команде:
java LookupServer database_name
К примеру, если ваша база данных с набором имен и телефонов находится в файле C:\PHONE.TXT, то вы должны дать команду:
java LookupServer C:\PHONE.TXT
Старт клиента
Клиентская программа стартуется по команде:
java LookupClient Ivanov
_Ivanov_ - это искомое имя в базе.
Таким образом, RMI дает возможность Возможность — направление развития, присутствующее в каждом явлении жизни; выступает и в качестве предстоящего, и вполне объяснимо рациональным путем: в каждой возможности присутствует вероятная невозможность, «возможность невозможного». Возможность не определяется познанием того, что может быть. Познание вероятностей, возможностей не всегда влияет на нашу возможность. На изучении возможности основывается, главным образом, исследование бытия и события. создавать распределенные Java-to-Java прикладные программы, в которых методы удаленных объектов Java вызываются из других Java-программ на различных главных ЭВМ так как, если бы эти методы вызывались локально. Естественно, что подобные возможности можно эффективно использовать при работе с SQL-серверами, которые предоставляют Java-API интерфейс для доступа к данным. Например, в группе продуктов Informix в Informix Informix— семейство систем управления реляционными базами данных (СУБД), выпускаемых компанией IBM. Informix позиционируется как флагман среди СУБД IBM, предназначенный для онлайновой обработки транзакций (OLTP), а также как СУБД для интегрированных решений. Client SDK дано описание Informix Object Interface for Java, где приводятся многочисленные примеры, как организовать взаимодействующие RMI-приложения с доступом к базам данных Informix. Более того, имеется и соответствующий RMI-сервер, который содержит массу удобных и полезных методов, которые можно вызывать дистанционно. В сущности, приведенный выше пример можно приспособить для работы с любыми базами данных и SQL-серверами, если вы знаете каким образом устроен Java-API интерфейс для доступа к базам данных. В крайнем Крайнем (нидерл.Kraainem; фр.Crainhem)— муниципалитет во Фландрии, часть провинции Фламандский Брабант, расположен в двуязычном избирательном и судебном районе Брюссель-Халле-Вилворде, в непосредственной близости от г. Брюссель, фактически представляя собой часть его восточной периферии. случае не возбраняется и использование JDBC в RMI-приложениях, хотя вряд ли это будет в достаточной степени эффективно. В Informix, например, для непосредственного взаимодействия с базами данных существуют два RMI-пакета: informix.api.remote.rmi - для удаленных клиентов и informix.api.remote.rmi.server - для rmi-сервера. При этом в клиентском приложении используется интерфейс к DBMSManager, который накапливает информацию обо всех серверах Informix и базах данных, и вы можете установить либо локальное, либо удаленное соединение с базой через RMI сервер. Для локального соединения создается DirectDBMSManager объект. Для удаленного соединения создается RMIDBMS-Manager объект и передается к соответствующему RMI серверу. Спецификация RMI сервера осуществляется в форме:
rmi://hostname[:port]/
//Создание DBMSManager объекта
DBMSManager getDBMSManager() throws Exception
{
// based on RMI Checkbox, get appropriate DBMSManager
DBMSManager dbmsManager;
if (RMIcheckbox.getState())
dbmsManager = new RMIDBMSManager(rmiServerTextField.getText());
else
dbmsManager = new DirectDBMSManager();
return dbmsManager;
Само взаимодействие Взаимодействие— философская категория, отражающая процессы воздействия объектов друг на друга, их взаимную обусловленность и порождение одним объектом другого. Взаимодействие— объективная и универсальная форма движения, развития, которая определяет существование и структурную организацию любой материальной системы. с базой осуществляется с помощью специальных транзакционных методов и методов управления курсором, которые могут вызываться как локально, так и дистанционно. В различных базах и SQL-серверах это может осуществляться по разному, но если сервер кроссплатформенный Кроссплатформенное программное обеспечение— программное обеспечение, работающее более чем на одной аппаратной платформе и/или операционной системе. Типичным примером является программное обеспечение, предназначенное для работы в операционных системах Linux и Windows одновременно. - единый и универсальный Java-API интерфейс играет немаловажную роль.
2.1 Java, инкапсулированная в СУБД
Java может быть встроена в СУБД множеством различных способов и при этом всегда достигается решение сразу нескольких задач:
- Применение полноценного языка программирования для написания хранимых процедур. В сервер встраивается виртуальная машина Java и внутренний интерфейс JDBC. Встраивание мощного и безопасного языка программирования позволяет обойти ограничения хранимых процедур на языке SQL.
- Расширение объектных типов данных. Объекты, написанные на языке Java могут храниться в виде значений в реляционной таблице. Это позволяет создавать и использовать произвольные типы данных. Java-класс может быть использован в качестве типа данных для столбца таблицы. Каждое поле такой записи становится экземпляром соответствующего Java-класса. В качестве примера возьмем простой класс на языке Java, хранящий адреса. Прикладной код может быть включен в методы класса. Например, строковые данные могут содержаться только в полях Street и Postal Code(почтовый код), а значение поля City может вычисляться на основе почтового индекса. Более того, можно использовать наследование классов и методов. При этом допускается перегрузка методов в зависимости от используемого класса. Так можно создать классы
Класс (от лат.classis— группа) в классификации— группа предметов или явлений, обладающих общими признаками. US_Address и Rus_Address, унаследованные от базового класса Address. В каждом таком классе могут быть разные методы определения городов по почтовому индексу и методы проверки его значений, естественно разные для России и США. Даже сам SQL может использоваться для доступа к Java-объектам, как это уже сделано в Sybase Sybase— дочерняя компания SAP AG, разработчик программного обеспечения для обработки данных: СУБД, средств моделирования баз данных и приложений обработки данных, средств анализа данных, технологий для корпоративного использования портативной электроники. Adaptive Server.
Следующий пример вставляет новую запись в таблицу:
INSERT INTO employees (id, name, Address)
VALUES(1789, _Serg Dunaev_, new Rus_Address(_58 Gagarin Street_, _153038_)
)
Следующий запрос с использованием Java-объектов возвращает список сотрудников, живущих на указанной улице:
SELECT SELECT ("селект") — оператор DML языка SQL, возвращающий набор данных (выборку) из базы данных, удовлетворяющих заданному условию. name
FROM employees
WHERE Rus_Address.street="Gagarin Street"
Единая программная модель. Впервые прикладные программные компоненты можно будет перемещать между клиентскими программами, серверами приложений и СУБД. Разработчики смогут использовать единую программную модель на всех уровнях информационной системы. Произвольная программа на Java состоит из набора классов. Для их использования необходимо провести инсталляцию Java-классов в СУБД. Классы Класс (от лат.classis— группа) в классификации— группа предметов или явлений, обладающих общими признаками. должны быть откомпилированы в байт-код и тем самым, готовы для использования в любой виртуальной машине. В связи с использованием виртуальной машины для исполнения методов на Java и встроенной поддержке интерфейса JDBC, один и тот же объект на языке Java может быть использован как внутри, так и вне СУБД.
3. Java-сервлеты
Если апплеты расширяют функциональность Web-браузеров, то сервлеты расширяют функциональность Web-серверов и являются мощным средством программирования. В последнее время многие предпочитают обыкновенным апплетам, загружаемым локально или удаленно, именно сервлеты, которые не нужно никуда загружать и, которые всегда выполняются в контексте Web-сервера, обеспечивая, в отличие от обычных CGI-процессов или скриптов, куда более развитые возможности.
3.1 Сервлеты на базе Java Web Server
Сервлеты являются объектами, которые образуют специфический интерфейс, с помощью которого их можно свободно встраивать в Java-ориентированные Web-сервера. В отличие от апплетов, они являются облегченными Java-объектами (без графики и GUI-компонентов), но зато, будучи кроссплатформенными и динамически загружаемыми и, используя все возможности Java, они могут использовать практически любой HTML и взаимодействовать с любым браузером. Естественно, что сервлеты можно использовать и используют для доступа к базам данных, программируя все удаленные операции с базой из браузера. В настоящее Настоящее— часть линии времени, состоящая из событий, которые происходят в настоящий момент, то есть определенная область пространства-времени. время большинство Web серверов поддерживают технологию сервлетов. Java Web-Server хорош тем, что что он наиболее полно реализует эту технологию. Стандартный Servlet-API реализован как в самом Java Web Server, так и в отдельном продукте JSDK, но начиная с версии 1.2, он включен в состав Состав — предмет (вещество), включающей в себя много частей (компонентов), а также описание качества, количества и иных характеристик частей такого предмета (вещества). JDK. Характерной особенностью сервлетов является то, что они не требуют создания новых процессов при каждом новом запросе. Множество сервлетов выполняются параллельно в рамках одного процесса на сервере и по своей производительности превосходят как CGI, так и Fast-CGI приложения (см. Рис.3).

Рис. 3. Возможные процессы на Web-сервере.
Несмотря на то, что сервлеты используют HTTP-протокол, им нет необходимости перезагружать процесс при каждом новом запросе и это также повышает их быстродействие. К сожалению, когда вы используете сервлеты, опять-таки, возникает проблема использования кириллических символов. Дело в том, что стандартный путь прохождения данных тут не действует, потому что Web-сервер при старте запускает так называемый Java-handler, которому передает на выполнение все Java-сервлеты и обменивается вводом-выводом именно с ним через специальную библиотеку классов. Поэтому, если вы хотите получать в браузере от вашего Web-сервера, который исполняет сервлеты, кириллические строки, вам надо использовать вместо стандартных примитивов ввода/вывода некоторые специальные методы для работы со строками, например:
// Определение необходимого кодификатора
// в зависимости от используемого типа кодировки
String dos = new String(_Cp866_);
String win = new String(_Cp1251_);
String iso = new String(_8859_5_);
String im = new String(_Кириллический текст_);
.......................................................
out.println(_<body>_);
//out.write(im.getBytes(dos));
out.write(im1.getBytes(win));
//out.write(im2.getBytes(iso));
out.println(_</body></html>_);
Но и весьма эффективная функция Java - getBytes() не действует, когда вы извлекаете данные при помощи сервлетов из баз данных. Здесь необходимо применить метод, который мы уже использовали при работе с базами данных при помощи интерфейса JDBC. Кроме того, файл font.properties в каталоге $JDK_HOME/lib или в специальном каталоге вашего браузера должен быть соответствущим образом настроен. Во многих пакетах Java имеются образцы файла font.properties.ru, который можно взять в качестве основы. Если вы работаете с уже русифицированным Web-сервером, например, русской версией Apache, то он позаботится за вас и сам перекодирует данные, поступающие из базы данных от сервлета. Каким образом программируются операции с базой данных в сервере? Сервлет не накладывает никаких ограничений на использование интерфейсов с базой данных. Можно использовать обыкновенный JDBC-ODBC, или специфические драйвера ориентированные на конкретные SQL-сервера и базы данных. Рассмотрим типичный DBServlet.java, который с успехом будет выполняться как на Java Web Server, так и Web сервере Apache.
/*
* @(#)DBServlet.java 1.6 97/06/13
*/
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import java.net.*;
import Реимпорт— ввоз товаров, ранее вывезенных, но не переработанных. java.sql.*;
/**
* DBServlet
*
* Этот сервлет демонстрирует как использовать JDBC стек
* и получать доступ к базам
данных при помощи сервлетов. Для того, чтобы выполнить этот
* сервлет, переменные CLASSPATH, LD_LIBRARY_PATH, ODBCINI
* должны быть соответствующим образом установлены.
*/
public class DBServlet extends HttpServlet {
/**
* init method
*/
public void init(ServletConfig conf) throws ServletException {
super.init(conf);
}
/**
* service method
*/
public void service(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException
{
String stack, username,
password, query;
Connection con;
PrintStream out;
/* ServletOutputStream out = res.getOutputStream();*/
// Загрузка параметров. Именно эти параметры должны будут
вводиться
// в специально прорисованном окне браузера, с которым будет
// взаимодействовать наш сервлет
stack = req.getParameter(_stack_);
username = req.getParameter(_username_);
password = req.getParameter(_password_);
query = req.getParameter(_query_);
res.setContentType(_text/html_);
out = new PrintStream(res.getOutputStream());
printPageHeader(out);
// в том случае, если параметры отсутствуют
if (stack == null || username == null || password == null ||
query == null) {
printPageFooter(out);
return;
}
String url = _jdbc:odbc:_+stack;
out.println(_<hr><h3>Previous Query</h3>_);
out.println(_<pre>_);
out.println(_Database Stack : _+stack);
out.println(_ User ID : _+username);
out.println(_ Password : _+password);
out.println(_ Query : _+query);
out.println(_</pre>_);
try {
// Найти jdbc стек. Может
существовать несколько
зарегистрированных драйверов
Class.forName(_sun.jdbc.odbc.JdbcOdbcDriver_);
//Class.forName(_jdbc.odbc.JdbcOdbcDriver_);
// Получить соединение Соединение — процесс изготовления изделия из деталей, сборочных единиц (узлов), агрегатов путём физического объединения в одно целое. Показатели работоспособности соединения — это прочность и(ли) герметичность, а также технологичность. Является основной частью производственного процесса сборки. с базой данных
con = DriverManager.getConnection(url, username, password);
out.println(_<hr>_);
out.println(_<h3>ODBC Driver and Database Messages</h3>_);
checkForWarning(con.getWarnings(), out);
DatabaseMetaData dma = con.getMetaData();
out.println(_Connected to _ + dma.getURL() + _<br>_);
out.println(_Driver _ + dma.getDriverName() + _<br>_);
out.println(_Version _ + dma.getDriverVersion() + _<br>_);
// Создать и выполнить запрос. Конкретный оператор SQL
// вводится удаленным
пользователем в окне его браузера
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery(query);
// Печать результатов.
Они переназначаются на стандартный вывод
// и поступают в браузер клиента
dispResultSet(rs, out);
rs.close();
stmt.close();
con.close();
out.println(_<hr>_);
}
catch (SQLException ex) {
out.println(_<hr>*** SQLException caught ***_);
while (ex != null) {
out.println(_SQLState: _ + ex.getSQLState() + _<br>_);
out.println(_Message: _ + ex.getMessage() + _<br>_);
out.println(_Vendor: _ + ex.getErrorCode() + _<br>_);
ex = ex.getNextException();
}
}
catch (java.lang.Exception ex) {
ex.printStackTrace();
}
printPageFooter(out);
}
/**
* возврат запрошенной
информации
*/
public String getServletInfo() {
return _Это простой сервлет,
который показывает как
использовать JDBC_;
}
/*
* проверка и печать информации сервера
*/
private void checkForWarning(SQLWarning warn, PrintStream out)
throws SQLException
{
boolean rc = false;
if (warn != null) {
out.println(_<hr>*** Warning ***_);
rc = true;
while (warn != null) {
out.println(_SQLState: _ + warn.getSQLState() + _<br>_);
out.println(_Message: _ + warn.getMessage() + _<br>_);
out.println(_Vendor: _ + warn.getErrorCode() + _<br>_);
warn = warn.getNextWarning();
}
}
}
/*
* Показ результатов запроса в табличном html формат Формат— стандартизирование формы построения (и подачи) того или иного предмета (объекта), явления или процесса.е
*/
private void dispResultSet(ResultSet rs, PrintStream out)
throws SQLException, IOException
{
int i;
// метаданные Данные (калька от лат.data) — это представление фактов и идей в формализованном виде, пригодном для передачи и обработки в некотором информационном процессе. используются для получения информации о схеме
ResultSetMetaData rsmd = rs.getMetaData();
int numCols = rsmd.getColumnCount();
out.println(_<hr>_);
out.println(_<h3>Database Columns and Data</h3>_);
out.println(_<table border=3>_);
out.println(_<tr>_);
for (i=1; i<=numCols; i++) {
out.println(_<th>_ + rsmd.getColumnLabel(i) + _</th>_);
}
out.println(_</tr>_);
// для всех данных
while (rs.next()) {
out.println(_<tr>_);
// for one row
for (i=1; i<=numCols; i++) {
dispElement(rs, rsmd.getColumnType(i), out, i);
}
out.println(_</tr>_);
}
out.println(_</table>_);
}
// печать одного элемента
private void dispElement(ResultSet rs, int dataType,
PrintStream out, int col)
throws SQLException, IOException
{
String cp1 = new String(_Cp1251_);
// в зависимости от типа
данных, определяем различные типы обработки
switch(dataType) {
case Types.DATE:
java.sql.Date date = rs.getDate(col);
out.println(_<th>_ + date.toString() + _</th>_);
break;
case Types.TIME:
java.sql.Time time = rs.getTime(col);
out.println(_<th>_ + time.toString() + _</th>_);
break;
case Types.TIMESTAMP:
java.sql.Timestamp timestamp = rs.getTimestamp(col);
out.println(_<th>_ +
timestamp Timestamp может ссылаться на time code или digitally signed timestamp, который предназначен для подтверждения существования определённого документа в определённое время, как часть электронной подписи..toString() + _</th>_);
break;
case Types.CHAR:
case Types.VARCHAR:
case Types.LONGVARCHAR:
String str = rs.getString(col);
// Возможно, что здесь вам
понадобятся кириллические
преобразования
out.println(_<th>_ + str + _</th>_);
break;
case Types.NUMERIC:
case Types.DECIMAL:
java.math.BigDecimal numeric = rs.getBigDecimal(col, 10);
out.println(_<th>_ + numeric.toString() + _</th>_);
break;
case Types.BIT:
boolean bit = rs.getBoolean(col);
out.println(_<th>_ + new Boolean(bit) + _</th>_);
break;
case Types.TINYINT:
byte tinyint = rs.getByte(col);
out.println(_<th>_ + new Integer(tinyint) + _</th>_);
break;
case Types.SMALLINT:
short smallint = rs.getShort(col);
out.println(_<th>_ + new Integer(smallint) + _</th>_);
break;
case Types.INTEGER:
int integer = rs.getInt(col);
out.println(_<th>_ + new Integer(integer) + _</th>_);
break;
case Types.BIGINT:
long bigint = rs.getLong(col);
out.println(_<th>_ + new Long(bigint) + _</th>_);
break;
case Types.REAL:
float real = rs.getFloat(col);
out.println(_<th>_ + new Float(real) + _</th>_);
break;
case Types.FLOAT:
case Types.DOUBLE:
double Число двойной точности (Double precision, Double) — компьютерный формат представления чисел, занимающий в памяти две последовательных ячейки (компьютерных слова; в случае 32-битного компьютера — 64 бита или 8 байт). Как правило, обозначает формат числа с плавающей запятой стандарта IEEE 754. Числа с плавающей точкой (двойной/одинарной/четверной точности) поддерживаются сопроцессором (в 80386 выполнен как отдельный модуль, начиная с 80486 является встроенным в главный процессор. Сопроцессор, хотя он сейчас и является частью главного процессора, принято называть FPU — Floating Point Unit, буквально Модуль Плавающей Запятой). longreal = rs.getDouble(col);
out.println(_<th>_ + new Double(longreal) + _</th>_);
break;
case Types.BINARY:
case Types.VARBINARY:
case Types.LONGVARBINARY:
byte[] binary = rs.getBytes(col);
out.println(_<th>_ + new String(binary, 0) + _</th>_);
break;
}
}
private void printPageHeader(PrintStream out) {
out.println(_<html>_);
out.println(_<head>_);
out.println(_<tltle>
Типичный сервлет для работы
с базами данных
</title>_);
out.println(_</head>_);
out.println(_<body>_);
out.println(_<center><font size=5>_ +
_<b>Jeeves Database Servlet</b>_ +
_</font></center>_);
out.println(_<hr>_);
out.println(_<form action=\_/servlet/dbServlet\_ method=\_get\_>_);
out.println(_<pre>_);
out.println(_ODBC DSN : <input type=textarea name=stack>_);
out.println(_ User ID : <input type=textarea name=username>_);
out.println(_ Password : <input type=textarea name=password>_);
out.println(_ SQL Query :
<input type=textarea name=query>_);
out.println(_</pre>_);
out.println(_<input type=
submit>_);
out.println(_</form>_);
}
private void printPageFooter(PrintStream out) {
out.println(_</body>_);
out.println(_</html>_);
out.flush();
}
}
В этой программе содержатся пакеты классов для поддержки сервлетов - javax.servlet.* и javax.servlet.http.*, которые находятся в специальном продукте фирмы JavaSoft JSDK1.0.1 или непосредственно в JDK1.2.
Главная вещь, которую необходимо при этом понять, - это каким образом извлекаются переданные сервлету аргументы на вводе и каким образом передаются ответные параметры на выводе.
public void service (HttpServletRequest req,
HttpServletResponse res) throws
ServletException,
IOException
{
...
}
Специальный метод request содержит список параметров, которые могут быть извлечены при помощи HttpServletRequest::getParameterNames метода.
stack = req.getParameter(_stack_);
возвращает вам значение Значение— ассоциативная связь между знаком и предметом обозначения. вами же определенного в htm-форме параметра stack, в котором вы можете задавать с клавиатуры имя ODBC-источника (ODBC DSN).
Можно установить специальный цикл обработки для извлечения каждого параметра, переданного из HTML-формы, когда она направлена для обработки к сервлету:
while ( values.hasMoreElements() )
{
...
}
Имя и значение каждого извлекаемого параметра можно получать во время работы цикла.
String name, value;
name = (String)values.nextElement();
value = req.getParameter (name);
Этих знаний вполне достаточно для того, чтобы начать писать простые сервлеты, расширяющие функциональность JavaServer"а для обработки форм, вместо того, чтобы писать cложные CGI. Имеется, впрочем, еще одна проблема Проблема (др.-греч. ) — положение, причинность, условие, вопрос, объект, который создаёт затруднение, побуждает к действию и связан с избыточностью или недостатком чего либо для сознания субъекта,например: процессора (движителя, калькулятора, компьютера,специалиста), знаний, ресурсов, регламента (упорядоченности, алгоритма, программы) и побуждает к действию или ограничивает его и соответственно неразрешён или нежелателен. В природе, вне деятельности человека, проблемы находят естественное разрешение и в последовательности движения форм материи есть этап в наблюдениях формализуемый человеком. Отличие природного процесса, разрешение проблемы как результат законов природы. Сущность проблемы для человека такова, что требует анализа, оценки, формирования идеи, концепции для поиска ответа (решение проблемы) с проверкой и подтверждением опытом. В природе это: Вода течёт вниз. Ветер качает деревья. Вода камень точит. и др., что естественно и непротиворечиво. ПРОБЛЕМОЙ преимущественно называется вопрос, не имеющий однозначного решения (степень неопределённости). Неопределённостью проблема отличается от задачи. Совокупность возможных вопросов взаимосвязанных объектом рассмотрения называется проблематикой., которую также необходимо изучить - обработка событий и исключительных ситуаций. Убедитесь, что вы специфицировали этот сервис и init методы в вашем подклассе HttpServlet как ServletException:
public void init
(ServletConfig conf) throws ServletException
...
public void service (HttpServletRequest req,
HttpServletResponse res)
throws ServletException, IOException
...
Внутри DBServlet сервлета метод service может использовать один или несколько блоков try/catch, которые обеспечивают пользователю или программисту обработку событий, связанных с некоторыми неверными действиями или ситуациями. В первом блоке try пользователь может обработать ситуацию при возникновении проблемы соединения с сервером базы данных или выполнении sql-запроса. Второй Второй — второй по счёту альбом песен Владимира Высоцкого в исполнении Григория Лепса, записанный и вышедший в 2007 году блок try можно использовать по своему усмотрению, например, при записи результатов в файл и последующей проверке - должным ли образом он закрыт перед выходом из обслуживающей процедуры. Если нет - в стандартное устройство Устройство(также прибор, жарг.девайс— от англ.device)— рукотворный объект со сложной внутренней структурой, созданный для выполнения определённых функций, обычно в области техники. вывода выдается соответствующая трассировка.
Эту программу легко модифицировать в соответствии с вашими нуждами и получать не только содержимое таблиц и колонок, но и любые метаданные Потому в стандартном пакете java.sql содержится гораздо больше методов, чем те, которые предлагают стандартные средства для построения стандартных ODBC-приложений.
3.2 Сервлеты на базе Apache
Для тех, кто имеет дело с различными компьютерными платформами и стремится к универсализму, выбор Apache HTTP-сервера является, пожалуй, самым подходящим. Разве плохо, когда написанные вами модули могут работать и на ПК и на многопроцессорных высокопроизводительных системах, причем инсталляция и компоновка Компоновка (лат.componere — «складывать, строить, сочинять») — расположение, структуризация отдельных частей в целостном объекте. рабочих программ, как правило не требуется, дело сводится к простому копированию. Можно, не выходя из офиса, перемещать рабочие программы в специальные каталоги Web-сервера, находящегося за тридеять земель, и они мгновенно могут быть востребованы десятками пользователей, которым нет необходимости загружать их на свои компьютеры Компьютер (англ.computer— «вычислитель»), электронная вычислительная машина (ЭВМ)— вычислительная машина, предназначенная для передачи, хранения и обработки информации.. До недавнего времени все Web-серверы могли вызывать на выполнение только три типа процессов: CGI, ISAPI или NSAPI, причем два последних чаще всего были реализованы на Wintel-платформе. Так, с появлением Delphi-3 многие стали предлагать свои разработки в виде Web-модулей, но аппетиты пользователей умерялись разработчиками, которые могли предложить только вариант Web, работающий под Windows Microsoft Windows (/wndoz/) (англ.windows— окна)— семейство проприетарных операционных систем корпорации Майкрософт (Microsoft), ориентированных на применение графического интерфейса при управлении. Изначально были представлены многофункциональными надстройками для MS-DOS.-95/NT, и для связи с СУБД на больших машинах приходилось применять некое подобие Gateway-ODBC. Такой вариант Вариант (фр.variante, от лат.varians, родительный падеж variantis — меняющий, изменяющийся) — одна из нескольких редакций какого-либо произведения (литературного, музыкального и т. п.) или официального документа; видоизменение какой-либо части произведения (разночтения отдельных слов, строк, строф, глав). не всегда оказывался эффективным, тем более, что протокол HTTP при каждом новом запросе требовал перезагрузки модуля Применение сервлетов в связке с СУБД решает эту проблему. Для Apache существует специальный программный компонент JServ, который также как и сам сервер в исходных кодах распространяется совершенно бесплатно. При запуске Apache автоматически стартует Java-обработчик, которому и будут передаваться на исполнение все запросы, связанные с запуском Java-программ. Наоборот, весь вывод из Java переадресуется непосредственно в Web, который аккуратным образом передает его запросившему браузеру. Скорость Скорость (часто обозначается , от англ.velocity или фр.vitesse)— векторная физическая величина, характеризующая быстроту перемещения и направление движения материальной точки в пространстве относительно выбранной системы отсчёта (например угловая скорость). Этим же словом может называться скалярная величина, точнее модуль производной радиус-вектора. выполнения Java-приложений зависит от производительности компьютера, на котором сконфигурирован Web-сервер Apache. Если это, к примеру UltraSparc-3000 c Java-виртуальной машиной HotSpot, то скорость может быть очень большой, в десятки, а то и в сотни раз быстрее, чем на обычной NT-машине. Apache Apache HTTP-сервер (произносится /.p.i/, сокращение от англ.a patchy server) — свободный веб-сервер., в отличие от браузеров не имеет собственной виртуальной машины Java, а настраивается на ту, которая сгенерирована для данной платформы. Такой подход чрезвычайно гибок, ибо позволяет постоянно обновлять Java-среду, наращивать библиотеку классов и ничего не изменять в настройках Apache. Впрочем, и в самих конфигурационных файлах Apache для программистов имеется масса полезных вещей, они свободно корректируются, открыты для добавлений и предоставляют гораздо больше простора для маневра по сравнению с жестко запрограммированными системами для администрирования Web-узлов, такими как Fastrack, или Java Web Server. Для того, чтобы использовать Apache во взаимодействии с Java, необходимо инсталлировать продукт Jserv, содержащий необходимые библиотеки Java-классов, затем изменить конфигурационный файл Apache Configuration, добавив в него строку:
Module jserv_module mod_jserv.o
(модуль mod_jserv.c должен находиться при этом в src/директории Apache). После этого необходимо рекомпилировать Apache с помощью программы make. Затем можно изменить основной конфигурационный файл Apache httpd.conf, добавив в него строки вида:
<IfModule mod_jserv.c>
ServletProperties conf/servlet.properties
ServletPort 8007
ServletBinary /opt1/jdk1.1.5/bin/java
ServletClassPath /opt1/jdk1.1.5/lib/classes.zip
ServletClassPath /opt1/local/etc/httpd/jserv/lib/servclasses.zip
ServletClassPath /opt1/local/etc/httpd/jserv/classes
ServletClassPath /opt1/JSDK1.0.1/lib/classes.zip
ServletErrorLog
logs/jserv_log
ServletAlias
/servlets /opt1/local/etc/httpd/
jserv/servlets
ServletAuthExport Off
# AddHandler
jhtml-parser .jhtml
# Action jhtml-parser
/servlets/
org.apache.jserv.JServSSI
</IfModule>
Разумеется, в каждом конкретном случае директории могут быть разными, однако, сразу после старта Apache HTTP-сервера по команде httpd, он автоматически запускает Java-обработчик, который и будет загружать и исполнять все запрошенные сервлеты, в том числе и те, которые будут работать с базами данных. Преимущество Apache при работе с базами данных заключается в том, что поскольку он, также как и Java, доступен в исходных кодах, можно эффективно использовать его расширяемую архитектуру и дополнять его различными промежуточными фильтрами на Java и на языке C, которые, по усмотрению разработчиков могут выполнять различные полезные функции.
Заключение
Перечисленные методы не исчепывают возможности использования Java-программ при работе с базами данных. Следует учесть, что технологии постоянно развиваются, совершенствуются и пополняются новыми стандартами. Совсем недавно Microsoft объявила о создании новых стандартов RDO, ADO и OLE DB. Эти разработки, также как JDBC движутся в направлении объектно-ориентированных технологий и основаны на классах, которые могут быть применены в JDBC. В то же время и JDBC развивается и в скором времени появится язык JSQL, который уже анонсировали некоторые компании Юридическое лицо— созданная и зарегистрированная в установленном законом порядке организация, которая имеет в собственности, хозяйственном ведении или оперативном управлении обособленное имущество и отвечает по своим обязательствам этим имуществом, может от своего имени приобретать и осуществлять имущественные и личные неимущественные права, нести обязанности, быть истцом и ответчиком в суде. Юридические лица должны иметь самостоятельный баланс или смету.. В этом случае, SQL операторы можно будет встраивать в Java программы, а не передавать их как строковые переменные Переменная— атрибут физической или абстрактной системы, который может изменять своё значение. Значение может меняться в зависимости от контекста, в котором рассматривается система, или в случае уточнения, о какой конкретно системе идёт речь. Концепция переменной широко используется в таких областях как математика, естественные науки, техника и программирование. Примерами переменных могут служить температура воздуха, параметр функции и многое другое. В широком смысле, переменная характеризуется лишь множеством значений, которые она может принимать. в Java-методы. Встроенный SQL-препроцессор позволит программистам использовать Java-переменные в SQL операторах.
Сергей Борисович Дунаев, Ивановский государственный энергетический университет.
|