3 страница. Коллекция LinkedList<E> реализует связанный список
Коллекция LinkedList<E> реализует связанный список. В отличие от мас- сива, который хранит объекты в последовательных ячейках памяти, связанный список хранит объекты отдельно, но вместе со ссылками на следующее и преды- дущее звенья последовательности. В добавление ко всем имеющимся методам в LinkedList<E> реализованы методы void addFirst(E ob), void addLast(E ob), E getFirst(), E getLast(), E removeFirst(), E removeLast() добавляющие, извле- кающие, удаляющие и извлекающие первый и последний элементы списка соот- ветственно. Класс LinkedList<E> реализует интерфейс Queue<E>, что позволяет предположить, что такому списку легко придать свойства очереди. К тому же специализированные методы интерфейса Queue<E> по манипуляции первым и
последним элементами такого списка E element(), boolean offer(E o), E peek(), E poll(), E remove() работают немного быстрее, чем соответ- ствующие методы класса LinkedList<E>. Методы интерфейса Queue<E>: E element() – возвращает, но не удаляет головной элемент очереди; boolean offer(E o) – вставляет элемент в очередь, если возможно; E peek() – возвращает, но не удаляет головной элемент очереди, возвра- щает null, если очередь пуста; E poll() – возвращает и удаляет головной элемент очереди, возвращает null, если очередь пуста; E remove() – возвращает и удаляет головной элемент очереди. Методы element() и remove() отличаются от методов peek() и poll() тем, что генерируют исключение, если очередь пуста.
28. Множества.
Интерфейс Set<E> объявляет поведение коллекции, не допускающей дуб- лирования элементов. Интерфейс SortedSet<E> наследует Set<E> и объявля- ет поведение набора, отсортированного в возрастающем порядке, заранее опреде- ленном для класса. Интерфейс NavigableSet существенно облегчает поиск элементов.
Класс HashSet<E> наследуется от абстрактного суперкласса AbstractSet<E> и реализует интерфейс Set<E>, используя хэш-таблицу для хранения коллекции. Ключ (хэш-код) используется вместо индекса для доступа к данным, что значительно ускоряет поиск определенного элемента. Скорость по- иска существенна для коллекций с большим количеством элементов. Все элемен- ты такого множества упорядочены посредством хэш-таблицы, в которой хранятся хэш-коды элементов
Класс TreeSet<E> для хранения объектов использует бинарное дерево. При добавлении объекта в дерево он сразу же размещается в необходимую позицию с уче- том сортировки. Сортировка происходит благодаря тому, что все добавляемые эле- менты реализуют интерфейсы Comparator и Comparable. Обработка операций удаления и вставки объектов происходит медленнее, чем в хэш-множествах, но быстрее, чем в списках.
Абстрактный класс EnumSet<E extends Enum<E>> наследуется от аб- страктного класса AbstractSet. Специально реализован для работы с типами enum. Все элементы такой коллекции должны принадлежать единственному типу enum, определенному явно или неявно. Внутренне множество представимо в виде вектора битов, обычно единственного long. Множества нумераторов поддержи- вают перебор по диапазону из нумераторов. Скорость выполнения операций над таким множеством очень высока, даже если в ней участвует большое количество элементов
29. Карты отображений.
Карта отображений – это объект, который хранит пару “ключ-значение”. По- иск объекта (значения) облегчается по сравнению с множествами за счет того, что его можно найти по его уникальному ключу. Уникальность объектов-ключей должна обеспечиваться переопределением методов hashCode() и equals() пользовательским классом. Если элемент с указанным ключом отсутствует в кар- те, то возвращается значение null. Классы карт отображений: AbstractMap<K,V> – реализует интерфейс Map<K,V>; HashMap<K,V> – расширяет AbstractMap<K,V>, используя хэш-таблицу, в которой ключи отсортированы относительно значений их хэш-кодов; TreeMap<K,V> – расширяет AbstractMap<K,V>, используя дерево, где ключи расположены в виде дерева поиска в строгом порядке. WeakHashMap<K,V> позволяет механизму сборки мусора удалять из карты значения по ключу, ссылка на который вышла из области видимости приложения. LinkedHashMap<K,V> запоминает порядок добавления объектов в карту и образует при этом дважды связанный список ключей. Этот механизм эффективен, только если превышен коэффициент загруженности карты при работе с кэш- памятью и др.
Для класса IdentityHashMap<K,V> хэш-коды объектов-ключей вычис- ляются методом System.identityHashCode() по адресу объекта в памяти, в отличие от обычного значения hashCode(), вычисляемого сугубо по содер- жимому самого объекта.
Интерфейсы карт: Map<K,V> – отображает уникальные ключи и значения; Map.Entry<K,V> – описывает пару “ключ-значение”; SortedMap<K,V> – содержит отсортированные ключи и значения; NavigableMap<K,V> – добавляет новые возможности поиска по ключу. Интерфейс Map<K,V> содержит следующие методы: void clear() – удаляет все пары из вызываемой карты; boolean containsKey(Object key) – возвращает true, если вызы- вающая карта содержит key как ключ; boolean containsValue(Object value) – возвращает true, если вызывающая карта содержит value как значение; Set<Map.Entry<K,V>> entrySet() – возвращает множество, содержащее значения карты; Set<K> keySet() – возвращает множество ключей; V get(Object obj) – возвращает значение, связанное с ключом obj; V put(K key, V value) – помещает ключ key и значение value в вы- зывающую карту. При добавлении в карту элемента с существующим ключом произойдет замена текущего элемента новым. При этом метод возвратит заменяе- мый элемент; void putAll(Map <? extends K, ? extends V> t) – помещает коллекцию t в вызывающую карту; V remove(Object key) – удаляет пару “ключ-значение” по ключу key; Collection<V> values() – возвращает коллекцию, содержащую значе- ния карты. Интерфейс Map.Entry<K,V> содержит следующие методы: K getKey() – возвращает ключ текущего входа; V getValue() – возвращает значение текущего входа; V setValue(V obj) – устанавливает значение объекта obj в текущем входе.
30. Унаследованные коллекции.
В ряде распределенных приложений, например с использованием сервлетов, до сих пор применяются коллекции, более медленные в обработке, но при этом потокобезопасные, существовавшие в языке Java с момента его создания, а имен- но карта Hashtable<K,V>, список Vector<E> и перечисление Enumeration<E>. Все они также были параметризованы, но сохранили все свои особенности. Класс Hashtable<K,V> реализует интерфейс Map, но обладает также не- сколькими интересными методами: Enumeration<V> elements() – возвращает перечисление (аналог итератора) для значений карты;
31. Класс Collections.
Класс Collections содержит большое количество статических методов, предназначенных для манипулирования коллекциями. С применением предыдущих версий языка было разработано множество кол- лекций, в которых никаких проверок нет, следовательно, при их использовании нельзя гарантировать, что в коллекцию не будет помещен “посторонний” объект. Для этого в класс Collections был добавлен новый метод – checkedCol- lection(): public static <E> Collection <E> checkedCollection(Collection<E> c, Class<E> type) Этот метод создает коллекцию, проверяемую на этапе выполнения, то есть в случае добавления “постороннего” объекта генерируется исключение ClassCastException:
В этот же класс добавлен целый ряд методов, специализированных для про- верки конкретных типов коллекций, а именно: checkedList(), checkedSortedMap(), checkedMap(), checkedSortedSet(), checkedSet(), а также: <T> boolean addAll(Collection<? super T> c, T... a) – до- бавляет в параметризованную коллекцию соответствующие параметризации эле- менты; <T> void copy(List<? super T> dest, List<? extends T> src) – копирует все элементы из одного списка в другой; boolean disjoint(Collection<?> c1, Collection<?> c2) – возвращает true, если коллекции не содержат одинаковых элементов; <T> List <T> emptyList(), <K,V> Map <K,V> emptyMap(), <T> Set <T> emptySet() – возвращают пустой список, карту отображения и множество соответственно; <T> void fill(List<? super T> list, T obj) – заполняет спи- сок заданным элементом ; int frequency(Collection<?> c, Object o) – возвращает количе- ство вхождений в коллекцию заданного элемента; <T extends Object & Comparable <? super T>> T max(Collection<? extends T> coll), <T extends Object & Comparable <? super T>> T min(Collection<? extends T> coll) – возвращают минимальный и максимальный элемент соответственно; <T> T max(Collection <? extends T> coll, Comparator<? super T> comp), <T> T min(Collection<? extends T> coll, Comparator<? super T> comp) – возвращают минимальный и максималь- ный элемент соответственно, используя Comparator для сравнения; <T> List <T> nCopies(int n, T o) – возвращает список из n за- данных элементов; <T> boolean replaceAll(List<T> list, T oldVal, T newVal) – заменяет все заданные элементы новыми; void reverse(List<?> list) – “переворачивает” список;
void rotate(List<?> list, int distance) – сдвигает список цик- лически на заданное число элементов; void shuffle(List<?> list) – перетасовывает элементы списка; <T> Set <T> singleton(T o), singletonList(T o), singletonMap(K key, V value) – создают множество, список и карту отображения, состоящие из одного элемента; <T extends Comparable<? super T>> void sort(List<T> list), <T> void sort(List<T> list, Comparator<? super T> c) – сортировка списка, естественным порядком и используя Comparator соответ- ственно; void swap(List<?> list, int i, int j) – меняет местами эле- менты списка стоящие на заданных позициях.
32. Класс Класс Thread и интерфейс Runnable. Жизненный цикл потока.
Потоки – средство, которое помогает организовать одновременное выполнение несколь- ких задач, каждую в независимом потоке. Потоки представляют собой классы, каждый из которых запускается и функционирует самостоятельно, автономно (или относительно автономно) от главного потока выполнения программы. Суще- ствуют два способа создания и запуска потока: расширение класса Thread или реализация интерфейса Runnable.
// пример # 1 : расширение класса Thread: Talk.java package chapt14;
public class Talk extends Thread {
public void run() {
for (int i = 0; i < 8; i++) {
System.out.println("Talking");
try { // остановка на 400 миллисекунд
Thread.sleep(400);
} catch (InterruptedException e) { System.err.print(e); } } } }
При реализации интерфейса Runnable необходимо определить его един- ственный абстрактный метод run(). Например:
/* пример # 2 : реализация интерфейса Runnable:
public class Walk implements Runnable {
public void run() {
for (int i = 0; i < 8; i++) {
System.out.println("Walking");
try {
Thread.sleep(400);
} catch (InterruptedException e) { System.err.println(e); } } }
При выполнении программы объект класса Thread может быть в одном из четырех основных состояний: “новый”, “работоспособный”, “неработоспособ- ный” и “пассивный”. При создании потока он получает состояние “новый” (NEW) и не выполняется. Для перевода потока из состояния “новый” в состояние “рабо- тоспособный” (RUNNABLE) следует выполнить метод start(), который вызы- вает метод run() – основной метод потока.
Поток может находиться в одном из состояний, соответствующих элементам статически вложенного перечисления Thread.State: NEW – поток создан, но еще не запущен; RUNNABLE – поток выполняется; BLOCKED – поток блокирован; WAITING – поток ждет окончания работы другого потока; TIMED_WAITING – поток некоторое время ждет окончания другого потока; TERMINATED — поток завершен.
Поток переходит в состояние “неработоспособный” (WAITING) вызовом ме- тодов wait(), suspend() (deprecated-метод) или методов ввода/вывода, ко- торые предполагают задержку. Для задержки потока на некоторое время (в мил- лисекундах) можно перевести его в режим ожидания (TIMED_WAITING) с помо- щью методов sleep(long millis) и wait(long timeout), при выпол- нении которого может генерироваться прерывание InterruptedException. Вернуть потоку работоспособность после вызова метода suspend() можно ме- тодом resume() (deprecated-метод), а после вызова метода wait() – методами notify() или notifyAll(). Поток переходит в “пассивное” состояние (TERMINATED), если вызваны методы interrupt(), stop() (deprecated- метод) или метод run() завершил выполнение. После этого, чтобы запустить поток еще раз, необходимо создать новый объект потока. Метод interrupt() успешно завершает поток, если он находится в состоянии “работоспособность”. Если же поток неработоспособен, то метод генерирует исключительные ситуации разного типа в зависимости от способа остановки потока. Интерфейс Runnable не имеет метода start(), а только единственный ме- тод run(). Поэтому для запуска такого потока, как Walk, следует создать объект класса Thread и передать объект Walk его конструктору. Однако при прямом вызове метода run() поток не запустится, выполнится только тело самого ме- тода. Методы suspend(), resume() и stop() являются deprecated-методами и запрещены к использованию, так как они не являются в полной мере “потоко- безопасными”.
33. Управление приоритетами и группы потоков. Управление потоками. Потоки-демоны.
Потоку можно назначить приоритет от 1 (константа MIN_PRIORITY) до 10 (MAX_PRIORITY) с помощью метода setPriority(int prior). Получить значение приоритета можно с помощью метода getPriority().
Поток с более высоким приоритетом в данном случае, как правило, монопо- лизирует вывод на консоль. Потоки объединяются в группы потоков. После создания потока нельзя изме- нить его принадлежность к группе. ThreadGroup tg = new ThreadGroup("Группа потоков 1"); Thread t0 = new Thread(tg, "поток 0"); Все потоки, объединенные группой, имеют одинаковый приоритет. Чтобы определить, к какой группе относится поток, следует вызвать метод getThreadGroup(). Если поток до включения в группу имел приоритет выше приоритета группы потоков, то после включения значение его приритета станет равным приоритету группы. Поток же со значением приоритета более низким, чем приоритет группы после включения в оную, значения своего приоритета не изменит.
Приостановить (задержать) выполнение потока можно с помощью метода sleep(время задержки) класса Thread. Менее надежный альтернативный способ состоит в вызове метода yield(), который может сделать некоторую паузу и позволяет другим потокам начать выполнение своей задачи. Метод join() блокирует работу потока, в котором он вызван, до тех пор, пока не будет закончено выполнение вызывающего метод потока.
Потоки-демоны работают в фоновом режиме вместе с программой, но не яв- ляются неотъемлемой частью программы. Если какой-либо процесс может вы- полняться на фоне работы основных потоков выполнения и его деятельность за-
ключается в обслуживании основных потоков приложения, то такой процесс мо- жет быть запущен как поток-демон. С помощью метода setDaemon(boolean value), вызванного вновь созданным потоком до его запуска, можно определить поток-демон. Метод boolean isDaemon() позволяет определить, является ли указанный поток демоном или нет.
Поток-демон (из-за вызова метода sleep(10000)) не успел завершить вы- полнение своего кода до завершения основного потока приложения, связанного с методом main(). Базовое свойство потоков-демонов заключается в возможности основного потока приложения завершить выполнение потока-демона (в отличие от обычных потоков) с окончанием кода метода main(), не обращая внимания на то, что поток-демон еще работает. Если уменьшать время задержки потока- демона, то он может успеть завершить свое выполнение до окончания работы ос- новного потока.
34. Методы synchronized. Инструкция synchronized.
Очень часто возникает ситуация, когда несколько потоков, обращающихся к некоторому общему ресурсу, начинают мешать друг другу; более того, они могут повредить этот общий ресурс. Например, когда два потока записывают информа- цию в файл/объект/поток. Для предотвращения такой ситуации может использо- ваться ключевое слово synchronized. Синхронизации не требуют только ато- марные процессы по записи/чтению, не превышающие по объему 32 бит.
public synchronized void writing(String str, int i)
Синхронизировать объект можно не только при помощи методов с соответству- ющим модификатором, но и при помощи синхронизированного блока кода. В этом случае происходит блокировка объекта, указанного в инструкции synchronized, и он становится недоступным для других синхронизированных методов и блоков. Обычные методы на синхронизацию внимания не обращают, поэтому ответствен- ность за грамотную блокировку объектов ложится на программиста.
final StringBuffer s = new StringBuffer();
new Thread() {
public void run() {
int i = 0;
synchronized (s) {
while (i++ < 3) {
s.append("A");
try {
sleep(100);
} catch (InterruptedException e) { System.err.print(e); } System.out.println(s);
} }//конец synchronized } }.start();
35. Состояния потока.
В классе Thread объявлено внутреннее перечисление State, простейшее применение элементов которого призвано помочь в отслеживании состояний потока в процессе функционирования приложения и, как следствие, в улучшении управления им
NEW, RUNNABLE, TIMED_WAITING, TERMINATED, BLOCKED, WAITING
36. Сокетные соединения по протоколу TCP/IP.
Сокеты (сетевые разъёмы) это логическое понятие, соответствующее разъ- ёмам, к которым подключены сетевые компьютеры и через которые осуществляя- ется двунаправленная поточная передача данных между компьютерами. Сокет определяется номером порта и IP-адресом. При этом IP-адрес используется для идентификации компьютера, номер порта – для идентификации процесса, рабо- тающего на компьютере. Когда одно приложение знает сокет другого, создается сокетное протоколо-ориентированное соединение по протоколу TCP/IP. Клиент пытается соединиться с сервером, инициализируя сокетное соединение. Сервер прослушивает сообщение и ждет, пока клиент не свяжется с ним. Первое сообще- ние, посылаемое клиентом на сервер, содержит сокет клиента. Сервер, в свою очередь, создает сокет, который будет использоваться для связи с клиентом, и посылает его клиенту с первым сообщением. После этого устанавливается ком- муникационное соединение.
Сокетное соединение с сервером создается клиентом с помощью объекта класса Socket. При этом указывается IP-адрес сервера и номер порта. Если ука- зано символьное имя домена, то Java преобразует его с помощью DNS-сервера к IP-адресу.
Сервер ожидает сообщения клиента и должен быть заранее запущен с указа- нием определенного порта. Объект класса ServerSocket создается с указанием конструктору номера порта и ожидает сообщения клиента с помощью метода accept()класса ServerSocket, который возвращает сокет клиента: ServerSocket server = new ServerSocket(8030); Socket socket = server.accept();
Таким образом, для установки необходимо установить IP-адрес и номер порта сервера, IP-адрес и номер порта клиента. Обычно порт клиента и сервера устанав- ливаются одинаковыми. Клиент и сервер после установления сокетного соедине- ния могут получать данные из потока ввода и записывать данные в поток вывода с помощью методов getInputStrеam() и getOutputStrеam() или к PrintStream для того, чтобы программа могла трактовать поток как выходные файлы.
37. Многопоточность.
Сервер должен поддерживать многопоточность, иначе он будет не в состоя- нии обрабатывать несколько соединений одновременно. В этом случае сервер содержит цикл, ожидающий нового клиентского соединения. Каждый раз, когда клиент просит соединения, сервер создает новый поток.
38. Датаграммы и протокол UDP.
UDP (User Datagram Protocol) не устанавливает виртуального соединения и не гарантирует доставку данных. Отправитель просто посылает пакеты по указанно- му адресу; если отосланная информация была повреждена или вообще не дошла, отправитель об этом даже не узнает. Однако достоинством UDP является высокая скорость передачи данных. Данный протокол часто используется при трансляции аудио- и видеосигналов, где потеря небольшого количества данных не может привести к серьезным искажениям всей информации. По протоколу UDP данные передаются пакетами. Пакетом в этом случае UDP является объект класса DatagramPacket. Этот класс содержит в себе передава- емые данные, представленные в виде массива байт.
Класс DatagramSocket может выступать в роли клиента и сервера, то есть он способен получать и отправлять пакеты. Отправить пакет можно с помощью метода send(DatagramPacket pac), для получения пакета используется ме- тод receive(DatagramPacket pac).
39. Интерфейс ServletContext. Интерфейс ServletConfig
Сервлет применяется для создания серверного приложения, получающего от клиента запрос, анализирующего его, делающего выборку данных из базы, а затем пересылающего клиенту страницу HTML, сгенерированную с помощью JSP на основе полученных данных. Преимуществом сервлетов перед CGI или ASP является быстродействие, переносимость на различные платформы, использование объектно- ориентированного языка высокого уровня Java, который расширяется большим числом классов и программных интерфейсов. Сервлеты поддерживаются большинством Web-серверов и являются частью платформы J2EE. Сервлеты реализуют интерфейс Servlet, в котором, кроме рассмотренных выше методов service(), init(), destroy(), предусмотре- на реализация еще двух методов: ServletConfig getServletConfig() – возвращает объект, содер- жащий параметры конфигурации сервлета; String getServletInfo() – определение информации о назначении сервлета.
Интерфейс ServletContext объявляет методы, которые сервлет применя- ет для связи с контейнером сервлетов и позволяет получать информацию о среде выполнения, а также использовать ресурсы совместно с другими объектами при- ложения. Каждому сервлету ставится в соответствие единственный объект, реали- зующий ServletContext. Контекст выполнения сервлета дает средства для общения с сервером. В частности, можно получить информацию о MIME-типе файла, добавить/удалить атрибуты контекста или записать информацию в log- файл. Получить ссылку на объект ServletContext можно вызовом метода getServletContext(). Следующие методы позволяют получить из контекста сервлета базовую ин- формацию: String getMimeType(String filename) – определение MIME-типа файла или документа. По умолчанию MIME-типом для сервлетов является text/plain, но используется обычно text/html; String getRealPath(String filename) – определение истинного маршрута файла относительно каталога, в котором сервер хранит документы; String getServerInfo() – предоставляет информацию о самом сервере. Ряд методов предназначен для управления атрибутами, с помощью которых передается информация между различными компонентами приложения (JSP, сервлетами):
Object getAttribute(String name) – получает значение атрибута по имени; Enumeration getAttributeNames() – получает список имен атрибу- тов; void setAttribute(String name, Object object) – добавляет атрибут и его значение в контекст; void removeAttribute(String name) – удаляет атрибут из контекста; ServletContext getContext(String uripath) – позволяет полу- чить доступ к контексту других ресурсов данного контейнера сервлетов; String getServletContextName()– возвращает имя сервлета, которо- му принадлежит данный объект интерфейса ServletContext. Используя объект ServletContext, можно регистрировать события серв- лета, сессии и запроса.
Ранее уже упоминался метод getServletConfig(), но не было сказано об интерфейсе ServletConfig, с помощью которого контейнер сервлетов передает информацию сервлету в процессе его инициализации. Некоторые методы класса: String getServletName() – определение имени сервлета; Enumeration getInitParameterNames() – определение имен пара- метров инициализации сервлета из дескрипторного файда web.xml; String getInitParameter(String name) – определение значения конкретного параметра по его имени. Чтобы задать параметры инициализации сервлета MyServlet, необходимо в тег <servlet> его описания вложить тег <init-param> с описанием имени и значения параметра в виде: <servlet>
<servlet-name>MyServletname</servlet-name>
<servlet-class>chapt18.MyServlet</servlet-class>
<init-param>
<param-name>mail.smtphost</param-name>
<param-value>mail.bsu</param-value>
</init-param>
<init-param>
<param-name>mail.smtpport</param-name>
<param-value>25</param-value>
</init-param>
</servlet>
40. Интерфейсы ServletRequest и HttpServletRequest. Интерфейсы ServletResponse и HttpServletResponse.
Информация от компьютера клиента отправляется серверу в виде объекта за- проса типа HttpServletRequest. Данный интерфейс является производным от интерфейса ServletRequest. Используя методы интерфейса ServletRequest, можно получить много дополнительной информации, в том числе и о сервлете и деталях протокола HTTP, закодированной и упакованной в запрос: String getCharacterEncoding() – определение символьной коди- ровки запроса; String getContentType() – определение MIME-типа (Multipurpose In- ternet Mail Extension) пришедшего запроса; String getProtocol() – определение названия и версии протокола; String getServerName(), getServerPort() – определение имени сервера, принявшего запрос, и порта, на котором запрос был принят сервером соответственно; String getRemoteAddr(), getRemoteHost() – определение IP- адреса клиента, от имени которого пришел запрос, и его имени соответственно; String getRemoteUser() – определение имени пользователя, выпол- нившего запрос; ServletInputStream getInputStream(), BufferedReader getReader() – получение ссылки на поток, ассоциированный с содержимым полученного запроса. Первый метод возвращает ссылку на байтовый поток ServletInputStream, а второй – на объект BufferedReader. В результате можно прочитать любой байт из полученного объекта-запроса. Если метод getReader() был вызван после вызова getInputStream() для этого запро- са, то генерируется исключение IllegalStateException и наоборот. При обращении к серверу, как правило, передаются параметры и их значения. Для разбора параметров и извлечения их значений применяются методы: String getParameter(String name) – определение значения пара- метра по его имени или null, если параметр с таким именем не задан; String[] getParameterValues(String name) – определение всех значений параметра по его имени;
Enumeration getParameterNames() – определение ссылки на список имен всех параметров через объект типа Enumeration. Непосредственно в интерфейсе HttpServletRequest объявлен ряд мето- дов, позволяющих манипулировать содержимым запросов: void setAttribute(String name, Object ob) – установка значе- ния атрибута компонента, являющегося внутренним параметром для передачи информации между компонентами приложения, например от сервлета к странице JSP или другому сервлету; Enumeration getAttributeNames() – извлечение перечисления имен атрибутов; Object getAttribute(String name) – извлечение значения передан- ного атрибута по имени; Cookie[] getCookies() – извлечение массива cookie, полученного с за- просом. Файл cookie – маленький файл, сохраняемый приложением на стороне клиента; String getMethod() – определение имени метода доступа к ресурсам, на основе которого построен запрос; String getQueryString() – извлечение строки HTTP-запроса.
Когда клиент переходит по адресу URL, который обрабатывается сервлетом, контейнер сервлета перехватывает запрос и вызывает метод doGet() или doPost(). Эти методы вызываются после конфигурации объектов, наследую- щих интерфейсы HttpServletRequest, HttpServletResponse. Задача методов doGet() и doPost() – взаимодействие с HTTP-запросом клиента и создание HTTP-ответа, основанного на данных запроса. Метод getWriter() объекта-ответа возвращает поток PrintWriter, который используется для за- писи символьных данных ответа.
Генерируемые сервлетами данные пересылаются серверу-контейнеру с по- мощью объектов, реализующих интерфейс ServletResponse, а сервер, в свою очередь, пересылает ответ клиенту, инициировавшему запрос. Можно получить ссылки на потоки вывода одним из двух методов: ServletOutputStream getOutputStream() – извлечение ссылки на поток ServletOutputStream для передачи бинарной информации; PrintWriter getWriter() – извлечение ссылки на поток типа PrintWriter для передачи символьной информации; Если метод getOutputStream() уже был вызван для этого ответа, то гене- рируется IllegalStateException. Обратное также верно. В интерфейсе HttpServletResponse, наследующем интерфейс ServletResponse, есть еще несколько полезных методов: void setContentType(String type) – установка MIME-типа гене- рируемых документов; void addCookie(Cookie c) – добавление cookie к объекту ответа для последующей пересылки на клиентский компьютер; void sendError(int sc, String msg) – сообщение о возникших ошибках, где sc – код ошибки, msg – текстовое сообщение; void setDateHeader(String name, long date) – добавление даты в заголовок ответа; void setHeader(String name, String value) – добавление пара- метров в заголовок ответа. Если параметр с таким именем уже существует, то он будет заменен.
Дата добавления: 2015-01-10; просмотров: 1349;