Главная > J2EE > JSTL: Шаблоны для разработки веб-приложений в java. Часть 1

Тема Зацепин
268

Java-разработчик 🧩
235
3 минуты

JSTL: Шаблоны для разработки веб-приложений в java. Часть 1

Эта статья является логическим развитием материалов посвященных средствам отображения информации (слой View в ставшей уже классической связке Model-View-Controller). Чтобы вы понимали место, которое занимают JSTL и Velocity нужно рассказать о Страшной Ошибке постигшей разработчиков jsp. Как вы наверняка слышали, много-много лет назад java-программисты хотевшие создать веб-приложение не имели в своем распоряжении ничего кроме сервлетов. Сервлет это был класс со специальным методом (doGet или doPost), который вызывался из браузера и должен был сгенерировать html-страницу. Очевидно, что сначала нужно было на основании пришедших от клиента данных (параметры ссылки или содержимое полей формы) выполнить расчет какой-то информации, подготовить набор переменных, массивов, списков и, второй шаг, каким-то образом надо это визуализировать, т.е. перемещать html-теги и те самые подготовленные данные. И было это ужасно:

Добавлено : 3 Nov 2008, 16:09 OutputStream out = response.getOutputStream();
out.println
("");
out.println
("");
out.println
("

Привет, " + vasyanoFIO + "

"
);
out.println
( "");
out.println
("");

Потом придумали jsp. Сделали его, похоже, для того, чтобы пишущие на asp (тогда еще не было asp.net) или php, не могли тыкать в java-программистов пальцами и тихо хихикать в кулачок. Действительно типовая страница характеризуется значительным превышением количества html-кода над динамической информацией (взятой из файлов, баз данных, вычисленных веб-приложением). Поэтому логично было не встраивать html-код внутрь java-кода, а наоборот встроить java-код внутрь html-шаблона.

<%@ page contentType="text/html;charset=UTF-8" language="java"%><%StringvasuanoFIO = "Бла-бла-бла"; if ( 1 < 2) vasuanoFIO = "Бум-бам-тарарам"; %>

<%=vasuanoFIO%>

Выглядит ужасно. Конечно, если нужно сделать одну страничку и быстро, то это наилучший выход. Вот только “пихать” логику (в примере сравнение, расчет чему же будет равна переменная vasyanoFIO) это не кошерно. По мере роста количества расчетов и усложнения верстки код превращается в винегрет. Большой код не читаем. Код, где и html и логика, не читаем вдвойне. Очень скоро будет продублирована часть логики, и размазана по тысяче файлов, так что понять, откуда что взялось не возможно. Где-то тут еще “повесился” дизайнер, когда понял то, сколько ему нужно потратить здоровья, для того чтобы заменить размер шрифта заголовка h1 на h2. Вообще-то в стандарте jsp рекомендуемой практикой является вынос логики обработки запроса в объект bean. Например, задачу с приветствиями можно оформить в виде отдельного класса, добавить к нему поля (управляющие расчетом итогового значения).

public class HelloMachineBean {
public String fio;
public String age;
public String sex;

public String getFio() {
return fio;
}

public void setFio(String fio) {
this.fio = fio;
}

public String getAge() {
return age;
}

public void setAge(String age) {
this.age = age;
}

public String getSex() {
return sex;
}

public void setSex(String sex) {
this.sex = sex;
}

public String getResult (){
if ("male".equalsIgnoreCase(sex))
return "Это дядя " + fio + " его возраст "+age;
return "Это тетя "+fio+ " ее возраст "+age;
}
}

Обратите внимание на метод getResult – именно он содержит логику расчета сообщения, которое будет показано пользователю. Теперь нужно создать jsp-файл, в котором создается объект bean, наполняются его свойства значениями и в нужном месте извлекается расчет значения (getResult).

