После обзора общих концепций, связанных с
Программное обеспечение в современном мире становится все сложнее и приобретает все больше функций. Коммерческие компании и государственные организации стремятся автоматизировать все больше своих процессов, как внутренних, так и тех, что связаны с общением с внешним миром. При этом, однако, разработка таких приложений, их внедрение и поддержка становятся все дороже.
Есть, тем не менее, фактор, который помогает значительно снизить расходы — широчайшее распространение Интернет. Если ваше программное обеспечение использует для связи между своими элементами базовые протоколы Интернет (TCP/IP и HTTP) и предоставляет пользовательский интерфейс с помощью HTML, который можно просматривать в любом браузере, то практически каждый его потенциальный пользователь не имеет технических препятствий для обращения к этому ПО. Не нужно распространять специальные клиентские компоненты, ставить клиентам специальное оборудование, не нужно тратить много времени и средств на обучение пользователей работе со специфическим интерфейсом, настройке связи с серверами и т.д. Интернет предоставляет готовую инфраструктуру для создания крупномасштабных программных систем, в рамках которых десятки тысяч компонентов могли бы работать совместно и миллионы пользователей могли бы пользоваться их услугами.
Поэтому вполне логично, что
Другим важным фактором является распространение
Поскольку все современные технологии разработки
Данный раздел содержит краткий обзор основных конструкций XML; для более глубокого изучения этого языка и связанных с ним технологий см. [1,2,3,4,5,6,7].
XML [3,4,5] является языком разметки: различные элементы данных в рамках XML-документов выделяются тегами — каждый элемент начинается с открывающего тега <tag> и заканчивается закрывающим </tag>. Здесь tag — идентификатор тега, который обычно является английским словом или набором слов, разделяемых знаками ‘ - ’, которое(-ые) описывают назначение этого элемента данных. Элементы данных могут быть вложены друг в друга, образуя <tag … />, т.е. не иметь отдельного закрывающего тега.
Ниже приведен пример описания информации о книге в виде XML:
<book
title = "Pattern-Oriented Software Architecture, Volume 1: A System of Patterns"
ISBN = "047195869"
year = 1996
hardcover = true
pages = 476
language = "English">
<author>Frank Buschmann</author>
<author>Regine Meunier</author>
<author>Hans Rohnert</author>
<author>Peter Sommerlad</author>
<author>Michael Stal</author>
<publisher
title = "John Wiley Sons"
address = "605 Third Avenue, New York, NY 10158-0012, USA" />
</book>
В этом примере тег <book>, представляющий описание книги, имеет вложенные теги <author> и <publisher>, представляющие ее авторов (таких тегов может быть несколько) и издателя. Он также имеет атрибуты title, ISBN, year, hardcover, pages и language (название книги, ее международный стандартный номер, т.е. <publisher>, в свою очередь, имеет атрибуты title и address (название и юридический адрес издательской организации).
Элементы XML-документа, называемые также сущностями, являются в некотором смысле аналогами значений структурных типов в .NET, а значения их атрибутов — аналогами соответствующих значений полей. При этом теги играют роль самих типов, а атрибуты и вложенные теги — роль их полей, имеющих, соответственно, примитивные и структурные типы.
XML-документ всегда начинается заголовком, описывающим версию XML, которой соответствует документ, и используемую кодировку. По умолчанию используется кодировка UTF-8.
Затем чаще всего идет описание типа документа, указывающее схему, которой он соответствует, и тег корневого элемента, содержащего все остальные элементы данного документа. Схема может задаваться в формате DTD или XMLSchema. Второй, хотя и является более новым, пока еще используется реже, потому что достаточно много документов определяется с помощью DTD и очень многие инструменты для обработки XML могут пользоваться этим форматом. Используемая схема определяется сразу двумя способами — при помощи строки, которая может служить ключом для поиска схемы на данной машине, и при помощи унифицированного идентификатора документа (Unified Resource Identifier, URI), содержащего ее описание и используемого в том случае, если ее не удалось найти локально.
Ниже приводится пример заголовка и описания типа документа для
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sun-ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Application Server 8.1 EJB 2.1//EN"
"http://www.sun.com/software/appserver/dtds/sun-ejb-jar_2_1-1.dtd">
<sun-ejb-jar>
…
</sun-ejb-jar>
Другой пример показывает заголовок документа DocBook — основанного на XML формата для технической документации, которая может быть автоматически преобразована в HTML, PDF и другие документы с определенными для них правилами верстки.
<?xml version="1.0" encoding="windows-1251"?> <!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd"> <article> … </article>
Помимо элементов данных и заголовка с описанием типа документа, XML-документ может содержать комментарии, помещаемые в теги <!-- … -->, инструкции обработки вида <? processor-name … ?> (здесь processor-name — идентификатор обработчика, которому предназначена инструкция) и секции символьных данных CDATA, которые начинаются набором символов <![CDATA[, а заканчиваются с помощью ]]>. Внутри секций символьных данных могут быть любые символы, за исключением закрывающей комбинации. В остальных местах некоторые специальные символы должны быть представлены комбинациями символов в соответствии с таблицей 13.1.
| Символ | Представление в XML |
|---|---|
< |
lt; |
> |
gt; |
|
amp; |
" |
quot; |
' |
apos; |
XML содержит много других конструкций, помимо уже перечисленных, но их рассмотрение выходит за рамки данного курса. Читатель, желающий узнать больше об этом языке и связанных с ним технологиях, может обратиться к [1,2,3,4,5,6,7].
Платформа J2EE предназначена в первую очередь для разработки распределенных
Компоненты
В целом
Эти компоненты служат для предоставления интерфейса к корпоративным программным системам поверх широко используемых протоколов Интернета, а именно, HTTP. Предоставляемые интерфейсы могут быть как интерфейсами для людей (WebUI), так и специализированными программными интерфейсами, работающими подобно удаленному вызову методов, но поверх HTTP.
В группу Web-компонентов входят фильтры (filters), обработчики Web-событий (web event listeners), сервлеты (servlets) и серверные страницы Java (JavaServer Pages, JSP).
J2EE является расширением
Это небольшие компоненты, имеющие графический интерфейс пользователя и предназначенные для работы внутри стандартного Web-браузера. Они используются в тех случаях, когда не хватает выразительных возможностей пользовательского интерфейса на базе HTML, и могут связываться с удаленными Web-компонентами, работающими на сервере, по HTTP.
Компонент любого из этих видов оформляется как небольшой набор классов и интерфейсов на Java, а также имеет
Платформа J2EE приспособлена для разработки многоуровневых
(рис 13.1) Типовая архитектура J2EE приложения.Выделены компоненты, разрабатываемые вручную
Таким образом, приложения на базе J2EE строятся с использованием трех основных
Самые крупные подсистемы организованы как уровни, решающие различные задачи.
Первые два уровня построены из отдельных компонентов, каждый из которых имеет собственную область ответственности, но может привлекать для решения частных задач другие компоненты.
Работа компонентов в рамках обработки группы тесно связанных запросов организуется по образцу MVC. При этом
Рассмотрим теперь, как решаются общие задачи построения распределенных систем [9] на базе платформы J2EE.
Связь между компонентами, работающими в разных процессах и на разных машинах, обеспечивается в J2EE, в основном, двумя способами: синхронная связь — с помощью реализации удаленного вызова методов на Java (
java. стандартной библиотеки.
Набор методов некоторого класса, доступных для удаленных вызовов, выделяется в специальный интерфейс, называемый удаленным интерфейсом (remote interface) и наследующий java.. Сам класс, методы объектов которого можно вызвать удаленно, должен реализовывать этот интерфейс. Этот же интерфейс реализуется автоматически создаваемой клиентской заглушкой. Поэтому объекты-клиенты работают только с объектом этого интерфейса, а не с объектом класса, реализующего декларированные в таком интерфейсе операции.
Кроме того, класс, реализующий удаленный интерфейс, должен наследовать класс java.. Этот класс содержит реализации методов hashCode(), equals() и toString(), которые учитывают возможность размещения его объектов в процессах, отличных от того, где они вызываются. Обычно наследуется не сам этот класс, а его подклассы java. или java.. Первый реализует общую функциональность объектов, которые можно вызвать удаленно поверх транспортного протокола TCP, пока работает содержащий их процесс, включая занесение информации о таких объектах в реестр
Каждый удаленный метод (remote method), т.е. метод, который можно вызвать из другого процесса, должен декларировать в качестве класса возможных исключений java. или его базовые типы java.io.IOException или java.lang.Exception. Этот класс сам служит базовым для
Объекты, реализующие один из удаленных интерфейсов, могут быть переданы в качестве параметров или результатов удаленных методов по ссылке как объекты этого интерфейса. При этом в другой процесс передается байт-код клиентской заглушки, связанной с таким объектом, и объекты этого процесса получают возможность вызывать в нем методы.
Остальные объекты передаются как параметры или результаты удаленных вызовов с помощью сериализации их данных и построения копии такого объекта в другом процессе. Так же передаются и создаваемые удаленным методом исключения. Для этого им необходимо реализовывать интерфейс java.io.Serializable или же быть значениями примитивных типов.
Простой пример Java-классов, взаимодействующих по
Код удаленного интерфейса:
package examples.rmi;
public interface Hello extends java.rmi.Remote
{
public String hello() throws java.rmi.RemoteException;
}
Код реализации удаленного интерфейса.
package examples.rmi;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
public class HelloImpl extends UnicastRemoteObject implements Hello
{
public static final String ServerHost = "hostname";
public static final String ServerURL = "rmi://" + ServerHost + ":2001/SERVER";
public static final int RegistryPort = 2000;
public HelloImpl () throws java.rmi.RemoteException { }
public String hello () throws java.rmi.RemoteException
{ return "Hello!"; }
public static void main (String[] args)
{
try
{
Hello stub = new HelloImpl();
Registry registry = LocateRegistry.getRegistry(RegistryPort);
registry.rebind(ServerURL, stub);
}
catch (Exception e)
{
System.out.println("server creation exception");
e.printStackTrace();
}
}
}
Код класса-клиента.
package examples.rmi;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class HelloClient
{
public HelloClient () { }
public static void main (String[] args)
{
try
{
Registry registry = LocateRegistry.getRegistry
(HelloImpl.ServerHost, HelloImpl.RegistryPort);
Hello stub = (Hello) registry.lookup(HelloImpl.ServerURL);
System.out.println("response: " + stub.hello());
}
catch (Exception e)
{
System.err.println("Client exception: " + e.toString());
e.printStackTrace();
}
}
}
Для того чтобы запустить этот пример, нужно выполнить следующие действия.
rmic examples.rmi.HelloImpl
HelloImpl. Реестр используется для регистрации start rmiregistry 2000
java examples.rmi.HelloImpl
java examples.rmi.HelloClient
Если никаких ошибок не сделано, и порты 2000 и 2001 на серверной машине свободны, клиент выдаст сообщение.
response: Hello!
Поскольку базовые интерфейсы компонентов java., такие компоненты автоматически предоставляют возможность обращаться к некоторым из своих методов удаленно.
Служба сообщений Java ( javax.JMS — не входят в состав
Основные элементы
javax.JMS.Message.Сообщение имеет тело, которое может быть отображением (map) ключей в значения, текстом, объектом, набором байт или потоком значений примитивных типов Java. Каждый из видов сообщений представлен особым подинтерфейсом общего интерфейса Message.
Сообщение может иметь набор заголовков (headers), большинство из которых определяются автоматически.
Кроме того, сообщение может иметь набор свойств, которые позволяют определять дополнительные заголовки, специфичные для данного приложения.
javax.JMS.Connection, а получить соединение можно с помощью фабрики соединений (объект javax.JMS.ConnectionFactory ), найдя ее при помощи службы именования. Передать сообщение можно и воспользовавшись объектом-адресатом (объект javax.JMS.Destination ), который также можно получить через службу именования.точка-точка (peer-to-peer, P2P ), так и посылку и прием сообщений по схеме подписки/публикации. Основные интерфейсы Поиск ресурсов по именам или идентификаторам и набору их свойств в рамках J2EE и
Интерфейсы и классы javax.namimg и его javax.naming.directory, javax.naming.event, javax.naming.ldap.
Основные сущности служб именования и каталогов, хранящие привязку ресурсов к именам и наборам атрибутов, называются контекстами. Они представляются объектами интерфейса javax.naming.Context, в частности, реализующих его классов javax.naming.InitialContext, javax.naming.directory.InitialDirContext, javax.naming.ldap.InitialLdapContext.
Методы этого интерфейса служат для привязки объекта к имени ( void bind( — связать данное имя с данным объектом, даже если оно уже имеется в этом контексте), поиска объекта по имени ( Object lookup (String) ), разрыва связи между именем и объектом ( void ) и пр.
В дополнение к этим методам классы InitialDirContext и InitialLdapContext реализуют интерфейс контекста службы каталогов DirContext. Контекст службы каталогов имеет методы void bind( для привязки набора атрибутов к объекту, Attributes getAttributes(String) — для получения набора атрибутов объекта по указанному имени и NamingEnumeration<SearchResult> search(String, Attributes) — для
Класс InitialLdapContext реализует общий протокол работы со службами каталогов — простой протокол доступа к службам каталогов (Lightweight Directory Access Protocol, LDAP).
При загрузке виртуальной машины механизм инициализации , которые находятся в директориях, перечисленных в classpath.
Стандартный набор
java.naming.factory.initial (соответствует константе Context.INITIAL_CONTEXT_FACTORY ) — имя класса фабрики для создания начальных контекстов, обязательно должно быть установлено;java.naming.provider.url (соответствует константе Context.PROVIDER_URL ) — URL java.naming.dns.url (соответствует константе Context.DNS_URL ) — URL для определения DNS узла, используемого для получения адреса java.naming.applet (соответствует константе Context.APPLET ) — объект-апплет, используемый для получения java.naming.language (соответствует константе Context.LANGUAGE ) — список, через запятую, предпочтительных языков для использования в данной службе (пример: en-US, fr, ja-JP-kanji ). Языки описываются в соответствии с RFC 1766 [13].Ниже приведен пример использования c:/tmp. Для работы с файловой системой через
package examples.jndi;
import java.util.Properties;
import javax.naming.Binding;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
public class JNDIExample
{
public static void main (String[] args)
{
Properties env = new Properties();
env.put(Context.INITIAL_CONTEXT_FACTORY,
"com.sun.jndi.fscontext.RefFSContextFactory");
env.put(Context.PROVIDER_URL, "file://c:/tmp");
try
{
Context cntx = new InitialContext(env);
NamingEnumeration list = cntx.listBindings("");
while(list.hasMore())
{
Binding bnd = (Binding)list.next();
System.out.println(bnd.getName());
}
}
catch (NamingException e) { e.printStackTrace(); }
}
}
Разбиение J2EE приложения на набор взаимодействующих процессов и потоков и управление ими осуществляется их
Все методы вспомогательных классов, которые используются Web-компонентами или компонентами synchronized ).
Компоненты J2EE-приложений, работающие в рамках контейнеров, могут создавать собственные отдельные потоки, но делать это нужно с большой осторожностью, поскольку этими потоками контейнер управлять не сможет и они могут помешать работе других компонентов.
Целостность и непротиворечивость данных при работе J2EE-приложений поддерживается с помощью механизма распределенных транзакций. Управление такими транзакциями может быть возложено на
Базовые интерфейсы javax.transaction. и javax.transaction.xa. Это, прежде всего, интерфейсы менеджера транзакций TransactionManager, самих транзакций Transaction и UserTransaction и интерфейс синхронизации Synchronization, позволяющий получать уведомление о начале завершения и конце завершения транзакций.
Методы интерфейса TransactionManager позволяют запустить транзакцию, завершить ее успешно или откатить, а также получить объект, представляющий текущую транзакцию и имеющий тип Transaction. Методы интерфейса Transaction позволяют завершить или откатить транзакцию, представляемую объектом такого интерфейса, зарегистрировать объекты для синхронизации при завершении транзакции, а также добавить некоторые ресурсы в число участников данной транзакции или удалить их из этого списка. Такие ресурсы представляются в виде объектов интерфейса javax.transaction.xa.XAResource. Интерфейс UserTransaction предназначен для управления пользовательскими транзакциями — он предоставляет немного меньше возможностей, чем TransactionManager.
В том случае, если управление транзакциями целиком поручается
RequiredМетод, имеющий такой атрибут, всегда должен выполняться в контексте транзакции. Он будет работать в контексте той же транзакции, в которой работал вызвавший его метод, а если он был вызван вне контекста транзакции, с началом его работы будет запущена новая транзакция.
Этот атрибут используется наиболее часто.
RequiresNewМетод, имеющий такой атрибут, всегда будет запускать новую транзакцию в самом начале работы. При этом внешняя транзакция, если она была, будет временно приостановлена.
MandatoryМетод, имеющий такой атрибут, должен вызываться только из транзакции, в контексте которой он и продолжит работать. При вызове такого метода извне транзакции будет создана исключительная ситуация типа TransactionRequiredException.
NotSupportedПри вызове такого метода внешняя транзакция, если она есть, будет временно приостановлена. Если ее нет, новая транзакция не будет запущена.
SupportsТакой метод работает внутри транзакции, если его вызвали из ее контекста; если же он был вызван вне транзакции, новая транзакция не запускается.
NeverПри вызове такого метода из транзакции создается исключительная ситуация типа RemoteException. Он может работать, только будучи вызван извне транзакции.
Откатить автоматически управляемую транзакцию можно, создав исключительную ситуацию типа javax. или вызвав метод setRollbackOnly() интерфейса javax..
Отказоустойчивость J2EE-приложений не обеспечивается дополнительными средствами, такими как репликация, надежная передача сообщений и пр. Если в них возникает необходимость, разработчик должен сам реализовывать эти механизмы либо пользоваться готовыми решениями за рамками платформы J2EE.
Защищенность J2EE приложения поддерживается несколькими способами.
Можно потребовать использовать только такие соединения, указав атрибуты и/или INTEGRAL в
При развертывании приложения зарегистрированные на J2EE-сервере пользователи и группы пользователей могут быть отображены на различные роли, определенные в приложении.
Это можно делать при помощи методов isUserInRole() и getUserPrincipal() интерфейса HTTPServletRequest, используемого для представления запросов к Web-компонентам, и аналогичных методов isCallerInRole() и getCallerPrincipal() интерфейса EJBContext, используемого для описания контекста выполнения методов
Поскольку сейчас очень часто информация хранится и передается в виде XML-документов, для разработки
Библиотеки для работы с XML-документами находятся в пакетах javax.xml, org.w3c.dom и org.xml., a также во вложенных в них пакетах. В этих пакетах определяются следующие интерфейсы.
javax.xml.parsers. Такие обработчики могут быть основаны на простом интерфейсе работы с XML (Simple API for XML, org.xml.sax . Это интерфейс, основанный на событиях, — XML-парсер, реализующий его, последовательно разбирает XML-данные и генерирует очередное событие в зависимости от вида обнаруженной конструкции. Для работы с XML-документами необходимо написать ряд обработчиков таких событий, являющихся реализациями интерфейса org.xml.sax .ContentHandler.org.w3c.dom. Одной из его реализаций является JDOM [17], а dom4j [18] предоставляет несколько упрощенную и более удобную с точки зрения Java, но не вполне соответствующую стандарту javax.xml.transform. Широко используемыми Среда .NET предназначена для более широкого использования, чем платформа J2EE. Однако ее функциональность в части, предназначенной для разработки распределенных
В рамках .NET имеются аналоги основных видов компонентов J2EE. Web-компонентам соответствуют компоненты, построенные по технологии
Тем самым, типовая архитектура
(рис 13.2) Типовая архитектура Web-приложения на основе .NETВ целом,
Обычно .NET-компоненты представляют собой набор .NET-классов и
Связь между компонентами в рамках .NET осуществляется при помощи механизма
Классы и интерфейсы, служащие основой механизма System.Runtime.Remoting и его подпространствах, в сборках mscorlib и System.Rutime.Remoting.
В рамках
Тип объекта, передаваемого по значению, должен реализовывать интерфейс System.Runtime.Serialization.ISerializable или должен быть помечен атрибутом System.SerializableAttribute. В последнем случае .NET автоматически создает код, необходимый для сериализации или
Объекты, передаваемые по ссылке, должны наследовать классу System.MarshalByRefObject. При передаче такого объекта как аргумента или результата в другом процессе (или
Более тонкую настройку удаленных вызовов можно делать при помощи наследников класса System.ContextBoundObject. Наследование этого класса говорит о том, что удаленные вызовы в объекте этого класса должны происходить в рамках некоторого контекста, являющегося частью его
Ниже находится пример взаимодействующих по механизму
Код класса, реализующего метод для удаленных обращений.
using System;
namespace Examples.Remoting
{
public class Hello : MarshalByRefObject
{
public String HelloMethod() { return "Hello!"; }
}
}
Код сервера, ожидающего обращения клиентов.
using System;
using System.Runtime.Remoting;
namespace Examples.Remoting
{
public class HelloImpl
{
public static void Main()
{
RemotingConfiguration.Configure("RemotingServer.exe.config");
Console.ReadLine();
}
}
}
Код клиентского класса.
using System;
using System.Runtime.Remoting;
namespace Examples.Remoting
{
public class HelloClient
{
public static void Main()
{
RemotingConfiguration.Configure("RemotingClient.exe.config");
Hello stub = new Hello();
Console.WriteLine("response: " + stub.HelloMethod());
}
}
}
Кроме классов, должны быть написаны конфигурационные файлы серверного и клиентского приложений. Конфигурационный файл сервера выглядит так.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.runtime.remoting>
<application>
<service>
<wellknown
mode = "Singleton"
type = "Examples.Remoting.Hello, Hello"
objectUri = "MessageServer"
/>
</service>
<channels>
<channel ref = "http" port = "8989" />
</channels>
</application>
</system.runtime.remoting>
</configuration>
Конфигурационный файл клиента.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.runtime.remoting>
<application>
<client>
<wellknown
type = "Examples.Remoting.Hello, Hello"
url = "http://hostname:8989/MessageServer"
/>
</client>
</application>
</system.runtime.remoting>
</configuration>
Чтобы запустить этот пример, нужно выполнить следующие шаги.
csc.exe /noconfig /t:library Hello.cs csc.exe /noconfig /r:Hello.dll Server.cs csc.exe /noconfig /r:Hello.dll Client.cs
В результате первой команды будет получена динамическая библиотека, содержащая определение класса Hello. В двух других она используется, чтобы предоставить ссылку на этот тип.
Server.exe
Client.exe
Если никаких ошибок не сделано, и порт 8989 на серверной машине доступен, клиент выдаст сообщение.
response: Hello!
С помощью конфигурационных файлов можно определить политику активации
System.Messaging.
Взаимодействие между компонентами
В примере на взаимодействие по
Если же это не так, необходимо иметь полноценную службу именования и/или службу каталогов. В этом качестве в .NET используется System.DirectoryServices и его подпространствах, в сборках System.DirectoryServices и System.DirectoryServices.Protocols.
Для работы с записями System.DirectoryServices.DirectoryEntry. C помощью конструкторов и методов этого класса можно создавать и изменять регистрационные записи службы каталогов. Для поиска зарегистрированных объектов по идентификаторам или свойствам используются методы класса System.DirectoryServices.DirectorySearcher.
Помимо процессов и потоков, среда .NET поддерживает так называемые
Помимо автоматически создаваемых потоков и
Целостность данных в .NET поддерживается, как и в J2EE, в основном, за счет механизма транзакций. Распределенные транзакции в .NET реализованы на базе сервера транзакций Microsoft (Microsoft Transaction Server, MTS), который появился как часть компонентной среды COM+. Интерфейсы для работы с его функциями собраны в пространстве имен System.EnterpriseServices, в сборке с таким же именем.
Автоматические транзакции поддерживаются при помощи указания у классов транзакционных атрибутов, имеющих тип System.EnterpriseServices.TransactionAttribute. Такой атрибут может принимать значения Required, RequiresNew, NotSupported, Supported и Disabled. Первые три имеют то же значение, что и в J2EE. Атрибут Supported действует аналогично Supports в J2EE. Атрибут Disabled обозначает, что транзакционный контекст вызвавшего метода будет проигнорирован.
Значение атрибутов по умолчанию для методов компонентов Disabled, у вторых — Required.
Чтобы определить класс, чьи методы могут участвовать в транзакциях, нужно унаследовать его от класса System.EnterpriseServices.ServicedComponent, определить транзакционный атрибут, а также прикрепить к сборке, содержащей этот класс, сертификат и зарегистрировать сборку в реестре COM+.
Для завершения или отката автоматической транзакции используются следующие конструкции.
System.EnterpriseServices.AutoCompleteAttribute у участвующего в транзакции метода говорит о том, что в случае нормального завершения работы метода и отсутствия проблем у других ее участников транзакция будет завершена успешно. Если же в результате работы метода будет создано исключение, транзакция будет отменена.SetComplete() и SetAbort() класса System.EnterpriseServices.ContextUtil могут использоваться для успешного завершения или отката автоматически созданной транзакции.Создание и управление транзакциями "в ручном режиме" может быть осуществлено для компонентов System.Data.Common.DbConnection и его наследников и класса System.Data.Common.DbTransaction. Для управления транзакциями при передаче сообщений используется класс System.Messaging.MessageQueueTransaction.
Так же, как и для J2EE, отказоустойчивость .NET-приложений должна обеспечиваться либо за счет использования дополнительных продуктов, либо за счет специфического проектирования приложения.
Защищенность .NET-приложений поддерживается примерно теми же методами, что и защищенность J2EE-приложений.
Здесь также имеется несколько техник аутентификации, возможность определения ролей, обеспеченных набором прав доступа к различным элементам системы, а также возможность использования различных протоколов шифрования и защищенной передачи данных, управления ключами и подтверждения целостности данных. В рамках .NET используются также многоуровневые политики защиты, которые определяют набор прав, предоставляемых коду из разных источников.
Программные интерфейсы к различным механизмам управления защищенностью приложений и ресурсов реализуются классами и интерфейсами пространства имен System.Security, находящимися в сборках mscorlib, System и System.Security.
В целом техника работы с XML-документами в .NET опирается на реализацию объектной модели документов XML ( System.Xml.XmlReader. Классы, реализующие различные парсеры XML, различные варианты представления XML-документов, а также их трансформацию на основе System.Xml, разбросанном по сборкам System.Data, System.Data.SqlXml и System.Xml.
Одной из особенностей работы с XML в .NET является встроенная возможность работы с XML-данными в рамках механизмов System.Xml.XmlDataDocument.
После обзора общих концепций, связанных с
Программное обеспечение в современном мире становится все сложнее и приобретает все больше функций. Коммерческие компании и государственные организации стремятся автоматизировать все больше своих процессов, как внутренних, так и тех, что связаны с общением с внешним миром. При этом, однако, разработка таких приложений, их внедрение и поддержка становятся все дороже.
Есть, тем не менее, фактор, который помогает значительно снизить расходы — широчайшее распространение Интернет. Если ваше программное обеспечение использует для связи между своими элементами базовые протоколы Интернет (TCP/IP и HTTP) и предоставляет пользовательский интерфейс с помощью HTML, который можно просматривать в любом браузере, то практически каждый его потенциальный пользователь не имеет технических препятствий для обращения к этому ПО. Не нужно распространять специальные клиентские компоненты, ставить клиентам специальное оборудование, не нужно тратить много времени и средств на обучение пользователей работе со специфическим интерфейсом, настройке связи с серверами и т.д. Интернет предоставляет готовую инфраструктуру для создания крупномасштабных программных систем, в рамках которых десятки тысяч компонентов могли бы работать совместно и миллионы пользователей могли бы пользоваться их услугами.
Поэтому вполне логично, что
Другим важным фактором является распространение
Поскольку все современные технологии разработки
Данный раздел содержит краткий обзор основных конструкций XML; для более глубокого изучения этого языка и связанных с ним технологий см. [1,2,3,4,5,6,7].
XML [3,4,5] является языком разметки: различные элементы данных в рамках XML-документов выделяются тегами — каждый элемент начинается с открывающего тега <tag> и заканчивается закрывающим </tag>. Здесь tag — идентификатор тега, который обычно является английским словом или набором слов, разделяемых знаками ‘ - ’, которое(-ые) описывают назначение этого элемента данных. Элементы данных могут быть вложены друг в друга, образуя <tag … />, т.е. не иметь отдельного закрывающего тега.
Ниже приведен пример описания информации о книге в виде XML:
<book
title = "Pattern-Oriented Software Architecture, Volume 1: A System of Patterns"
ISBN = "047195869"
year = 1996
hardcover = true
pages = 476
language = "English">
<author>Frank Buschmann</author>
<author>Regine Meunier</author>
<author>Hans Rohnert</author>
<author>Peter Sommerlad</author>
<author>Michael Stal</author>
<publisher
title = "John Wiley Sons"
address = "605 Third Avenue, New York, NY 10158-0012, USA" />
</book>
В этом примере тег <book>, представляющий описание книги, имеет вложенные теги <author> и <publisher>, представляющие ее авторов (таких тегов может быть несколько) и издателя. Он также имеет атрибуты title, ISBN, year, hardcover, pages и language (название книги, ее международный стандартный номер, т.е. <publisher>, в свою очередь, имеет атрибуты title и address (название и юридический адрес издательской организации).
Элементы XML-документа, называемые также сущностями, являются в некотором смысле аналогами значений структурных типов в .NET, а значения их атрибутов — аналогами соответствующих значений полей. При этом теги играют роль самих типов, а атрибуты и вложенные теги — роль их полей, имеющих, соответственно, примитивные и структурные типы.
XML-документ всегда начинается заголовком, описывающим версию XML, которой соответствует документ, и используемую кодировку. По умолчанию используется кодировка UTF-8.
Затем чаще всего идет описание типа документа, указывающее схему, которой он соответствует, и тег корневого элемента, содержащего все остальные элементы данного документа. Схема может задаваться в формате DTD или XMLSchema. Второй, хотя и является более новым, пока еще используется реже, потому что достаточно много документов определяется с помощью DTD и очень многие инструменты для обработки XML могут пользоваться этим форматом. Используемая схема определяется сразу двумя способами — при помощи строки, которая может служить ключом для поиска схемы на данной машине, и при помощи унифицированного идентификатора документа (Unified Resource Identifier, URI), содержащего ее описание и используемого в том случае, если ее не удалось найти локально.
Ниже приводится пример заголовка и описания типа документа для
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sun-ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Application Server 8.1 EJB 2.1//EN"
"http://www.sun.com/software/appserver/dtds/sun-ejb-jar_2_1-1.dtd">
<sun-ejb-jar>
…
</sun-ejb-jar>
Другой пример показывает заголовок документа DocBook — основанного на XML формата для технической документации, которая может быть автоматически преобразована в HTML, PDF и другие документы с определенными для них правилами верстки.
<?xml version="1.0" encoding="windows-1251"?> <!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN" "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd"> <article> … </article>
Помимо элементов данных и заголовка с описанием типа документа, XML-документ может содержать комментарии, помещаемые в теги <!-- … -->, инструкции обработки вида <? processor-name … ?> (здесь processor-name — идентификатор обработчика, которому предназначена инструкция) и секции символьных данных CDATA, которые начинаются набором символов <![CDATA[, а заканчиваются с помощью ]]>. Внутри секций символьных данных могут быть любые символы, за исключением закрывающей комбинации. В остальных местах некоторые специальные символы должны быть представлены комбинациями символов в соответствии с таблицей 13.1.
| Символ | Представление в XML |
|---|---|
< |
lt; |
> |
gt; |
|
amp; |
" |
quot; |
' |
apos; |
XML содержит много других конструкций, помимо уже перечисленных, но их рассмотрение выходит за рамки данного курса. Читатель, желающий узнать больше об этом языке и связанных с ним технологиях, может обратиться к [1,2,3,4,5,6,7].
Платформа J2EE предназначена в первую очередь для разработки распределенных
Компоненты
В целом
Эти компоненты служат для предоставления интерфейса к корпоративным программным системам поверх широко используемых протоколов Интернета, а именно, HTTP. Предоставляемые интерфейсы могут быть как интерфейсами для людей (WebUI), так и специализированными программными интерфейсами, работающими подобно удаленному вызову методов, но поверх HTTP.
В группу Web-компонентов входят фильтры (filters), обработчики Web-событий (web event listeners), сервлеты (servlets) и серверные страницы Java (JavaServer Pages, JSP).
J2EE является расширением
Это небольшие компоненты, имеющие графический интерфейс пользователя и предназначенные для работы внутри стандартного Web-браузера. Они используются в тех случаях, когда не хватает выразительных возможностей пользовательского интерфейса на базе HTML, и могут связываться с удаленными Web-компонентами, работающими на сервере, по HTTP.
Компонент любого из этих видов оформляется как небольшой набор классов и интерфейсов на Java, а также имеет
Платформа J2EE приспособлена для разработки многоуровневых
(рис 13.1) Типовая архитектура J2EE приложения.Выделены компоненты, разрабатываемые вручную
Таким образом, приложения на базе J2EE строятся с использованием трех основных
Самые крупные подсистемы организованы как уровни, решающие различные задачи.
Первые два уровня построены из отдельных компонентов, каждый из которых имеет собственную область ответственности, но может привлекать для решения частных задач другие компоненты.
Работа компонентов в рамках обработки группы тесно связанных запросов организуется по образцу MVC. При этом
Рассмотрим теперь, как решаются общие задачи построения распределенных систем [9] на базе платформы J2EE.
Связь между компонентами, работающими в разных процессах и на разных машинах, обеспечивается в J2EE, в основном, двумя способами: синхронная связь — с помощью реализации удаленного вызова методов на Java (
java. стандартной библиотеки.
Набор методов некоторого класса, доступных для удаленных вызовов, выделяется в специальный интерфейс, называемый удаленным интерфейсом (remote interface) и наследующий java.. Сам класс, методы объектов которого можно вызвать удаленно, должен реализовывать этот интерфейс. Этот же интерфейс реализуется автоматически создаваемой клиентской заглушкой. Поэтому объекты-клиенты работают только с объектом этого интерфейса, а не с объектом класса, реализующего декларированные в таком интерфейсе операции.
Кроме того, класс, реализующий удаленный интерфейс, должен наследовать класс java.. Этот класс содержит реализации методов hashCode(), equals() и toString(), которые учитывают возможность размещения его объектов в процессах, отличных от того, где они вызываются. Обычно наследуется не сам этот класс, а его подклассы java. или java.. Первый реализует общую функциональность объектов, которые можно вызвать удаленно поверх транспортного протокола TCP, пока работает содержащий их процесс, включая занесение информации о таких объектах в реестр
Каждый удаленный метод (remote method), т.е. метод, который можно вызвать из другого процесса, должен декларировать в качестве класса возможных исключений java. или его базовые типы java.io.IOException или java.lang.Exception. Этот класс сам служит базовым для
Объекты, реализующие один из удаленных интерфейсов, могут быть переданы в качестве параметров или результатов удаленных методов по ссылке как объекты этого интерфейса. При этом в другой процесс передается байт-код клиентской заглушки, связанной с таким объектом, и объекты этого процесса получают возможность вызывать в нем методы.
Остальные объекты передаются как параметры или результаты удаленных вызовов с помощью сериализации их данных и построения копии такого объекта в другом процессе. Так же передаются и создаваемые удаленным методом исключения. Для этого им необходимо реализовывать интерфейс java.io.Serializable или же быть значениями примитивных типов.
Простой пример Java-классов, взаимодействующих по
Код удаленного интерфейса:
package examples.rmi;
public interface Hello extends java.rmi.Remote
{
public String hello() throws java.rmi.RemoteException;
}
Код реализации удаленного интерфейса.
package examples.rmi;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
public class HelloImpl extends UnicastRemoteObject implements Hello
{
public static final String ServerHost = "hostname";
public static final String ServerURL = "rmi://" + ServerHost + ":2001/SERVER";
public static final int RegistryPort = 2000;
public HelloImpl () throws java.rmi.RemoteException { }
public String hello () throws java.rmi.RemoteException
{ return "Hello!"; }
public static void main (String[] args)
{
try
{
Hello stub = new HelloImpl();
Registry registry = LocateRegistry.getRegistry(RegistryPort);
registry.rebind(ServerURL, stub);
}
catch (Exception e)
{
System.out.println("server creation exception");
e.printStackTrace();
}
}
}
Код класса-клиента.
package examples.rmi;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class HelloClient
{
public HelloClient () { }
public static void main (String[] args)
{
try
{
Registry registry = LocateRegistry.getRegistry
(HelloImpl.ServerHost, HelloImpl.RegistryPort);
Hello stub = (Hello) registry.lookup(HelloImpl.ServerURL);
System.out.println("response: " + stub.hello());
}
catch (Exception e)
{
System.err.println("Client exception: " + e.toString());
e.printStackTrace();
}
}
}
Для того чтобы запустить этот пример, нужно выполнить следующие действия.
rmic examples.rmi.HelloImpl
HelloImpl. Реестр используется для регистрации start rmiregistry 2000
java examples.rmi.HelloImpl
java examples.rmi.HelloClient
Если никаких ошибок не сделано, и порты 2000 и 2001 на серверной машине свободны, клиент выдаст сообщение.
response: Hello!
Поскольку базовые интерфейсы компонентов java., такие компоненты автоматически предоставляют возможность обращаться к некоторым из своих методов удаленно.
Служба сообщений Java ( javax.JMS — не входят в состав
Основные элементы
javax.JMS.Message.Сообщение имеет тело, которое может быть отображением (map) ключей в значения, текстом, объектом, набором байт или потоком значений примитивных типов Java. Каждый из видов сообщений представлен особым подинтерфейсом общего интерфейса Message.
Сообщение может иметь набор заголовков (headers), большинство из которых определяются автоматически.
Кроме того, сообщение может иметь набор свойств, которые позволяют определять дополнительные заголовки, специфичные для данного приложения.
javax.JMS.Connection, а получить соединение можно с помощью фабрики соединений (объект javax.JMS.ConnectionFactory ), найдя ее при помощи службы именования. Передать сообщение можно и воспользовавшись объектом-адресатом (объект javax.JMS.Destination ), который также можно получить через службу именования.точка-точка (peer-to-peer, P2P ), так и посылку и прием сообщений по схеме подписки/публикации. Основные интерфейсы Поиск ресурсов по именам или идентификаторам и набору их свойств в рамках J2EE и
Интерфейсы и классы javax.namimg и его javax.naming.directory, javax.naming.event, javax.naming.ldap.
Основные сущности служб именования и каталогов, хранящие привязку ресурсов к именам и наборам атрибутов, называются контекстами. Они представляются объектами интерфейса javax.naming.Context, в частности, реализующих его классов javax.naming.InitialContext, javax.naming.directory.InitialDirContext, javax.naming.ldap.InitialLdapContext.
Методы этого интерфейса служат для привязки объекта к имени ( void bind( — связать данное имя с данным объектом, даже если оно уже имеется в этом контексте), поиска объекта по имени ( Object lookup (String) ), разрыва связи между именем и объектом ( void ) и пр.
В дополнение к этим методам классы InitialDirContext и InitialLdapContext реализуют интерфейс контекста службы каталогов DirContext. Контекст службы каталогов имеет методы void bind( для привязки набора атрибутов к объекту, Attributes getAttributes(String) — для получения набора атрибутов объекта по указанному имени и NamingEnumeration<SearchResult> search(String, Attributes) — для
Класс InitialLdapContext реализует общий протокол работы со службами каталогов — простой протокол доступа к службам каталогов (Lightweight Directory Access Protocol, LDAP).
При загрузке виртуальной машины механизм инициализации , которые находятся в директориях, перечисленных в classpath.
Стандартный набор
java.naming.factory.initial (соответствует константе Context.INITIAL_CONTEXT_FACTORY ) — имя класса фабрики для создания начальных контекстов, обязательно должно быть установлено;java.naming.provider.url (соответствует константе Context.PROVIDER_URL ) — URL java.naming.dns.url (соответствует константе Context.DNS_URL ) — URL для определения DNS узла, используемого для получения адреса java.naming.applet (соответствует константе Context.APPLET ) — объект-апплет, используемый для получения java.naming.language (соответствует константе Context.LANGUAGE ) — список, через запятую, предпочтительных языков для использования в данной службе (пример: en-US, fr, ja-JP-kanji ). Языки описываются в соответствии с RFC 1766 [13].Ниже приведен пример использования c:/tmp. Для работы с файловой системой через
package examples.jndi;
import java.util.Properties;
import javax.naming.Binding;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
public class JNDIExample
{
public static void main (String[] args)
{
Properties env = new Properties();
env.put(Context.INITIAL_CONTEXT_FACTORY,
"com.sun.jndi.fscontext.RefFSContextFactory");
env.put(Context.PROVIDER_URL, "file://c:/tmp");
try
{
Context cntx = new InitialContext(env);
NamingEnumeration list = cntx.listBindings("");
while(list.hasMore())
{
Binding bnd = (Binding)list.next();
System.out.println(bnd.getName());
}
}
catch (NamingException e) { e.printStackTrace(); }
}
}
Разбиение J2EE приложения на набор взаимодействующих процессов и потоков и управление ими осуществляется их
Все методы вспомогательных классов, которые используются Web-компонентами или компонентами synchronized ).
Компоненты J2EE-приложений, работающие в рамках контейнеров, могут создавать собственные отдельные потоки, но делать это нужно с большой осторожностью, поскольку этими потоками контейнер управлять не сможет и они могут помешать работе других компонентов.
Целостность и непротиворечивость данных при работе J2EE-приложений поддерживается с помощью механизма распределенных транзакций. Управление такими транзакциями может быть возложено на
Базовые интерфейсы javax.transaction. и javax.transaction.xa. Это, прежде всего, интерфейсы менеджера транзакций TransactionManager, самих транзакций Transaction и UserTransaction и интерфейс синхронизации Synchronization, позволяющий получать уведомление о начале завершения и конце завершения транзакций.
Методы интерфейса TransactionManager позволяют запустить транзакцию, завершить ее успешно или откатить, а также получить объект, представляющий текущую транзакцию и имеющий тип Transaction. Методы интерфейса Transaction позволяют завершить или откатить транзакцию, представляемую объектом такого интерфейса, зарегистрировать объекты для синхронизации при завершении транзакции, а также добавить некоторые ресурсы в число участников данной транзакции или удалить их из этого списка. Такие ресурсы представляются в виде объектов интерфейса javax.transaction.xa.XAResource. Интерфейс UserTransaction предназначен для управления пользовательскими транзакциями — он предоставляет немного меньше возможностей, чем TransactionManager.
В том случае, если управление транзакциями целиком поручается
RequiredМетод, имеющий такой атрибут, всегда должен выполняться в контексте транзакции. Он будет работать в контексте той же транзакции, в которой работал вызвавший его метод, а если он был вызван вне контекста транзакции, с началом его работы будет запущена новая транзакция.
Этот атрибут используется наиболее часто.
RequiresNewМетод, имеющий такой атрибут, всегда будет запускать новую транзакцию в самом начале работы. При этом внешняя транзакция, если она была, будет временно приостановлена.
MandatoryМетод, имеющий такой атрибут, должен вызываться только из транзакции, в контексте которой он и продолжит работать. При вызове такого метода извне транзакции будет создана исключительная ситуация типа TransactionRequiredException.
NotSupportedПри вызове такого метода внешняя транзакция, если она есть, будет временно приостановлена. Если ее нет, новая транзакция не будет запущена.
SupportsТакой метод работает внутри транзакции, если его вызвали из ее контекста; если же он был вызван вне транзакции, новая транзакция не запускается.
NeverПри вызове такого метода из транзакции создается исключительная ситуация типа RemoteException. Он может работать, только будучи вызван извне транзакции.
Откатить автоматически управляемую транзакцию можно, создав исключительную ситуацию типа javax. или вызвав метод setRollbackOnly() интерфейса javax..
Отказоустойчивость J2EE-приложений не обеспечивается дополнительными средствами, такими как репликация, надежная передача сообщений и пр. Если в них возникает необходимость, разработчик должен сам реализовывать эти механизмы либо пользоваться готовыми решениями за рамками платформы J2EE.
Защищенность J2EE приложения поддерживается несколькими способами.
Можно потребовать использовать только такие соединения, указав атрибуты и/или INTEGRAL в
При развертывании приложения зарегистрированные на J2EE-сервере пользователи и группы пользователей могут быть отображены на различные роли, определенные в приложении.
Это можно делать при помощи методов isUserInRole() и getUserPrincipal() интерфейса HTTPServletRequest, используемого для представления запросов к Web-компонентам, и аналогичных методов isCallerInRole() и getCallerPrincipal() интерфейса EJBContext, используемого для описания контекста выполнения методов
Поскольку сейчас очень часто информация хранится и передается в виде XML-документов, для разработки
Библиотеки для работы с XML-документами находятся в пакетах javax.xml, org.w3c.dom и org.xml., a также во вложенных в них пакетах. В этих пакетах определяются следующие интерфейсы.
javax.xml.parsers. Такие обработчики могут быть основаны на простом интерфейсе работы с XML (Simple API for XML, org.xml.sax . Это интерфейс, основанный на событиях, — XML-парсер, реализующий его, последовательно разбирает XML-данные и генерирует очередное событие в зависимости от вида обнаруженной конструкции. Для работы с XML-документами необходимо написать ряд обработчиков таких событий, являющихся реализациями интерфейса org.xml.sax .ContentHandler.org.w3c.dom. Одной из его реализаций является JDOM [17], а dom4j [18] предоставляет несколько упрощенную и более удобную с точки зрения Java, но не вполне соответствующую стандарту javax.xml.transform. Широко используемыми Среда .NET предназначена для более широкого использования, чем платформа J2EE. Однако ее функциональность в части, предназначенной для разработки распределенных
В рамках .NET имеются аналоги основных видов компонентов J2EE. Web-компонентам соответствуют компоненты, построенные по технологии
Тем самым, типовая архитектура
(рис 13.2) Типовая архитектура Web-приложения на основе .NETВ целом,
Обычно .NET-компоненты представляют собой набор .NET-классов и
Связь между компонентами в рамках .NET осуществляется при помощи механизма
Классы и интерфейсы, служащие основой механизма System.Runtime.Remoting и его подпространствах, в сборках mscorlib и System.Rutime.Remoting.
В рамках
Тип объекта, передаваемого по значению, должен реализовывать интерфейс System.Runtime.Serialization.ISerializable или должен быть помечен атрибутом System.SerializableAttribute. В последнем случае .NET автоматически создает код, необходимый для сериализации или
Объекты, передаваемые по ссылке, должны наследовать классу System.MarshalByRefObject. При передаче такого объекта как аргумента или результата в другом процессе (или
Более тонкую настройку удаленных вызовов можно делать при помощи наследников класса System.ContextBoundObject. Наследование этого класса говорит о том, что удаленные вызовы в объекте этого класса должны происходить в рамках некоторого контекста, являющегося частью его
Ниже находится пример взаимодействующих по механизму
Код класса, реализующего метод для удаленных обращений.
using System;
namespace Examples.Remoting
{
public class Hello : MarshalByRefObject
{
public String HelloMethod() { return "Hello!"; }
}
}
Код сервера, ожидающего обращения клиентов.
using System;
using System.Runtime.Remoting;
namespace Examples.Remoting
{
public class HelloImpl
{
public static void Main()
{
RemotingConfiguration.Configure("RemotingServer.exe.config");
Console.ReadLine();
}
}
}
Код клиентского класса.
using System;
using System.Runtime.Remoting;
namespace Examples.Remoting
{
public class HelloClient
{
public static void Main()
{
RemotingConfiguration.Configure("RemotingClient.exe.config");
Hello stub = new Hello();
Console.WriteLine("response: " + stub.HelloMethod());
}
}
}
Кроме классов, должны быть написаны конфигурационные файлы серверного и клиентского приложений. Конфигурационный файл сервера выглядит так.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.runtime.remoting>
<application>
<service>
<wellknown
mode = "Singleton"
type = "Examples.Remoting.Hello, Hello"
objectUri = "MessageServer"
/>
</service>
<channels>
<channel ref = "http" port = "8989" />
</channels>
</application>
</system.runtime.remoting>
</configuration>
Конфигурационный файл клиента.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.runtime.remoting>
<application>
<client>
<wellknown
type = "Examples.Remoting.Hello, Hello"
url = "http://hostname:8989/MessageServer"
/>
</client>
</application>
</system.runtime.remoting>
</configuration>
Чтобы запустить этот пример, нужно выполнить следующие шаги.
csc.exe /noconfig /t:library Hello.cs csc.exe /noconfig /r:Hello.dll Server.cs csc.exe /noconfig /r:Hello.dll Client.cs
В результате первой команды будет получена динамическая библиотека, содержащая определение класса Hello. В двух других она используется, чтобы предоставить ссылку на этот тип.
Server.exe
Client.exe
Если никаких ошибок не сделано, и порт 8989 на серверной машине доступен, клиент выдаст сообщение.
response: Hello!
С помощью конфигурационных файлов можно определить политику активации
System.Messaging.
Взаимодействие между компонентами
В примере на взаимодействие по
Если же это не так, необходимо иметь полноценную службу именования и/или службу каталогов. В этом качестве в .NET используется System.DirectoryServices и его подпространствах, в сборках System.DirectoryServices и System.DirectoryServices.Protocols.
Для работы с записями System.DirectoryServices.DirectoryEntry. C помощью конструкторов и методов этого класса можно создавать и изменять регистрационные записи службы каталогов. Для поиска зарегистрированных объектов по идентификаторам или свойствам используются методы класса System.DirectoryServices.DirectorySearcher.
Помимо процессов и потоков, среда .NET поддерживает так называемые
Помимо автоматически создаваемых потоков и
Целостность данных в .NET поддерживается, как и в J2EE, в основном, за счет механизма транзакций. Распределенные транзакции в .NET реализованы на базе сервера транзакций Microsoft (Microsoft Transaction Server, MTS), который появился как часть компонентной среды COM+. Интерфейсы для работы с его функциями собраны в пространстве имен System.EnterpriseServices, в сборке с таким же именем.
Автоматические транзакции поддерживаются при помощи указания у классов транзакционных атрибутов, имеющих тип System.EnterpriseServices.TransactionAttribute. Такой атрибут может принимать значения Required, RequiresNew, NotSupported, Supported и Disabled. Первые три имеют то же значение, что и в J2EE. Атрибут Supported действует аналогично Supports в J2EE. Атрибут Disabled обозначает, что транзакционный контекст вызвавшего метода будет проигнорирован.
Значение атрибутов по умолчанию для методов компонентов Disabled, у вторых — Required.
Чтобы определить класс, чьи методы могут участвовать в транзакциях, нужно унаследовать его от класса System.EnterpriseServices.ServicedComponent, определить транзакционный атрибут, а также прикрепить к сборке, содержащей этот класс, сертификат и зарегистрировать сборку в реестре COM+.
Для завершения или отката автоматической транзакции используются следующие конструкции.
System.EnterpriseServices.AutoCompleteAttribute у участвующего в транзакции метода говорит о том, что в случае нормального завершения работы метода и отсутствия проблем у других ее участников транзакция будет завершена успешно. Если же в результате работы метода будет создано исключение, транзакция будет отменена.SetComplete() и SetAbort() класса System.EnterpriseServices.ContextUtil могут использоваться для успешного завершения или отката автоматически созданной транзакции.Создание и управление транзакциями "в ручном режиме" может быть осуществлено для компонентов System.Data.Common.DbConnection и его наследников и класса System.Data.Common.DbTransaction. Для управления транзакциями при передаче сообщений используется класс System.Messaging.MessageQueueTransaction.
Так же, как и для J2EE, отказоустойчивость .NET-приложений должна обеспечиваться либо за счет использования дополнительных продуктов, либо за счет специфического проектирования приложения.
Защищенность .NET-приложений поддерживается примерно теми же методами, что и защищенность J2EE-приложений.
Здесь также имеется несколько техник аутентификации, возможность определения ролей, обеспеченных набором прав доступа к различным элементам системы, а также возможность использования различных протоколов шифрования и защищенной передачи данных, управления ключами и подтверждения целостности данных. В рамках .NET используются также многоуровневые политики защиты, которые определяют набор прав, предоставляемых коду из разных источников.
Программные интерфейсы к различным механизмам управления защищенностью приложений и ресурсов реализуются классами и интерфейсами пространства имен System.Security, находящимися в сборках mscorlib, System и System.Security.
В целом техника работы с XML-документами в .NET опирается на реализацию объектной модели документов XML ( System.Xml.XmlReader. Классы, реализующие различные парсеры XML, различные варианты представления XML-документов, а также их трансформацию на основе System.Xml, разбросанном по сборкам System.Data, System.Data.SqlXml и System.Xml.
Одной из особенностей работы с XML в .NET является встроенная возможность работы с XML-данными в рамках механизмов System.Xml.XmlDataDocument.
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.