Студопедия  
Главная страница | Контакты | Случайная страница

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатика
ИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханика
ОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторика
СоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансы
ХимияЧерчениеЭкологияЭкономикаЭлектроника

Часть 8. Обработка сетевых данных

Читайте также:
  1. Betfair для начинающих. Часть вторая
  2. Betfair для начинающих. Часть первая
  3. Betfair для начинающих. Часть третья
  4. Betfair для начинающих. Часть четвертая
  5. FM передатчик начинающего радиопирата. Часть№2
  6. I часть
  7. I.2.3. Обработка исходных данных в режиме таблицы
  8. II Практическая часть
  9. II часть
  10. II. Основная часть

 

Для обработки сетевых данных в Java применяется технология вызова удаленных методов (RMI – Remote Method Invocation), реализованная в пакетах java.rmi и java.rmi.server. Эта технология позволяет разрабатывать мощные сетевые приложения, облегчая задачи программиста по организации доступа к сетевым данным. Она расширяет возможности технологии «клиент-сервер» за счет определения сервером объектов для использования сетевыми клиентами. Клиенты получают возможность работать с сетевыми данными таким же образом, если б они были локальными, внутри той же виртуальной машины, что и клиент. RMI скрывает от пользователя рутинные операции по организации обмена данными, транспортировки параметров методов и возвращаемых значений через сеть. Для создания приложений с использованием RMI необходимо произвести следующие действия:

· создать интерфейс на базе java.rmi.Remote, в котором определены экспортируемые методы, реализуемые на уровне сервера. Каждый метод этого интерфейса при этом должен обладать возможностью генерации исключений java.rmi.RemoteException для предотвращения сетевых коллизий;

· определить класс, производный от java.rmi.server, реализующий сетевой интерфейс. Например, UnicastRemoteObject, который представляет серверный объект с автоматической обработкой данных;

· создать программу, реализующую экземпляр сетевого объекта на сервере и организовать доступ к ней на основе регистрации имени объекта в службе реестра с помощью класса java.rmi.Naming. Такая серверная программа может сама выполнять функции сервера реестра, используя класс LocateRegistry;

· после компиляции серверной программы с помощью команды javac, запустить утилиту rmic для генерации к сетевому объекту заглушки (stub) и каркаса (skeleton). Технология RMI не предусматривает организации взаимодействия клиента с сервером, так как на стороне клиента ссылка на объект сетевых данных реализуется в виде экземпляра класса заглушки. Заглушка производит сетевые операции по передаче вызова классу каркасу на сервере, который и передает возвращаемые методом значения заглушке, а затем клиенту. При запуске утилиты rmic с указанием имени сетевого класса объекта автоматически будут созданы два новых класса с суффиксами _Stub и _Skel;

· запустить сервер реестра вызовом программы rmiregistry;

· теперь создать клиентскую программу, использующую экспортированный сервером сетевой объект с полученной на него ссылкой в форме rmi:URL. Далее методы сетевого объекта можно вызывать так же как и локального.

Пример 8.1. Сетевое банковское обслуживание на основе класса Bank, содержащего внутренние классы и интерфейсы клиент-серверной банковской системы:

· RemoteBank – сетевой интерфейс, реализуемый сервером и используемый клиентом банка;

· FunnyMoney – простейший класс для представления денег банковского обслуживания;

· BankingException – подкласс исключений для предотвращения различных коллизий, например, «недостаток денежных средств»;

· Client – класс, являющийся автономной программой, выполняющей функции клиента банковского сервера. Он использует метод Naming.Lookup() для поиска в системном реестре нужного объекта RemoteBank с последующим вызовом различных методов этого объекта.

 