// создаем объект Логики, указываем его имя и java-класс id="helloMachine"class="t sti.HelloMachineBean"/> // теперь начинаем заполнять значениями поля этого класса-бина, синтаксис // property=”*” означает, что все пришедшие параметры запроса должны быть помещены внутрь bean-а. name="helloMachine"property="*"/> // а вот еще вариант, когда указывается конкретное имя свойства, которое нужно заполнить информацией и имя поля из http-запроса name="helloMachine"property="fio"param="fio"/> // в конце-концов, можно присвоить атрибуту значение в виде константы name="helloMachine"property="sex"value="female"/> // а теперь использование, как будто бы в составе класса helloMachine есть свойство result. // на самом деле для обращения к свойствам используются методы getter-ы, // так что фактическое существование поля класса с именем result не существенно. 

Hello name="helloMachine"property="result"/>

Такой подход имеет слишком много подводных камней (я не про то, что инициализация всех нужных полей должна быть выполнена до использования bean-а, или то, что поступающие на вход данные нужно проверить, экранировать и прочая и прочая – все это решается без проблем. Например, если создать jsp-страницу как наследник от некоторого класса сервлета, который выполняет столь нужные но рутинные действия. Основных проблем две: программисты могут (а значат, будут) смешивать java-код и html, если бы были запрещены такие теги как:

<%If ( bla-bla) … Else%>

То у нас не было бы никакого выбора, и мы должны были бы уже писать так код, чтобы четко разделить логику (bean-ы) и внешний вид (jsp). Но тут подкралась другая проблема: реальный сайт оперирует данными не только скалярными (переменная со строковым значением fio), но и списками, массивами. Так что для их обработки нам нужны циклы, условные конструкции (если сумма денег на счету меньше чем 100 баков, то вывести ее красной, иначе зеленой). Можно было бы перенести циклы и условия внутрь bean-ов, но фактически это означает, что мы должны будем внутрь этих bean-ов перетащить также и генерацию html-кода (а к чему приводит такое решение, мы уже видели на примере сервлетов). В общем, как ни крутись, но хоть какая-то примитивная обработка условий и циклов на странице должна быть, иначе мы получим гораздо большее количество проблем.

<%StringvasuanoFIO = "Нет. Ты не сможешь победить силы Зла"; if ( 1 < 2) vasuanoFIO = "Твоя борьба против каши в JSP обречена на провал, Ха-ха-ха"; %>

На далеком диком западе, в стране непуганых дизайнеров, существует страшное поверье, что если дизайнер увидит код java в странице jsp, то он сойдет с ума и ему не поможет даже волшебное зелье “Гамбургер с кока-колой”. Поэтому придумали пользовательские теги. Т.е. вы создаете java-класс, который умеет делать что-то, и внедряете его в страницу, примерно, так (детали как создавать теги, описывать их с помощью tld-файлов я пропускаю, они есть в любом уважающем себя учебнике):

/>to="vasyano@mail.ru"/>

Это очень удобно, ведь теперь дизайнер не пугается тегов, он знает, что что-то заключенное в угловые скобочки никак не может ему навредить (собственно, он может не отличать тег H1 от придуманного вами тега ). И началось время, когда все стали создавать собственные библиотеки “очень нужных” тегов. Признаюсь, я сам на начальных этапах занимался изобретением тегов вида:

test=”bla == bla”> Bla-bla-bla 

В любом случае такой подход не способствовал накоплению знаний, библиотек тегов было слишком много, их делали все кому ни лень, страдало качество. Так что появление каких-то стандартов, принятых наборов тегов и их качественная реализация с последующим клеймением позором тех, кто продолжал использовать собственные “уникально-неповторимые” поделки была предопределена. И так появились JSTL – тема сегодняшнего материала.

1. Загрузить с сайта архив с библиотекой jstl (я использую версию 1.2). 2. Добавить эту библиотеку в папку WEB-INF/lib вашего веб-приложения. 3. Подключить в начале jsp-файла с помощью специальных директив taglib те библиотеки тегов, которые хотите использовать:

Основные теги позволяющие делать циклы, условия, выводить информацию на экран:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

Теги для работы с xml-документами:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/xml" %>

Теги для работы с базами данных (Ну зачем вы это сюда вставили …):

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/sql" %>

Теги для форматирования информации перед выводом и работы с i10n и i18n:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/fmt" %>

Сначала разберем теги из библиотеки http://java.sun.com/jsp/jstl/core. Начнем мы с самого простого: нужно вывести на экран браузера некоторый текст.

<%@ page contentType="text/html;charset=UTF-8" language="java" %><%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %></span><span>Simple jsp page</span><span>

Вот, правда, смысла в такой конструкции мало, ведь простой, статический текст мы можем выводить и без использования тегов jstl. А вот если нужно вывести на экран какие-то динамически рассчитываемые величины, то c:out уже нужен:

value="12+56*2"/>

Запустили, проверили, что получилось? Да ничего не получилось: на экран вывелся сам текст формулы, а не результат вычисления 12+56*2. Дело в том, что если мы хотим вывести некоторую информацию вычисляемую “на-лету”, то эту часть значения атрибута value тега c:out нужно поместить внутрь фигурных скобок.

value="${12+56*2}"/>

Уже лучше: на экране мы увидели цифру 124. Однако вывод на экран просто статических формул не слишком частое занятие, а вот вывести значение полученной от пользователя или html-формы переменной уже лучше: Теперь если я введу в адресную строку браузера нечто вроде: http://center:8080/velo/a2.jsp?fio=%C2%E0%F1%FF (Эти кракозюбры – слово ВАСЯ) И увижу на страницу … какую-то белиберду.

Aany

Собственно, другого не ожидалось: для того чтобы заставить tomcat нормально раскодировать входящие переменные нужно еще постараться. Как, что, и почему я писал в другой своей статье посвященной Русским буквами и java. Внимание, перед тем как написать имя переменной (fio) я должен указать контекст (место, где нужно искать эту переменную). Есть список предопределенных контекстов:

Контекст Комментарий
pageScope Контекст страницы (т.е. переменные объявленные на этой странице и доступные только для этой страницы).
requestScope Доступ к таким переменным имеют все страницы, сервлеты обслуживающие один, текущий, вот этот самый, запрос пользователя.
sessionScope Доступ к переменным сохраняется на протяжении всего сеанса пользователя (пока не закроет браузер или не истечет предельное время бездействия).
applicationScope Доступ к переменным сохраняется изо всех страниц размещенных внутри веб-приложения (самый глобальный контекст).
param В этом контексте находятся все переменные, полученные страницей от пользователя либо как параметры адресной строки, либо как поля html-формы.
paramValues Список значений тех переменных, которые были переданы в страницу пользователем, правда, формат отличен от предыдущего случая. Если там param фактически имел тип HashMap, то здесь HashMap.
header В этом объекте хранится информация об http-заголовках которые были переданы от браузера клиента вашему веб-серверу.
headerValues Список значений http-заголовков.
initParam Конфигурационные параметры, указанные для вашей страницы, сервлета в файле web.xml
cookie Список переменных помещенных внутрь cookie.
pageContext Ссылка на объект pageContext (см. описание служебных объектов автоматически создаваемых внутри jsp-страницы).

Для того чтобы обратиться к переменной находящейся внутри какого-нибудь из контекстов нужно написать имя контекста, затем символ точки, и наконец имя переменной. Возможен и альтернативный синтаксис:

value="${param.fio}"/>value="${param['fio']}"/>

У тега c:out есть еще несколько атрибутов:

value="${param.fio}"default="NO DATA"escapeXml="true"/>

В этом примере, в случае если на вход странице не была подана переменная fio, то будет выведена фраза “NO DATA”. Атрибут же escapeXML служит для того чтобы экранировать (заменить специальные символы xml: знаки больше, меньше, кавычки …) на их entities (т.е. < > …)

Научившись выводить переменные самое время задуматься над тем как эти переменные создавать. Помимо очевидных вариантов: из параметров запроса, из объекта java bean с логикой, из сессии есть еще способ самим внутри страницы положить какую-нибудь переменную внутрь одного и указанных выше контекстов. Для этого мы используем тег c:set. В качестве его атрибутов указывается название контекста, куда мы хотим положить переменную, имя переменной и значение:

var="vasyano"scope="session"value="Вася Тапкин"/>var="petyano"scope="page"> Петька Козлов на странице var="petyano"scope="request"> Петька Козлов в запросе var="petyano"scope="session"> Петька Козлов в сессии var="petyano"scope="application"> Петька Козлов в приложении  vasyano: value="${sessionScope.vasyano}"/>/> petyano: value="${petyano}"/>

Здесь я показываю несколько хитрых моментов в работе jstl. Во-первых, обратите внимание, как отличаются имена контекстов при операции положить переменную (set) и операции извлечь переменную (out). В первом случае я должен писать слово session, а во втором случае – sessionScope. Также посмотрите, что я создал переменную petyan сразу во всех четырех контекстах. Когда же я вывожу эту переменную на экран, то название контекста, к которому принадлежит переменная, я не указал. В этом случае работает правило поиска нужного контекста: ищем переменную внутри pageScope, если не найдено внутри requestScope, если опять не найдено внутри sessionScope и, наконец, внутри applicationScope.

Есть еще один вариант синтакиса оператора c:set, когда нужно установить значение свойства некоторого java-bean внедренного на страницу.

target="${helloMachine}"property="fio"value="Ленка Слонова"/>value="${helloMachine.fio}"/>

Для удаления переменных (на самом деле простого присвоения имя значения null) используется оператор remove, например, так:

var="fio"scope="session"value="Vasyano Petrovno"/> fio1 = value="${fio}"/>var="fio"/> fio2 = value="${fio}"/>

Вывод переменных без предварительного их анализа, без условных операторов малополезен. Так что нам нужны операторы if и switch. Оператор if не слишком похож на своих больших братьев в java и других языках: нельзя задать ни ветку else, ни ветку elseif (elif), можно только проверить некоторое условие и если оно истинно, то сделать что-то:

test="${param.age gt 12}"> Возраст более 12 лет test="${param.age lt 25}"> Возраст менее 25 лет 

Обратите внимание на то, что я в условии использую не знаки “<” или “>”, а слова “gt” и “lt”, это необходимо т.к. в противном случае мы нарушим правила записи xml-документов. Еще есть такие слова-операторы:

eq – проверка на равенство ne – проверка на неравенство lt – строго менее чем gt – строго более чем le – меньше либо равно чему-то ge – больше или равно чему-то

У тега if есть несколько необязательных атрибутов, которые возможно пригодятся вам, чтобы не записывать повторяющиеся выражения. Так если указан атрибут var, то в эту переменную будет записан результат вычисления условия (атрибута test). Куда именно будет положена эта переменная (в какой контекст) задается атрибутом scope.

test="${param.age gt 12}"var="if_less_12"> Возраст более 12 лет test="${if_less_12}"> Еще раз повторяю: Возраст более 12 лет 

В случае если нам нужно проверить несколько условий, то оператор if – не самое лучшее решение, здесь нужно использовать тег choose -> when -> otherwise:

test="${param.age lt 10}"> Возраст менее 10 лет test="${param.age lt 20}"> Возраст в отрезке от 10 до 20 лет  Срочно пройдите на процедуру усыпления 

Теперь разберемся как работать в JSTL с циклами. Есть две разновидности циклов: для прохода по элементам некоторого списка (для прохода всех чисел в отрезке ОТ и ДО). И вторая разновидность служит для прохода по списку token-ов (частей, на которые была разбита строка на основании некоторого символа разделителя). Первый тег “c:ForEach” имеет целых 6 атрибутов управляющих его работой, но среди них нет ни одного обязательного. Все дело в том, что c:ForEach предназначен и для прохода по элементам некоторого списка, например, так:

Прежде всего, я ввел в состав описанного выше класса HelloMachineBean несколько новых методов (как-бы-настоящий свойств) возвращающих массив элементов и список элементов.

public List< String> getFriendsAsList (){
return Arrays.asList(getFriendsAsArray ());
}

public String[] getFriendsAsArray(){
return new String[]{"Васька", "Петька", "Ленка"};
}

Теперь пример использования этих данных внутри цикла:

var="friends"value="${helloMachine.friendsAsArray}"/>var="friends2"value="${helloMachine.friendsAsList}"/>items="${friends}"var="friend">

value="${friend}"/>

items="${friends2}"var="friend">

value="${friend}"/>

Как видите, мне пришлось задействовать два атрибута тега ForEach – это items играющий роль источника данных и var – переменная, в которую будет последовательно помещаться элементы массива/списка.

Второй вариант цикла ForEach предназначен для прохода по целым числам в отрезке от X до Y, например, так:

var="friend_i"begin="0"end="2">
value="${friend_i}"/> = value="${friends[friend_i]}"/>

value="${friend_i}"/> = value="${friends2[friend_i]}"/>

Обратите внимание на то, что я могу с помощью индекса (квадратных скобок) обращаться к элементами не только массива, но и списка.

Еще один атрибут для тега forEach – это step. Его назначение управлять величиной шага, с которым выполняется проход по элементам массива. Обратите внимание, что в следующем примере атрибут step умеет корректно работать не только, когда цикл перебирает цифры в отрезке от X до Y, но и когда перебирается содержимое некоторой коллекции элементов.

items="${friends}"var="friend"step="2">

value="${friend}"/>

var="friend_i"begin="0"end="2"step="2">
value="${friend_i}"/> = value="${friends[friend_i]}"/>

value="${friend_i}"/> = value="${friends2[friend_i]}"/>

И, наконец, последний атрибут для цикла For – varStatus. В эту переменную будет помещена информация о выполняемом цикле и текущем его шаге. Значение переменной разнится в зависимости от того, какая разновидность цикла нами используется, например, когда у нас обычный цикл от X до Y, то значением этой переменной будет текущий индекс:

var="friend_i"begin="0"end="2"step="2"varStatus=”friendStatus”>
friend_i = value="${friendStatus}"/>* value="${friend_i}"/> = value="${friends[friend_i]}"/>

Если же цикл выполняется по элементам коллекции, то поведение varStatus меняется. Теперь это не число, а сложный объект с информацией о начальном и конечном шаге цикла, об том первый элемент коллекции перебирается или нет, например:

items="${friends}"var="friend"step="1"varStatus="friendStatus"> Status: index=value="${friendStatus.index}"/>/> count=value="${friendStatus.count}"/>/> first=value="${friendStatus.first}"/>/> last=value="${friendStatus.last}"/>/> step=value="${friendStatus.step}"/>/>

value="${friend}"/>

Разобравшись с одной разновидностью цикла (наиболее часто встречающейся и наиболее полезной), перейдем ко второй – forTokens. Этот цикл похож на ранее приведенный forEach: совпадают многие атрибуты тега. Но ключевое отличие в том, что цикл идет по списку лексем, на которые была разбита строка:

var="str"value="Гравитон Фотон Бозон Мюон"/>items="${str}"delims=" "var="token"begin="1"varStatus="tokenStatus"step="1"> index=value="${tokenStatus.index}"/>/> count=value="${tokenStatus.count}"/>/> first=value="${tokenStatus.first}"/>/> last=value="${tokenStatus.last}"/>/> step=value="${tokenStatus.step}"/>/>

value="${token}"/>

Итак: строка “Гравитон Фотон Бозон Мюон” была разбита на отдельные подстроки с помощью разделителя delims (пробела). Цикл был начат не с первого элемента “Гравитона”, а со второго “Фотона”. На каждой итерации цикла также выводились сведения о номере этой итерации, признаке первая ли это итерация, а может последняя. Неприятность только в том, что значение переменной count использовать нельзя, эта величина не равна “4”, как ожидалось, а растет по мере изменения цикла (похоже, цикл идет по мере разбора строки, а не после его завершения). Значением атрибута tokens может быть не отдельный символ, а некоторое их количество, например, следующий пример идентичен ранее приведенному (значение delims теперь пробел, точка и запятая):

var="str"value="Гравитон,Фотон.Бозон Мюон"/>items="${str}"delims=" ,."var="token"begin="0"varStatus="tokenStatus"step="1">

value="${token}"/>

Очевидно, что написать хороший код страницы в одном файле, без разбиения его на части тяжело. Поэтому в состав JSTL входит тег, позволяющий в один jsp-файл включить другой jsp-файл, и называется этот тег import. Тег этот очень гибкий, в самом простом случае в страницу можно включить статический кусочек текста в виде html/txt-блока:

url="heading.html"/>

Однако настоящей гибкости мы можем добиться лишь, когда включаемое содержимое является динамическим. Проверим, умеет ли import “включать” в jsp-страницу результат работы другой jsp-страницы:

Включаемая страница (footer.jsp):

<%@ page import="java.util.Date" %><%@ page contentType="text/html;charset=UTF-8" language="java"%><%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %><%out.write("Сложные расчеты по внедрению информации внутрь ... " + newDate()); %>

Обратите внимание, что здесь я обращаюсь и хочу вывести на экран переменную externalVar. Откуда же она взялась?

А теперь пример кода главной страницы (обратите внимание на то, что я указал область действия переменной externalVar – значит, что она будет доступна всем страницам обслуживающим данный запрос):

var="externalVar"value="Hello from Outer page"scope="request"/>url="footer.jsp"/>

Аналогичным образом переменные можно передавать и из вложенной страницы во внешнюю (не забывайте про контекст переменных). Естественно, что на включаемой странице будут доступны и те переменные, которые были переданы главному скрипту из html-формы. Количество атрибутов управляющих поведением тега import гораздо больше, чем один адрес включаемого документа. Начнем с попытки включить как вложенную, страницу содержащую русские буквы. И конечно же мы увидели кракозюбры. Дело в том, что кодировка включаемого документа по-умолчанию рассматривается как ISO8859-1. Для того чтобы явно указать кодировку делайте так:

url="heading.html"charEncoding="utf-8"/>

Содержимое включаемой страницы можно даже не посылать сразу в браузер клиенту, а накопить в какой-то переменной, для последующей обработки, например, так:

url="heading.html"charEncoding="utf-8"var="inner_c"scope="request"/>value="${requestScope.inner_c}"escapeXml="true"/>

Последний атрибут для импорта – это varReader. В случае если мы укажем его, то результат вставки страницы не будет ни выведен на экран, ни помещен в строковую переменную var, а будет доступен только при чтении потока varReader.

Вторым наиболее часто используемым приемом сборки странички из кусочков, является перенаправление на другой адрес, для этого используем тег redirect, в качестве атрибута которого укажем url (есть еще атрибут var и scope, но глубокого смысла в их существовании я не нашел).

url="heading.html">name="fio"value="${helloMachine.fio}"/>

Тег param можно использовать и при внедрении в страницу “подстраницы”:

url="heading.jsp"charEncoding="utf-8">name="fio"value="${helloMachine.fio}"/>

Еще один малополезный тег = c:url, он служит для декорирования некоторого адреса, так если я запишу:

value="/a3.jsp"/>

То на страницу будет вставлен адрес включая контекст приложения (собственно говоря, идея контекстов специфична для java, а браузер не может отличить контекст от просто имени папки), например, так:

/Имя-Моего-Контекста/a3.jsp

Источник — http://black-zorro.com/mediawiki/JSTL:_Шаблоны_для_разработки_веб-приложений_в_java._Часть_1

Теги: j2eejstlpatternstaglib

Еще от автора

Применение WeakHashmap для списков слушателей

В статье от 11мая 1999 года Reference Objects были описаны основные идеи применения ссылочных объектов, но не приводилось детального описания. Данная статья позволит вам получить больше сведений, касающихся данной темы. В основном ссылочные объекты применяются для косвенных ссылок на память необходимую объектам. Ссылочные объекты хранятся в очереди (класс ReferenceQueue), в которой отслеживается доступность ссылочных объектов. Исходя из типа ссылочного объекта, сборщик мусора может освобождать память даже тогда, когда обычные ссылки не могут быть освобождены.

Заставки в Mustang

Согласно определению, данному в Wikipedia, заставка - это компьютерный термин, обозначающий рисунок, появляющийся во время загрузки программы или операционной системы. Заставка для пользователя является визуальным отображением инициализации программы. До выхода версии Java SE 6 (кодовое название Mustang) единственной возможностью применения заставки было создание окна, во время запуска метода main, и размещение в нем картинки. Хотя данный способ и работал, но он требовал полной инициализации исполняемой Java среды до появления окна заставки. При инициализации загружались библиотеки AWT и Swing, таким образом, появление заставки задерживалось. В Mustang появился новый аргумент командной строки, значительно облегчающий использование заставок. Этот способ позволяет выводить заставку значительно быстрее до запуска исполняемой Java среды. Окончательное добавление данной функциональности находится на рассмотрении в JCP.

Совмещение изображений

1 Введение 2 Правила визуализации и пример 3 Совмещение изображений в оперативной памяти 4 Постепенное исчезновение изображения 5 Ссылки и дополнительная информация

Еще по теме

Применение WeakHashmap для списков слушателей

В статье от 11мая 1999 года Reference Objects были описаны основные идеи применения ссылочных объектов, но не приводилось детального описания. Данная статья позволит вам получить больше сведений, касающихся данной темы. В основном ссылочные объекты применяются для косвенных ссылок на память необходимую объектам. Ссылочные объекты хранятся в очереди (класс ReferenceQueue), в которой отслеживается доступность ссылочных объектов. Исходя из типа ссылочного объекта, сборщик мусора может освобождать память даже тогда, когда обычные ссылки не могут быть освобождены.

Заставки в Mustang

Согласно определению, данному в Wikipedia, заставка - это компьютерный термин, обозначающий рисунок, появляющийся во время загрузки программы или операционной системы. Заставка для пользователя является визуальным отображением инициализации программы. До выхода версии Java SE 6 (кодовое название Mustang) единственной возможностью применения заставки было создание окна, во время запуска метода main, и размещение в нем картинки. Хотя данный способ и работал, но он требовал полной инициализации исполняемой Java среды до появления окна заставки. При инициализации загружались библиотеки AWT и Swing, таким образом, появление заставки задерживалось. В Mustang появился новый аргумент командной строки, значительно облегчающий использование заставок. Этот способ позволяет выводить заставку значительно быстрее до запуска исполняемой Java среды. Окончательное добавление данной функциональности находится на рассмотрении в JCP.

Использование потоков

1 Введение 2 Работа с выражениями типа Boolean 3 Класс JoptionPane 4 Приложение-счетчик 5 Ссылки

Перехват необрабатываемых исключений

В статье от 16 марта 2004 года Best Practices in Exception Handling были описаны приемы обработки исключений. В данной статье вы изучите новый способ обработки исключений при помощи класса UncaughtExceptionHandler добавленного в J2SE 5.0.

Использование класса LinkedHashMap

1 Введение 2 Сортировка хэш-таблицы 3 Копирование таблицы 4 Сохранение порядка доступа к элементам 5 Ссылки

Сказ про кодировки и java

С кодировками в java плохо. Т.е., наоборот, все идеально хорошо: внутреннее представление строк – Utf16-BE (и поддержка Unicode была с самых первых дней). Все возможные функции умеют преобразовывать строку из маленького регистра в большой, проверять является ли данный символ буквой или цифрой, выполнять поиск в строке (в том числе с регулярными выражениями) и прочее и прочее. Для этих операций не нужно использовать какие-то посторонние библиотеки вроде привычных для php mbstring или iconv. Как говорится, поддержка многоязычных тестов “есть в коробке”. Так откуда берутся проблемы? Проблемы возникают, как только строки текста пытаются “выбраться” из jvm (операции вывода текста различным потребителям) или наоборот пытаются в эту самую jvm “залезть” (операция чтения данных от некоторого поставщика).