Новые статьи и уроки JAVAJAVA EE:Разработка web-приложения. GET/POST. Filter. JSTL part 2.
|
eq | равенство == |
ne | неравенство != |
gt | больше > |
lt | меньше < |
ge | больше или равно >= |
le | меньше или равно <= |
Для проверки нескольких условий удобней использовать оператор:
<c:choose>
<c:when test="${param.count lt 5}">
Значение меньше 5
</c:when>
<c:when test="${param.count lt 10}">
Значение меньше больше или равно 5 и меньше 10
</c:when>
<c:otherwise>
Больше или равно 10
</c:otherwise>
</c:choose>
<c:otherwise> - инструкция выполняющаяся по умолчанию, если выше ничего не подошло.
Рассмотрим циклы. Один из вариантов цикла мы уже видели в начале статьи. Тот же цикл можно объявить по другому:
<c:forEach var="iter" begin="0" end="2">
Итерация номер ${iter} <br/>
</c:forEach>
Объявленный таким образом цикл будет выполняться итерационно от 0 до 2 и номер текущей итерации присваивается переменой iter.
Еще два атрибута циклов это: step и varStatus.
<c:forEach var="article" step="2" items="${articles}">
${article.title}
</c:forEach
Как видно выше, атрибут step можно использовать не только в цикле от begin и до end, но и при переборе массивов.
Атрибут varStatus хранит в себе информацию о цикле. Если мы используем цикл с begin/end, то в ней хранится номер итерации, если же цикл-перебор массива, то в переменной хранится информация о том, является ли элемент первым/последний в цикле и прочее.
Закончим с циклами и рассмотрим еще несколько тэгов.
Тэг для вставки содержимого одного jsp файла в другой:
<c:import url="head.jsp" />
Перенаправление (редирект) пользователя на другую страницу:
<c:redirect url="head.jsp">
<c:param name="name" value="${paran.name}" />
</c:redirect>
Далее я считаю нужным рассмотреть библиотеку дополнительных функций объявляемой строкой:
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
В нашем самом первом примере используется функция из этой библиотеки:
${fn:substring(article.text,0,300)}
Эта функция возвращает подстроку из значения article.text с 0 символа в количестве 300 символов.
Функция проверки вхождения одной подстроки в другую (возращает знаечение true/false):
${fn:contains('Vladimir Kiril guest', 'guest')}
Та же самая проверка, но без учета регистра (возвращает значение true/false):
${fn:containsIgnoreCase('Vladimir Kiril guest', 'GUEST')}
Проверка, начинается ли одна строка с заданной подстроки:
${fn:startsWith('Vladimir Kiril guest', 'Vlad')}
Проверка, заканчивается ли одна строка заданной подстрокой:
${fn:endsWith('Vladimir Kiril guest', 'est')}
Поиск позиции в строке, с которой начинается искомая подстрока:
${fn:indexOf('Vladimir Kiril guest', 'Kiril' )}
Вычисление длины строки:
${fn:length('Stroka')}
Для вырезания подстроки из строки до заданного маркера используется функция:
${fn:substringAfter('Vladimir Kiril guest', 'gu')}
Соответственно функция, вырезающая подстроку после заданного маркера:
${fn:substringBefore('Vladimir Kiril guest', 'gu')}
Функция, приводящая все символы строки к нижнему регистру:
${fn:toLowerCase(boy)}
и к верхнему:
${fn:toUpperCase(boy)}
Для замены некой подстроки на другую используется функция:
${fn:replace('Vladimir Kiril guest', 'Kiril', 'Anna')}
Функция деление строки на массив подстрок (вторым параметром указывается разделитель):
${fn:split('Vladimir,Kiril,huest', ',')}
Склеиванием массива строк в одну занимается функция:
${fn:join(arr_string, ',')}
Теперь, когда вы знакомы с основными JSTL тэгами, можете использовать их в своих проектах, избегая всевозможные скриплеты.
Идем дальше, пора научиться обрабатывать параметры, полученные от пользователя и анализировать их.
Работа с GET и POST запросами пользователя
Теперь мы можем вновь вернуться к нашему проекту. На главной странице у нас выводятся списки статей и ссылка на каждую из них. Пришло время обработать запрос пользователя и вывести интересующею его статью.
Необходимые нам данные от пользователя, а именно номер статьи, который передается в строке запроса, хранятся в перемененной HttpServletRequest request.
Основные функции, которые мы используем в этот раз - это:
функция, возвращающая перечисления имен параметров, полученных от пользователя,
request.getParameterNames();
функция, возвращающая значение параметра по его имени,
request.getParameter("paramName");
- Откройте наш web_controller и условный оператор, определяющий, что пользователь перешел на страницу статьи, добавьте следующий код:
if ("/article".equals(userPath)){
String id=null;
Enumeration<String> params = request.getParameterNames()
} - Мы объявили переменную id, в которой будет храниться значение, переданное пользователем, и создали перечисление, в которое поместили список имен параметров.
- Далее нам необходимо пройтись по полученному списку имен и, если там есть интересующий нас параметр, то запомнить его:
while (params.hasMoreElements()) {
String param = params.nextElement();
id="id".equals(param)?request.getParameter(param):id;
} - В объявленном массиве поочередно перебираются имена всех полученных от пользователя параметров, как только будет найден параметр с именем id, его значение присваиваем одноименной переменой.
- Далее добавляем блок try catch и в нем ищем статью по полученному id. Полученное значение передаем атрибутом.
try{
Articles article = articlesFacade.find(Integer.parseInt(id));
request.setAttribute("article", article);
}catch(Exception e){
e.printStackTrace();
} - Для поиска статьи использовалась функция find, которая в качестве параметра принимает идентификатор таблицы. Теперь воспользуемся созданным нами атрибутом и распределим его поля по нужным местам в файле article.jsp.
<section>
<article>
<h1>${article.title}</h1>
<div class="text-article">
${article.text}
</div>
<div class="fotter-article>
<span class="date-article">Дата статьи: ${article.date}</span>
</div>
</article>
</section> - Теперь, переходя по ссылкам на наши статьи (например http://localhost:8080/myblog/article?id=3), мы сможем созерцать полные тексты наших статей.
Функционал просмотра статей можно считать готовым.
Фильтр
Прежде чем приступить к реализации фильтра, создадим предпосылку необходимости его использования. В файле article.jsp и перед открывающимся тэгов <section> добавьте строку кода ${param.name} :
</aside>
${param.name}
<section>
Теперь откройте любую из статей и в адресной строке браузера добавьте следующий текст: &name=Виктор, URL адрес будет выгледить примерно вот так:
http://localhost:8080/myblog/article?id=3&name=Виктор
или вот так:
http://localhost:8080/myblog/article?id=3&name=%D0%92%D0%B8%D0%BA%D1%82%D0%BE%D1%80
что по сути одно и тоже.
Обновите страницу... Вы увидите, что сервер некорректно обработал кириллицу и на выходе мы видим абсолютно нечитабельный текст:
Сервер обработал данные от пользователя, полученные GET-запросом в кодировке отличной от utf-8, то же самое произошло бы и с данными, полученными POST-запросом.
Для решения этой проблемы мы создадим фильтр, который будет обрабатывать все запросы от пользователя еще до того, как они достигнут сервлета.
- Нажмите на кнопку создания нового файла и в окне выбора типа файла укажите "Фильтр":
- На следующем шаге задайте имя фильтра web_filter и пакет filter:
- Параметры на следующих шагах оставьте по умолчанию. Пройдите все шаги до готовности фильтра.
IDE создало каркас фильтра. Его объявление происходит так же как и сервлет, путем аннотации:
@WebFilter(filterName = "web_filter", urlPatterns = {"/*"})
Думаю, после изучения аннотаций сервлета, эта аннотация вам вполне понятна. Можно установить urlPatterns чтобы указать все пути, какие должен обрабатывать данный фильтр, а можно сделать еще проще - замените аннотацию объявления фильтра на следующую:
@WebFilter(servletNames = {"web_controller"})
Мы просто указали сервлет, к которому относится фильтр и, тем самым закрепили за фильтром все пути, которые будет обрабатывать и сам сервлет.
Среда разработки сгененировала множество функций, но главной является функция doFilter; именно в этой функции происходит выполенение операций над запросами, перехваченными фильтром.
- Удалите все содержимое функции doFilter и вставьте в ее тело следующий код:
request.setCharacterEncoding("UTF-8");
chain.doFilter(request, response); - Обновите страницу /article и теперь кириллица отобразилась корректно.
Вот так, очень просто и со смыслом мы решели проблему кодировок сервера и познакомились с фильтром.
Подведем итог: в статье мы углубили наши статья о библиотеке стандартных тэгов JSTL, рассмотрели функции основной библиотеки и библиотеки дополнительных функций. Эта технология значительно упрощает работу с данными в jsp страницах, позволяет отказаться от скриплетов и не портит читабельность кода. На примере страницы статей мы познакомились с методом получения пользовательских данных и их обработки. В ходе решения задач мы столкнулись с проблемой некорректной кодировки обработки получаемых от пользователя данных, с этой проблемой мы справились с использованием фильтра.
Если вы изучаете JavaEE с самых первых статей, то наверняка уже затянулись этой технологией и ее возможностями. Однако мы едва ли прошли пол-пути из запланированных мной уроков. Могу гарантировать, что каждый последующий урок будет интереснее предыдущих, и в следующей статье мы научимся составлять собственные выборки, а главное мы научимся добавлять данные в базу, и тем самым попутно познакомимся с технологией транзакций, которую предоставляет нам JTA.
Комментарии