package Bank.java;import java.rmi.*;import java.util.List; /** * Этот класс является контейнером, содержащим другие классы * и интерфейсы банковской системы. **/public class Bank { /** * Интерфейс, определяющий методы, экспортируемые * банковским сервером. **/ public interface RemoteBank extends Remote { /** открытие счета с указанием имени и пароля */ public void openAccount(String name, String password) throws RemoteException, BankingException; /** закрытие счета */ public FunnyMoney closeAccount(String name, String password) throws RemoteException, BankingException; /** снятие денег со счета */ public void deposit(String name, String password, FunnyMoney money) throws RemoteException, BankingException; /** снятие денежной суммы со счета */ public FunnyMoney withdraw(String name, String password, int amount) throws RemoteException, BankingException; /** возвращение суммы, хранящейся на счете */ public int getBalance(String name, String password) throws RemoteException, BankingException; /** * возвращение списка строк с проводками счета **/ public List getTransactionHistory(String name, String password) throws RemoteException, BankingException; } /** * класс денежного счета. **/ public static class FunnyMoney implements java.io.Serializable { public int amount; public FunnyMoney(int amount) { this.amount = amount; } } /** * тип исключений для предотвращения различных коллизий **/ public static class BankingException extends Exception { public BankingException(String msg) { super(msg); } } /** * клиентская программа, взаимодействующая с сервером * RemoteBank при помощи RMI. **/ public static class Client { public static void main(String[] args) { try { // определение места RemoteBank для соединения String url = System.getProperty("bank", "rmi:///FirstRemote"); // поиск сервера RemoteBank с использованием объекта Naming // по заданному url вызов возвращает объект // RemoteBank, методы которого используются в сети RemoteBank bank = (RemoteBank) Naming.lookup(url); // преобразование команды пользователя String cmd = args[0].toLowerCase(); // проверка команды на совпадение if (cmd.equals("open")) { // открыть счет bank.openAccount(args[1], args[2]); System.out.println("Account opened."); } else if (cmd.equals("close")) { // закрыть счет FunnyMoney money = bank.closeAccount(args[1], args[2]); // валюта System.out.println(money.amount + " вам возвращено."); System.out.println("большое спасибо"); } else if (cmd.equals("deposit")) { // внесение денег FunnyMoney money=new FunnyMoney(Integer.parseInt(args[3])); bank.deposit(args[1], args[2], money); System.out.println("пополнено " + money.amount + " денег"); } else if (cmd.equals("withdraw")) { // снятие денег FunnyMoney money = bank.withdraw(args[1], args[2], Integer.parseInt(args[3])); System.out.println("снято " + money.amount + " денег"); } else if (cmd.equals("balance")) { // баланс счета int amt = bank.getBalance(args[1], args[2]); System.out.println("на счету " + amt + " денег"); } else if (cmd.equals("history")) { // выписка проводок List transactions = bank.getTransactionHistory(args[1], args[2]); for(int i = 0; i < transactions.size(); i++) System.out.println(transactions.get(i)); } else System.out.println("неизвестная команда"); } // перехват и вывод исключений RMI catch (RemoteException e) { System.err.println(e); } // исключения по объекту Banking catch (BankingException e) { System.err.println(e.getMessage()); } // другие ошибки catch (Exception e) { System.err.println(e); System.err.println("Usage: java [-Dbank=<url>] Bank$Client " + "<cmd> <name> <password> [<amount>]"); System.err.println("where cmd is: open, close, deposit, " + "withdraw, balance, history"); } } }}

 

Загрузка...

Пример 8.2. Реализация класса RemoteBankServer – серверной части для для предыдущей клиентской программы.

 

package RemoteBankServer.java;import java.rmi.*;import java.rmi.server.*;import java.util.*;import Bank.*; /** * класс реализует методы, определенные интерфейсом RemoteBank**/public class RemoteBankServer extends UnicastRemoteObject implements RemoteBank{ /** * вложенный класс хранит данные об отдельном счете **/ class Account { String password; // пароль счета int balance; // баланс счета List transactions = new ArrayList(); // история проводок Account(String password) { this.password = password; transactions.add("Account opened at " + new Date()); } } /** * матрица для хранения всех открытых счетов и связи имени счета * с объектом Account **/ Map accounts = new HashMap(); /** * конструктор исключения **/ public RemoteBankServer() throws RemoteException { super(); } /** * открытие счета с именем и паролем **/ public synchronized void openAccount(String name, String password) throws RemoteException, BankingException { // проверка имени счета if (accounts.get(name) != null) throw new BankingException("счет уже существует"); // если не существует, то создать Account acct = new Account(password); // и зарегистрировать accounts.put(name, acct); } /** * проверка имени и пароля счета **/ Account verify(String name, String password) throws BankingException { synchronized(accounts) { Account acct = (Account)accounts.get(name); if (acct == null) throw new BankingException("нет такого счета"); if (!password.equals(acct.password)) throw new BankingException("неверный пароль"); return acct; } } /** * закрытие счета. **/ public synchronized FunnyMoney closeAccount(String name, String password) throws RemoteException, BankingException { Account acct; acct = verify(name, password); accounts.remove(name); // перед изменением баланса блокирум счет synchronized (acct) { int balance = acct.balance; acct.balance = 0; return new FunnyMoney(balance); } } /** пополнение счета FunnyMoney */ public void deposit(String name, String password, FunnyMoney money) throws RemoteException, BankingException { Account acct = verify(name, password); synchronized(acct) { acct.balance += money.amount; acct.transactions.add("внесено " + money.amount + " в " + new Date()); } } /** снятие суммы с указанного счета */ public FunnyMoney withdraw(String name, String password, int amount) throws RemoteException, BankingException { Account acct = verify(name, password); synchronized(acct) { if (acct.balance < amount) throw new BankingException("нет средств"); acct.balance -= amount; acct.transactions.add("снято " + amount + " с "+new Date()); return new FunnyMoney(amount); } } /** текущий баланс счета */ public int getBalance(String name, String password) throws RemoteException, BankingException { Account acct = verify(name, password); synchronized(acct) { return acct.balance; } } /** * строки с историей проводок по счету **/ public List getTransactionHistory(String name, String password) throws RemoteException, BankingException { Account acct = verify(name, password); synchronized(acct) { return acct.transactions; } } /** * основная программа, выполняющая RemoteBankServer. * создание объекта RemoteBankServer с присвоением имени в реестре * определяем имя по умолчанию "FirstRemote" **/ public static void main(String[] args) { try { // создание объекта банковского сервера RemoteBankServer bank = new RemoteBankServer(); // его имя String name = System.getProperty("bankname", "FirstRemote"); // присвоение имени Naming.rebind(name, bank); // готовность к работе System.out.println(name + " открыт для работы с клиентами"); } catch (Exception e) { System.err.println(e); System.err.println("формат: java [-Dbankname=<name>] " + " RemoteBankServer.java "); System.exit(1); // принудительный выход } }}

 


Дата добавления: 2015-09-11; просмотров: 3 | Нарушение авторских прав

Пример 2.21. | Пример 2.26. | Пример 3.1. | Пример 3.4. Обработка изображений. | Пример 3.5. Улучшенная анимация. | Пример 3.6. | Пример 4.1. | Простая сериализация. | Пример 5.3. | Часть 6. Программный интерфейс JavaBeans |


lektsii.net - Лекции.Нет - 2014-2019 год. (0.01 сек.) Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав