Доступ к базам данных из Javaпрограмм и проблемы русификации

       

Установка службы безопасности



Установка службы безопасности

Наиболее сложная часть этого кода - то, что происходит в процедуре 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) -это суррогат для удаленного объекта, и скелетон - некая сущность на сервере, которая обрабатывает удаленные вызовы.

Стаб обеспечивает функции приема передачи на стороне клиента, а скелетон - на стороне сервера. При этом производится преобразование объектов в последовательную форму, а проще говоря, в поток байтов, передаваемых с помощью протокола 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 файлы.

Перемещение.class файлов в соответствующее им место на диске

Вы должны переместить клиентские файлы (Lookup.class, LookupClient.class, и LookupServer_Stub.class) в директорию, откуда вы их желаете выполнять как клиент.

Вы должны переместить серверные файлы (Lookup.class, LookupServer.class, LookupServer_Skel.class, и LookupServer_Stub.class) в директорию, где они станут доступными для публичного доступа.

Регистрация

Объект, к которому обращаются дистанционно, должен быть введен в регистр объектов, т.е. зарегистрирован. В 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 Client SDK дано описание Informix Object Interface for Java, где приводятся многочисленные примеры, как организовать взаимодействующие RMI-приложения с доступом к базам данных Informix. Более того, имеется и соответствующий RMI-сервер, который содержит массу удобных и полезных методов, которые можно вызывать дистанционно. В сущности, приведенный выше пример можно приспособить для работы с любыми базами данных и SQL-серверами, если вы знаете каким образом устроен Java-API интерфейс для доступа к базам данных. В крайнем случае не возбраняется и использование 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-серверах это может осуществляться по разному, но если сервер кроссплатформенный - единый и универсальный Java-API интерфейс играет немаловажную роль.


Содержание раздела