Начнем с того, где мы будем хранить наш код и как обмениваться им с друзьями. Думаю, не все начинающие знают про репозитории, и эта часть именно для них.
После всего этого у Вас будет ссылка на Ваше пространство. Чтобы понять, что это такое - нужно взять один из ваших проектов (или создайте какой нибудь пустой проект в NetBeans). Нажимаете на нем правой кнопочкой и у Вас в меню будет доступно «Управление версиями» -> «импортировать в репозиторий Subversion». После этого будет диалоговое окно, в котом будет путь к репозиторию - это ссылка которую Вы получили на сайте во вкладке «Исходный код».
Далее, полностью удалите проект, который вы закоммитили. Дальше зайдите в папку, где у вас проекты хранятся, и проверьте что реально все удалено. Потом возвращаетесь в NetBeans и ищете в панели меню вкладку Группа(на панели где Файл, Вид, Правка, Переход, Источник...) в нем есть наш Subversion. И в подменю на нем есть «Получить». Дальше в диалоговых окнах надо будет указать ссылку на репозиторий (это ссылка которую вы получили на сайте во вкладке «Исходный код».) И когда он предложит выкачивать папки, то по дереву репозитория нужно будет найти ваш проект и выбрать его, и по окончанию вы выкачаете свой проект. Вот так происходит обмен кодом.
Ваш проект будет постоянно синхронизироваться с репозиторием и помечать файлы, которые были изменены, или новые(то что отличается от версии на репозитории). Чтобы обновить, нужно вызвать контекстное меню, и в закладке «Управление Версиями» будет большой список того, что можно делать с проектом. «Обновлять» - это обновить свои файлы; «Фиксировать» - ложить код который Вы написали или изменили в репозиторий; «Сбрасывать» - возвращаться к версии на репозитории, и «Сравнивать» - отображение изменений строк которые отличаются от удаленных. Это способ командного обмена кодом, который используется всегда и нужно к нему привыкать.
Вы уже скачали NetBeans, поигрались с SVN - теперь перейдем к делу. Создаете проект. Нажимаете «Создать проект», там выбираете Maven-> Веб-приложение. Называете как хотите, это все Ваша фантазия. Итак, у нас есть веб-приложение, сборка нашего проекта идет мавеном, у нас есть цель и теперь наступило время подумать над тем, как ее осуществить. То есть Вы, как разработчик, должны подумать над тем, как будет выглядеть Ваше приложение, какую иметь архитектуру, дерево пакетов и так далее. Общее количество строк кода здесь около 4000 и лучше позаботиться о красивой архитектуре заранее, иначе потом Вы просто не будете понимать что где и как у Вас работает, каким чудом Вы, к примеру, выводите последнюю купленную вещь, как считаете общую сумму покупок. И если Вас потом попросят что-то доделать или добавить - Вы осознаете что проще написать все с нуля.
Ну и конечно нам нужно прикинуть наш план действий.
2) Создаем HibernateUtil (вообще суффикс или приставка Util подразумевает, что код в этом классе есть универсальный и используется множеством классов).
Итак, в HibernateUtil мы размещаем SessionFactory. Он тяжеловесный. Этот код, по идее, должен быть независим от всего приложения, так как он устанавливает соединение с базой данных при старте и должен нам давать только Сессии с базой данных. Еще мы в этом классе регистрируем наши классы-сущности. Подробнее про этот класс расскажу позже. Засунем его тоже в отдельный пакет, к примеру, edu.shop.model.hbutil.HibernateUtil.java
3) Пишем DAO.
Что в нем писать? Пишем то, что мы хотим получить от базы данных, но нам не нужно думать как получились эти данные, важен результат. К примеру, мы определяем интерфейс ProductDAO и пишем в нем методы
List
В чем идея? Если бы это приложение писал я и Вы, Вы бы сказали: «Миха, мне нужны от БД следующие данные: все товары что у меня есть в БД». Я отвечаю: «не вопрос». И далее следующее развитие событий: вы в своем коде, везде где нужно делать запросы к базе пишете следующее%
*здесь обращение к методу*.getAllProducts(); - и видите, что компилятор не ругается, а реализацию этого интерфейса я мог еще не успеть написать. И какой итог? У Вас все скомпилилось, а рабочего кода даже нет. Здесь мы применим Enums и паттерн Factory, и еще кое-что, но всему свое время. Именно в DAO нужно уделить особое внимание обработке исключений, хотя бы генерировать страницы с ошибками. Чтобы Вы быстро находили кусок неработающего кода. Иначе, Вы просто замучаетесь с отладкой.
3)Здесь начнется наша работа с Spring MVC. Это долгая история и этому будет посвящена отдельная статья. Сразу скажу - это самое сложное в этом приложении. Но я Вам покажу и более простой вариант, как выводить все, не особо заботясь про паттерн MVC.
Затронем использование скриплетов.
4) Здесь у нас будут вспомогательные классы, добавляющие всякие вкусности в наш проект: подсчет общей суммы покупок; последняя купленная вещь; вспомогательные переменные, которые пригодятся нам для работы метода, который, к примеру, будет выводить нам с БД вещи не дороже 5000 грн, или не дешевле 500; вывод всех ноутбуков марки Асус. Этот пункт тесно взаимосвязан с предыдущим.
Пока остановимся на этом. С остальным разберемся чуть позже. Итак, у нас есть намеченный план, приступим к его реализации.
Примечание. Корзина, в которой будут храниться наши купленные товары, будет как таблица в БД, это я сделал т.к на ней покажу некоторые основы работы с БД. Для реального случая целесообразнее будет использовать коллекции для хранения наших товаров.
1) Product
2) Notebook
3) Camera
4) Book
5) Cable
6) Customer
7) Cart
Поговорим немного о том, что такое класс-сущность.
Entity (Сущность) - POJO-класс, связанный с БД с помощью аннотации (@Entity) или через XML. К такому классу предъявляются следующие требования:
Должен иметь пустой конструктор (public или protected);
- Не может быть вложенным, интерфейсом или enum;
- Не может быть final и не может содержать final-полей/свойств;
- Должен содержать хотя бы одно @Id-поле.
При этом entity может:
Entities могут быть связаны друг с другом: один-к-одному, один-ко-многим, многие-к-одному и многие-ко-многим.
Использовать мы будем аннотации. И тут сразу у нас появляется возможность описать двумя способами. Либо мы будем писать аннотации непосредственно над полями, либо над геттерами. Скажу одно: правильно писать над геттерами, а причину Вы спросите в гугле. Не могу я все темы абсолютно здесь описать.
Есть еще одно что хочу сказать. Для этого придется показать 2 примера описания класса сущности. Итак, первый пример:
Коментарии к нему я написал в самом коде:
Import java.io.Serializable; import javax.persistence.*; import javax.validation.constraints.Size; /** * * @author Mikhail Shumenko */ @Entity //Этой аннотацией мы указываем, что данный класс является сущностью. @Table(name = "CART")// Этой аннотацией мы указываем, что за эту сущность в БД отвечает таблица с именем CART //Хочу отметить, что регистр не важен, эту анотацию можно не указывать, тогда хибернейт создаст нам БД с //именем как у класса public class CartEntity implements Serializable { //Здесь мы пишем аннотации над полями. Правильно писать над геттерами //Описываем Id таблицы @Id //Указываем, что это поле класса отвечает за столбец в таблице с именем Id //Если мы его указывать не будем, хибернейт создаст столбец с именем как у поля. @Column(name = "ID") //Здесь написать можно много)) Почему я написал здесь так? В общем можно в //@GeneratedValue(strategy=GenerationType.вместо TABLE написать AUTO) тогда //при первой загрузке таблицы, Id сгенерируются автоматически от 1 до своего максимального значения. //Если у вас 20 вещей в таблице, то сгенерируется от 1 до 20. //Но при последующих добавлениях, id у добавленной вещи будет примерно таким - 345768. //Я написал все так, чтобы последний мой id хранился в таблице и генерировался потом адекватно при последующих добавлениях. //Также есть SEQUENCE, но он не поддерживается в Derby, а работать мы будем именно с ней. //В общем, это нюансы. Можете узнать про них самостоятельно @TableGenerator(name = "cartid", table = "cartpktb", pkColumnName = "idCart", pkColumnValue = "idCartValue",allocationSize = 1) @GeneratedValue (strategy = GenerationType.TABLE, generator = "cartid") private Integer id; //Указываем максимальный размер. Это строка из 25 символов. @Size(max = 25) @Column(name = "NAMEITEM") //Если тип нашего поля String, то и создаваться будет столбец с типом VARCHAR(в Derby) //Если Integer, то будет столбец, в который поместить можно только Integer //boolean в Derby - это столбец с типом SMALLINT private String nameItem; @Column(name = "PRICE") private Integer price; public CartEntity() { } public CartEntity(String nameItem, int price) { this.nameItem = nameItem; this.price = price; } public CartEntity(Integer id,String nameItem, int price) { this.id=id; this.nameItem = nameItem; this.price = price; } public CartEntity(Integer id) { this.id = id; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getNameItem() { return nameItem; } public void setNameItem(String nameItem) { this.nameItem = nameItem; } public Integer getPrice() { return price; } public void setPrice(Integer price) { this.price = price; } }
Итак, у Вас есть два примера классов сущностей. Создайте остальные, используя эти примеры. Такие поля как: модель, год публикации, имя, стоимость - все на Вашу фантазию. Включите обязательно поле Available(в переводе наличие). Оно Вам потом пригодится. Можете сделать его булевым и добавить столбец с именем количество. Это все нам пригодится.
Его смысл:
- Весь доступ к базе данных в системе производится через DAO для инкапсуляции.
- Каждый экземпляр DAO отвечает за один первичный доменный объект или сущность. Если доменный объект имеет независимый цикл жизни, он должен иметь свой собственный DAO.
- DAO отвечает за операции создания, чтения (по первичному ключу), обновления и удаления (то есть, CRUD (create, read, update, delete)) доменного объекта.
- DAO может разрешать запросы, основанные на критерии, отличном от первичного ключа. Я ссылаюсь на такие методы как finder или finders. Метод finder обычно возвращает коллекцию доменных объектов, за которые отвечает DAO.
- DAO не занимается обработкой транзакций, сессий или соединений. Это делается вне DAO для обеспечения гибкости.
Подробнее всегда расскажет гугл.
Мы пока напишем DAO для наших продуктов.
Итак, подумаем что нам вообще нужно. Таблица Product будет иметь 4 поля Id,nameProduct,available+amount+actionForServlet. Она нам будет нужна, чтобы создать на нашем сайте категории. Над последним полем пока не заморачиваемся. Единственное что нам нужно - это получение списка продуктов.
Пишем интерфейс
public interface ProductDAO {
ProductDAO INSTANCE_PRODUCT= new ProductDAOImpl();
List
Реализация нашего интерфейса. Пояснения смотрим в коде
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package edu.shop.model.dao;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.Session;
/**
*
* @author Mikhail Shumenko
*/
public class ProductDAOImpl implements ProductDAO {
@Override
public List
Итак, теперь у нас есть возможность получать данные из БД. Вы можете, используя скриплеты, создать незамысловатый цикл for-each и вывести свою продукцию на вашу страницу index.jsp
Категория | //INSTANCE_PRODUCT что это такое? //В ProductDAO описана такая переменная, отвечает за создание ProductDAOImpl //Ну у нас все будет по-другому, можете особо не запоминать это. //ProductDAO INSTANCE_PRODUCT= new ProductDAOImpl(); <% for (Product product:ProductDAO.INSTANCE_PRODUCT.getProducts()) {%>"><%=product.getName()%> | <%}%>
---|---|
Наличие | <% for (Product product: ProductDAO.INSTANCE_PRODUCT.getProducts()) {%><%=product.getAvailable()%> | <%}%>
Но это на первое время, а вообще так делать плохо. Это нарушает наш паттерн MVC. Как сделать правильно я объясню в следующем уроке, если мне дадут инвайт. Во втором уроке мы займемся Spring, в третьем коснемся паттерна Factory, и углубимся в хибернейт. Для особо нетерпеливых, покажу как нужно удалять из БД, сохранять в БД и удалять полностью все из БД. Ну, а как сделать, чтобы все это взаимодействовало в целом с нашим приложением и подробное рассмотрение оставим на потом.
Также Вам нужен будет файл настройки Hibernate. Создайте в Derby БД shop. Имя и пароль пользователя root и pass соответственно. Если не получится - не расстраивайтесь - я уделю еще этому время.
О том, как заполнять наши БД поговорим позже. Можете заполнить их вручную. Либо дождаться следующего урока.
JSP (JavaServer Pages ) - технология, позволяющая веб-разработчикам легко создавать содержимое, которое имеет как статические, так и динамические компоненты. По сути, страница JSP является текстовым документом, который содержит текст двух типов: статические исходные данные, которые могут быть оформлены в одном из текстовых форматов HTML , SVG , WML , или XML , и JSP элементы, которые конструируют динамическое содержимое. Кроме этого могут использоваться библиотеки JSP тегов, а также (Expression Language), для внедрения Java-кода в статичное содержимое JSP-страниц.
JSP - одна из высокопроизводительных технологий, так как весь код страницы транслируется в java-код сервлета с помощью компилятора JSP страниц Jasper , и затем компилируется в байт-код виртуальной машины java (JVM). Контейнеры сервлетов , способные исполнять JSP страницы, написаны на языке Java, который может работать на различных платформах. JSP страницы загружаются на сервере и управляются из структуры специального Java server packet, который называется Java EE Web Application, в большинстве своём упакованные в файловые архивы .war и .ear .
Выгода, которую дает технология JSP в сравнении с другими веб-технологиями заключается в том, что JSP является платформонезависимой, переносимой и легко расширяемой технологией для разработки веб-приложений.
Начиная с версии 1.2, JavaServer Pages были разработаны в рамках Java Community Process . JSR 53 определяет оба стандарта JSP 1.2 и Servlet 2.3, а JSR 152 определяет спецификацию JSP 2.0. В мае 2006 года JSP спецификация 2.1 была выпущена под JSR 245 в рамках Java EE 5 . 10 декабря 2009 года была выпущена спецификация JSP 2.2 как содержание выпуска JSR 245.
Необходимо отметить, что эти версии кардинально отличаются от версий предыдущих, которые в свою очередь воспринимались больше, как ответ Java на ASP . Некоторые основные возможности и трюки прошлых версий были убраны или заменены другими. Например, возможность разрабатывать библиотеки тегов. Главной идеей было разделение кода и содержимого. Так как в больших объемах исходного кода трудно сориентироваться и отделить контент от самого кода, то пришла идея их разделить (перенести) с помощью JSP тегов таких как например
JSP 1.2 расширяет спецификацию JavaServer Pages 1.1 (JSP 1.1) следующим образом:
Новая версия спецификации JSP дополнена функциональностью увеличивающей скорость работы программиста. А именно:
Hello, ${ param.visitor } <% -- аналогично коду: Hello, <% =request.getParameter ("visitor" ) %> --%>
Платформа Java EE 5 главным образом фокусируется на простую разработку используя языковые аннотации Java, которые были введены J2SE 5.0 . JSP 2.1 поддерживает эту цель определением аннотаций для зависимых инъекций в JSP операторах и в контекстных слушателях (Listeners).
JavaServer Pages (JSP) позволяют отделить динамическую часть страниц от статического HTML . Процедура довольно проста, создаёте обычный код HTML (статический), а динамическую часть заключаете в специальные теги "<% %>" .
Имя вашего хоста: <% = request.getRemoteHost () %>
JSP страницы имеют расширение.jsp и размещаются там же, где и обычные Web страницы. Структура таких страниц может состоять из пяти конструкций: HTML , комментарии, скриптовые элементы, директивы и действия. JSP страница при компиляции преобразуется в обычный сервлет со статическим содержимым, которое направляется в поток вывода, связанный с методом service. Поэтому при первом запросе этот процесс может вызвать некую задержку, но в большинстве своём незаметную первому пользователю. Комментарии в документе или программе служат к объяснению содержимого. Они не являются причиной замедления программы, так как транслятор и исполнитель их игнорируют. Скриптовые элементы позволяют вам указать код на языке Java , который впоследствии станет частью конечного сервлета, директивы дадут вам возможность управлять всей структурой сервлета, а действия служат для задания существующих используемых компонентов, а также для контроля над поведением движка JSP. Для упрощения работы со скриптами имеются заранее определённые переменные, такие как request, response, pageContext, session, out, application, config, page, exception . Пример JSP страницы с использованием всех составляющих JSP конструкции:
Комментарии используются для пояснения исходного текста программы. В JSP-страницах комментарии можно разделить на две группы:
Комментарии исходного кода JSP отмечаются специальной последовательностью символов: <%-- в начале и --%> в конце комментария. Данный вид комментариев удаляется на этапе компиляции JSP-страницы и потому не доступны пользователям. Пример JSP-комментария:
<% -- Отобразит каталог изделий и актуальную корзину покупателя. --%>
Комментарии HTML -разметки оформляются в соответствии с правилами языка HTML. Данный вид комментариев рассматривается JSP-компилятором как статический текст и помещается в выходной HTML-документ. JSP-выражения внутри HTML-комментариев исполняются. Пример HTML-комментария:
-->
Спецификация JSP различает три типа скриптовых элементов:
Объявления обычно используются для определения переменных, методов, внутренних классов и остальных действующих Java конструкций на уровне класса. В выражения вкладываются любые действующие выражения Java. С помощью скриплетов в JSP страницы вкладываются работающие части кода Java. Все эти элементы начинаются знаками <% и заканчиваются %> . Обратите внимание и на то, что все скриптовые элементы отличаются немного записью конструкции. Объявления используют восклицательный знак (! ) в конструкции (<%! %>), а выражения знак равенства (=) (<%= %>), в то время как скриплеты используют стандартный формат записи (<% %>).
Объявления JSP позволят вам задавать переменные, методы, внутренние классы и так далее. Другими словами объявления Вы используете для определения конструкций Java, которые Вы в программе используете. Так как объявления не осуществляют вывода, то обычно они используются совместно с JSP выражениями или скриплетами. В приведённом в качестве примера фрагменте JSP отображается количество запросов к данной странице с момента загрузки сервера (или с момента последнего изменения и перезагрузки сервлета). Обратите внимание, что в примере мы используем как объявление, так и выражение и что внутри конструкции после объявления стоит точка с запятой (; ):
<%! private int accessCount = 0 ; %> Количество обращений к странице с момента загрузки сервера: <% = ++accessCount %>
Выражения JSP применяются для того, чтобы вставить значения Java непосредственно в вывод. Выражения Java вычисляются, конвертируются в строку и вставляются в страницу. Эти вычисления проходят во время выполнения (то есть при запросе страницы), а потому существует полный доступ к информации о самом запросе. В выражениях можно использовать постоянные, переменные, вызовы различных методов. Все выражения, вне зависимости от сложности их содержимого, вычисляются в один результат или число. JSP страницы полагаются на JSP Writer, который берёт любой результат выражения, переводит его в тип String (текстовый) и заносит в буферную память. Например, следующий код служит для отображения даты и времени запроса данной страницы:
Текущее время: <% = new java.util .Date () %> Имя вашего хоста: <% = request.getRemoteHost () %>
Необходимо обратить внимание на три правила:
Если вы хотите сделать что-то большее чем просто вставку выражений, то скриплеты JSP дадут вам возможность вставить любой код в метод сервлета, который будет создан при обработке данной страницы. В данном случае Вы можете использовать большинство конструкций Java. Скриплеты также имеют доступ к тем же заранее определённым переменным, что и выражения. Поэтому, например, если вы хотите вывести что-нибудь на страницу, вы должны использовать заранее определённую переменную out .
<% String queryData = request.getQueryString () ; out.println ("Дополнительные данные запроса: " + queryData) ; %>
Обратите внимание на то, что код внутри скриплета вставляется в том виде, как он был записан, и весь статический HTML (текст шаблона) до или после скриплета конвертируется при помощи оператора print . Например, следующий фрагмент JSP содержит смешанный текст шаблона и скриплета:
<% if (Math .random () < 0.5 ) { %> < B> Удачного< /B> вам дня! <% } else { %> < B> Неудачного< /B> вам дня! <% } %>
После преобразования скриплета код будет выглядеть следующим образом:
If (Math .random () < 0.5 ) { out.println ("Удачного вам дня!" ) ; } else { out.println ("Неудачного вам дня!" ) ; }
Это означает, что скриплеты не обязательно должны содержать завершённые фрагменты Java, и что оставленные открытыми блоки могут оказать влияние на статический HTML вне скриплета.
JSP страница может послать сообщение соответствующему контейнеру с указаниями какие действия необходимо провести. Эти сообщения называются директивами. Все директивы начинаются с <%@ , затем следует название директивы и один или несколько атрибутов со значениями, и заканчиваются %> . Директивы в JSP странице приводят к тому, что контейнер пошлёт заявку на исполнение определённой службы, которая в генерированном документе не объявляется. Форму записи директив можно изобразить следующим образом:
<% @ директива атрибут="значение" %>
Вы также можете объединить установку нескольких атрибутов для одной директивы:
<% @ директива атрибут1 ="значение1" атрибут2 ="значение2" ... атрибутN="значениеN" %>
Существует три основных типа директив: page , которая позволяет вам совершать такие операции, как импорт классов, изменение суперкласса сервлета, и т. п.; include , которая даёт вам возможность вставить файл в класс сервлета при трансляции JSP файла в сервлет; и taglib , позволяющий расширить множество тегов своими собственными, которые JSP контейнер способен истолковать.
Как можно догадаться из названия, данная директива предоставляет атрибуты для JSP страницы. Атрибуты, определённые в этой директиве, внедряются в данную JSP страницу и на все её вложенные статические элементы, независимо от того были ли они вставлены с помощью директивы include или с помощью действия jsp:include . Форма записи директивы page следующая:
<% @ page атрибут=“значение“ %>
В качестве примера приведём следующую запись:
<% @ page import =”java.util .* , com.myclasses .* ”, buffer=”15kb” %>
Эта директива заявляет, что JSP страница импортирует классы из двух пакетов Java, java.util и com.myclasses , а потом уточняет размер буферной памяти, которая должна быть использована для обработки данной JSP страницы.
<% @ page import ="java.util.Date, javax.text.SimpleDateFormat, com.myclasses.*" %>
<% @ page language=”java” %>
<% @ page extends =”mojPaket.PrimerHttp ” %>
<% @ page session=”false ” %>
<% @ page buffer=”12kb” %>
<% @ page buffer=”16kb” autoflush=”true ” %>
<% @ page isThreadSafe=”false ” %>
<% @ page info=” версия:1.0 ” %>
<% @ page errorPage=“/myweb/errors/myerror.jsp “ %>
<% @ page isErrorPage=”true ” %>
<% @ page contentType="text/plain" %>
Того же результата можно добиться и использованием скриплета:
<% response.setContentType ("text/plain" ) ; %>
Эта директива позволяет Вам включать файлы в сервлет в процессе трансляции JSP страницы. Использование директивы выглядит следующим образом:
<% @ include file="относительный url" %>
Заданный URL обычно интерпретируется относительно JSP страницы, на которой расположена ссылка, но, как и при использовании любых других относительных URL вы можете задать системе положение интересующего вас ресурса относительно домашнего каталога Web сервера, добавив в начало URL символ «/ ». Содержимое подключаемого файла обрабатывается как обычный текст JSP и поэтому может включать такие элементы как статический HTML , элементы скриптов, директивы и действия. Например, многие сайты используют небольшую панель навигации на каждой странице. В связи с проблемами использования фреймов HTML часто эта задача решается размещением небольшой таблицы сверху или в левой половине страницы, HTML код которой многократно повторяется для каждой страницы сайта. Директива include наиболее естественный способ решения этой задачи, избавляющий разработчика от кошмара рутины копирования HTML в каждый отдельный файл. Это происходит следующим образом:
< html> < head> < title> Тестовая страница< /title> < /head> < body> <% @ include file="/navbar.html" %> < /body> < /html>
Учтите что поскольку директива include подключает файлы в ходе трансляции страницы, то после внесения изменений в панель навигации вам потребуется повторная трансляция всех использующих её JSP страниц. Что в данном случае является хорошим компромиссом, поскольку как правило панель навигации меняется достаточно редко и процесс подключения не теряет своей эффективности. Если же подключённые файлы меняются довольно часто, вы можете использовать вместо этого действие jsp:include . Это действие подключает файл в процессе обращения к JSP.
Как уже известно, в JSP страницах элементы записываются с помощью знаков (условных знаков, меток, марок). Множество знаков, которые JSP контейнер способен истолковать, можно расширить с помощью так называемых библиотек знаков. Также к расширенному множеству знаков можно присоединять действия, вследствие чего происходит расширение самого языка JSP. Действия можно разделить на стандартные и собственные. Обобщённый способ записи может выглядеть так:
<% @ taglib uri=”URI к библиотеке знаков” prefix=“префикс знака“ %>
Библиотеку знаков необходимо идентифицировать с помощью URI адреса (уникального идентификатора ресурса). URI может быть как абсолютным так и отностительным. Уникальный идентификатор ресурса определяет расположение библиотеки знаков (TLD), который определяет собственные знаки этой библиотеки. Пример записи директивы:
<% @ taglib uri=”http://www.moywebserver.ru/naydiznaki.tld” prefix=”iskat” %>
JSP страница может содержать бесконечное кол-во директив taglib , но для каждой директивы необходимо установить различные префиксы, которые определяют содержимое библиотеки на странице. В качестве префикса можете использовать какой угодно текст, слово. В то время, как директиву taglib можно использовать где угодно на JSP странице, все собственные знаки, которые эти директивы используют, должны использоваться за ними.
Действия JSP используют конструкции с синтаксисом XML для управления работой движка сервлета. Вы можете динамически подключать файл, многократно использовать компоненты JavaBeans , направить пользователя на другую страницу или сгенерировать HTML для Java plugin. Все эти действия детально рассмотрены далее. Помните что как и во всем XML , имена элементов и атрибутов регистрозависимы. Действия можно разделить на две группы: стандартные и созданные (собственные, что создает сам программист). Допустимо применение следующих стандартных действий:
Это действие позволяет загружать JavaBean для последующего использования на JSP странице. Эта возможность позволяет многократно использовать классы Java, не отказываясь при этом от преимуществ, предоставляемых сервлетами JSP. Помимо этого, это один из способов, как большую часть обработки Java исключить из JSP страницы. Если перенести обработку Java из JSP страницы до JavaBean, то потом эти функции можно использовать и в остальных JSP страницах. Простейший синтаксис для указания используемого bean:
< jsp:useBean id="имя" class ="пакет.class" />
Как правило это означает «создание нового экземпляра объекта класса, заданного через class , и его связь с переменной с именем, заданным при помощи id ». Однако можно задать атрибут scope (принимает значения page|request|session|application , page для страницы, request для запросов, session для сессий или диалогов, application для аппликаций), который ассоциирует bean не только с текущей страницей. В таком случае, полезно получить ссылки на существующие beans , и действие jsp:useBean создает экземпляр нового объекта лишь в том случае если не существует ни одного объекта с теми же значениями id и scope . Теперь, когда у вас есть bean , вы можете изменять его свойства при помощи действия jsp:setProperty , или используя для этого скриплет и явно вызывая метод объекта с именем переменной заданном ранее через атрибут id . Recall that with beans , когда вы говорите «у этого bean есть свойство типа X с названием foo », вы на самом деле имеете ввиду «у этого класса есть метод getFoo , который возвращает данные типа X, и другой метод setFoo , которому в качестве параметра передается X.» Действие jsp:setProperty более подробно рассмотрено в следующем разделе, но сейчас вы должны запомнить что вы можете либо явно задавать value , задавая атрибут param , чтобы получить значение из соответствующего параметра запроса, или просто перечислить свойства, чтобы получить значения из параметров запроса с теми же именами что и свойства. Вы можете получить значения существующих свойств при помощи выражений JSP или скриплетов, вызвав соответствующий метод getXxx , или (чаще всего), воспользовавшись действием jsp:getProperty .
Класс, заданный для bean, должен находиться в обычном каталоге классов сервера, а не в части, зарезервированной для классов, автоматически перезагружаемых после редактирования. Например, для Java Web Server, все используемые классы должны размещаться в каталоге classes или в .jar файле каталога lib , а не в каталоге servlets . Ниже приведен простой пример, загружающий bean и устанавливающий/получающий простой строковый параметр.
BeanTest.jsp
"-//W3C//DTD HTML 4.0 Transitional//EN" > < html> < head> < title>< /title> < /head> < body> < h1> Многократное использование JavaBeans в JSP< /h1> < jsp:useBean id="test" class ="hall.SimpleBean" /> < jsp:setProperty name="test" property="message" value="Привет, WWW" /> < p> Сообщение: < jsp:getProperty name="test" property="message" /> < /p> < /body> < /html>
SimpleBean.java
Package hall ; public class SimpleBean { private String message = "Текст сообщения не задан" ; public String getMessage() { return (message) ; } public void setMessage(String message) { this .message = message; } }
Еще несколько деталей о использовании jsp:useBean . Простейший способ использовать bean - это использование конструкции:
< jsp:useBean id="имя" class ="пакет.class" />
для загрузки bean , а затем использовать jsp:setProperty и jsp:getProperty для модификации и получения его свойств (параметров). Однако существуют еще два других способа. Во-первых, вы можете использовать формат контейнера, а именно:
< jsp:useBean ...> Тело < /jsp:useBean>
для того чтобы обеспечить выполнение Тела только в том случае, если экземпляр bean создается впервые, а не тогда, когда находится и используется уже существующий bean . Как обсуждается далее, beans могут совместно использоваться, поэтому не каждое выражение jsp:useBean приводит к созданию экземпляра нового bean . Во-вторых, кроме id и class , существуют еще три других атрибута, которые вы можете использовать: scope , type , и beanName . Эти атрибуты описаны далее:
Вы можете использовать jsp:setProperty для присвоения значений свойствам ранее описанных beans . Вы можете делать это двумя способами. Во-первых, вы можете использовать jsp:setProperty после, но вне элемента jsp:useBean , так как это показано в примере:
< jsp:useBean id="myName" ... /> ... < jsp:setProperty name="myName" property="someProperty" ... />
В этом случае jsp:setProperty выполняется независимо от того, был ли найден существующий bean или был создан новый экземпляр. Другим вариантом заключается в размещении jsp:setProperty в теле элемента jsp:useBean , как это показано в другом примере:
< jsp:useBean id="myName" ... > ... < jsp:setProperty name="myName" property="someProperty" ... /> < /jsp:useBean>
При этом jsp:setProperty выполняется лишь в том случае, если был создан новый экземпляр объекта, а не тогда, когда находится уже существующий. Действие jsp:setProperty допускает применение следующих четырех атрибутов:
< jsp:setProperty name="orderBean" property="numberOfItems" param="numItems" />
Если вы не используете ни value , ни param , это приравнивается к тому, как если бы вы задали имя param совпадающее с именем property . Вы можете применить этот принцип автоматического использования свойств запроса, чьи имена совпадают с именами свойств и пойти далее, задав в качестве имени свойства «* » и опустив параметры value и param . В этом случае сервер обработает допустимые свойства и параметры запроса, на предмет совпадения их с идентичными именами. Далее приведен пример в котором используется bean для создания таблицы простых чисел. Если существует параметр numDigits в данных запроса, он передается в свойство bean numDigits . Аналогично для numPrimes . JspPrimes.jsp
"-//W3C//DTD HTML 4.0 Transitional//EN" > < html> < head> < title> Многократное использование JavaBeans в JSP< /title> < /head> < body> < h1> Многократное использование JavaBeans в JSP< /h1> < jsp:useBean id="primeTable" class ="hall.NumberedPrimes" /> < jsp:setProperty name="primeTable" property="numDigits" /> < jsp:setProperty name="primeTable" property="numPrimes" /> < p> Несколько < jsp:getProperty name="primeTable" property="numDigits" /> символьных простых чисел: < jsp:getProperty name="primeTable" property="numberedList" /> < /p> < /body> < /html>
Этот элемент определяет значение свойства bean , конвертирует его в строку и направляет в поток вывода. Для выполнения действия требуется задание двух атрибутов: имени bean , которое предварительно задается в действии jsp:useBean , и имя свойства, значение которого должно быть определено. Далее приведен пример использования этого действия:
< jsp:useBean id="itemBean" ... /> ... < UL> < LI> Количество предметов: < jsp:getProperty name="itemBean" property="numItems" /> < LI> Цена за штуку: < jsp:getProperty name="itemBean" property="unitCost" /> < /UL>
Это действие позволяет вставлять содержимое файлов в генерируемую страницу. Синтаксис действия:
< jsp:include page="относительный URL" flush="true" />
В отличие от директивы include , которая вставляет файл на этапе трансляции JSP страницы, это действие вставляет файл при запросе страницы. Это приводит к некоторой потере эффективности и исключает возможность наличия во вставляемом файле кода JSP, но зато дает существенное преимущество в гибкости.
Пример вставки содержимого четырех файлов в JSP-страницу:
"http://www.w3.org/TR/html4/strict.dtd" > < html> < head> < title> Новости< /title> < /head> < body> < h1> Новости< /h1> < p> Вот фрагменты наших четырех самых популярных статей:< /p> < ol> < li>< jsp:include page="news/Item1.html" flush="true" />< /li> < li>< jsp:include page="news/Item2.html" flush="true" />< /li> < li>< jsp:include page="news/Item3.html" flush="true" />< /li> < li>< jsp:include page="news/Item4.html" flush="true" />< /li> < /ol> < /body> < /html>
Это действие позволяет вам передать запрос другой статической HTML странице, сервлету или JSP странице. В отличие от действия jsp:include обработка актуальной страницы заканчивается. Оно использует один атрибут page , который должен содержать относительный URL и на основании которого упорядочен объект request . К исходным параметрам запроса, которой передается другой странице, можете с помощью действия jsp:param добавить и другие параметры. Значением атрибута page может быть как статическое значение, так и вычисляемое в процессе запроса, что и показано на следующих двух примерах:
< jsp:forward page="/utils/errorReporter.jsp" /> < jsp:forward page="<%= какое-нибудьВыражениеНаJava %>" />
Также с помощью действия jsp:forward можно передать управление на другую страницу, но с условием, что перед вызовом этого действия ничего не было записано в выходящую буферную память (иначе будет вызвано исключение IllegalStateException).
Это действие предоставляет информацию типа название/значение. Данное действие используется в основном вместе со знакомыми уже действиями jsp:include и jsp:forward . Кроме этого его можно использовать и вместе с действием jsp:plugin . В остальных случаях использование этого действия не имеет значения. Использование jsp:param с действиями jsp:include и jsp:forward передаться новым страницам исходный объект request , который будет расширен на новые параметры. Если Вы зададите новые значения для уже существующих параметров, то именно новые значения будут иметь преимущество. С помощью действия jsp:params можно задать сразу несколько параметров
Это действие позволяет вам вставить элемент OBJECT или EMBED (в зависимости от типа используемого браузера), необходимый для запуска аплетов, использующих plugin Java. Другими словами данное действие служит к генерированию HTML для вложения Java API в JSP страницу. Таким же образом можете вставлять URL для скачивания модулей для Java API от JavaSoft, который предоставляет возможность запускать аплеты внутри браузера. Форма записи данного действия выглядит следующим образом.
Начнем с того, где мы будем хранить наш код и как обмениваться им с друзьями. Думаю, не все начинающие знают про репозитории, и эта часть именно для них.
После всего этого у Вас будет ссылка на Ваше пространство. Чтобы понять, что это такое - нужно взять один из ваших проектов (или создайте какой нибудь пустой проект в NetBeans). Нажимаете на нем правой кнопочкой и у Вас в меню будет доступно «Управление версиями» -> «импортировать в репозиторий Subversion». После этого будет диалоговое окно, в котом будет путь к репозиторию - это ссылка которую Вы получили на сайте во вкладке «Исходный код».
Далее, полностью удалите проект, который вы закоммитили. Дальше зайдите в папку, где у вас проекты хранятся, и проверьте что реально все удалено. Потом возвращаетесь в NetBeans и ищете в панели меню вкладку Группа(на панели где Файл, Вид, Правка, Переход, Источник...) в нем есть наш Subversion. И в подменю на нем есть «Получить». Дальше в диалоговых окнах надо будет указать ссылку на репозиторий (это ссылка которую вы получили на сайте во вкладке «Исходный код».) И когда он предложит выкачивать папки, то по дереву репозитория нужно будет найти ваш проект и выбрать его, и по окончанию вы выкачаете свой проект. Вот так происходит обмен кодом.
Ваш проект будет постоянно синхронизироваться с репозиторием и помечать файлы, которые были изменены, или новые(то что отличается от версии на репозитории). Чтобы обновить, нужно вызвать контекстное меню, и в закладке «Управление Версиями» будет большой список того, что можно делать с проектом. «Обновлять» - это обновить свои файлы; «Фиксировать» - ложить код который Вы написали или изменили в репозиторий; «Сбрасывать» - возвращаться к версии на репозитории, и «Сравнивать» - отображение изменений строк которые отличаются от удаленных. Это способ командного обмена кодом, который используется всегда и нужно к нему привыкать.
Вы уже скачали NetBeans, поигрались с SVN - теперь перейдем к делу. Создаете проект. Нажимаете «Создать проект», там выбираете Maven-> Веб-приложение. Называете как хотите, это все Ваша фантазия. Итак, у нас есть веб-приложение, сборка нашего проекта идет мавеном, у нас есть цель и теперь наступило время подумать над тем, как ее осуществить. То есть Вы, как разработчик, должны подумать над тем, как будет выглядеть Ваше приложение, какую иметь архитектуру, дерево пакетов и так далее. Общее количество строк кода здесь около 4000 и лучше позаботиться о красивой архитектуре заранее, иначе потом Вы просто не будете понимать что где и как у Вас работает, каким чудом Вы, к примеру, выводите последнюю купленную вещь, как считаете общую сумму покупок. И если Вас потом попросят что-то доделать или добавить - Вы осознаете что проще написать все с нуля.
Ну и конечно нам нужно прикинуть наш план действий.
2) Создаем HibernateUtil (вообще суффикс или приставка Util подразумевает, что код в этом классе есть универсальный и используется множеством классов).
Итак, в HibernateUtil мы размещаем SessionFactory. Он тяжеловесный. Этот код, по идее, должен быть независим от всего приложения, так как он устанавливает соединение с базой данных при старте и должен нам давать только Сессии с базой данных. Еще мы в этом классе регистрируем наши классы-сущности. Подробнее про этот класс расскажу позже. Засунем его тоже в отдельный пакет, к примеру, edu.shop.model.hbutil.HibernateUtil.java
3) Пишем DAO.
Что в нем писать? Пишем то, что мы хотим получить от базы данных, но нам не нужно думать как получились эти данные, важен результат. К примеру, мы определяем интерфейс ProductDAO и пишем в нем методы
List
В чем идея? Если бы это приложение писал я и Вы, Вы бы сказали: «Миха, мне нужны от БД следующие данные: все товары что у меня есть в БД». Я отвечаю: «не вопрос». И далее следующее развитие событий: вы в своем коде, везде где нужно делать запросы к базе пишете следующее%
*здесь обращение к методу*.getAllProducts(); - и видите, что компилятор не ругается, а реализацию этого интерфейса я мог еще не успеть написать. И какой итог? У Вас все скомпилилось, а рабочего кода даже нет. Здесь мы применим Enums и паттерн Factory, и еще кое-что, но всему свое время. Именно в DAO нужно уделить особое внимание обработке исключений, хотя бы генерировать страницы с ошибками. Чтобы Вы быстро находили кусок неработающего кода. Иначе, Вы просто замучаетесь с отладкой.
3)Здесь начнется наша работа с Spring MVC. Это долгая история и этому будет посвящена отдельная статья. Сразу скажу - это самое сложное в этом приложении. Но я Вам покажу и более простой вариант, как выводить все, не особо заботясь про паттерн MVC.
Затронем использование скриплетов.
4) Здесь у нас будут вспомогательные классы, добавляющие всякие вкусности в наш проект: подсчет общей суммы покупок; последняя купленная вещь; вспомогательные переменные, которые пригодятся нам для работы метода, который, к примеру, будет выводить нам с БД вещи не дороже 5000 грн, или не дешевле 500; вывод всех ноутбуков марки Асус. Этот пункт тесно взаимосвязан с предыдущим.
Пока остановимся на этом. С остальным разберемся чуть позже. Итак, у нас есть намеченный план, приступим к его реализации.
Примечание. Корзина, в которой будут храниться наши купленные товары, будет как таблица в БД, это я сделал т.к на ней покажу некоторые основы работы с БД. Для реального случая целесообразнее будет использовать коллекции для хранения наших товаров.
1) Product
2) Notebook
3) Camera
4) Book
5) Cable
6) Customer
7) Cart
Поговорим немного о том, что такое класс-сущность.
Entity (Сущность) - POJO-класс, связанный с БД с помощью аннотации (@Entity) или через XML. К такому классу предъявляются следующие требования:
Должен иметь пустой конструктор (public или protected);
- Не может быть вложенным, интерфейсом или enum;
- Не может быть final и не может содержать final-полей/свойств;
- Должен содержать хотя бы одно @Id-поле.
При этом entity может:
Entities могут быть связаны друг с другом: один-к-одному, один-ко-многим, многие-к-одному и многие-ко-многим.
Использовать мы будем аннотации. И тут сразу у нас появляется возможность описать двумя способами. Либо мы будем писать аннотации непосредственно над полями, либо над геттерами. Скажу одно: правильно писать над геттерами, а причину Вы спросите в гугле. Не могу я все темы абсолютно здесь описать.
Есть еще одно что хочу сказать. Для этого придется показать 2 примера описания класса сущности. Итак, первый пример:
Коментарии к нему я написал в самом коде:
Import java.io.Serializable; import javax.persistence.*; import javax.validation.constraints.Size; /** * * @author Mikhail Shumenko */ @Entity //Этой аннотацией мы указываем, что данный класс является сущностью. @Table(name = "CART")// Этой аннотацией мы указываем, что за эту сущность в БД отвечает таблица с именем CART //Хочу отметить, что регистр не важен, эту анотацию можно не указывать, тогда хибернейт создаст нам БД с //именем как у класса public class CartEntity implements Serializable { //Здесь мы пишем аннотации над полями. Правильно писать над геттерами //Описываем Id таблицы @Id //Указываем, что это поле класса отвечает за столбец в таблице с именем Id //Если мы его указывать не будем, хибернейт создаст столбец с именем как у поля. @Column(name = "ID") //Здесь написать можно много)) Почему я написал здесь так? В общем можно в //@GeneratedValue(strategy=GenerationType.вместо TABLE написать AUTO) тогда //при первой загрузке таблицы, Id сгенерируются автоматически от 1 до своего максимального значения. //Если у вас 20 вещей в таблице, то сгенерируется от 1 до 20. //Но при последующих добавлениях, id у добавленной вещи будет примерно таким - 345768. //Я написал все так, чтобы последний мой id хранился в таблице и генерировался потом адекватно при последующих добавлениях. //Также есть SEQUENCE, но он не поддерживается в Derby, а работать мы будем именно с ней. //В общем, это нюансы. Можете узнать про них самостоятельно @TableGenerator(name = "cartid", table = "cartpktb", pkColumnName = "idCart", pkColumnValue = "idCartValue",allocationSize = 1) @GeneratedValue (strategy = GenerationType.TABLE, generator = "cartid") private Integer id; //Указываем максимальный размер. Это строка из 25 символов. @Size(max = 25) @Column(name = "NAMEITEM") //Если тип нашего поля String, то и создаваться будет столбец с типом VARCHAR(в Derby) //Если Integer, то будет столбец, в который поместить можно только Integer //boolean в Derby - это столбец с типом SMALLINT private String nameItem; @Column(name = "PRICE") private Integer price; public CartEntity() { } public CartEntity(String nameItem, int price) { this.nameItem = nameItem; this.price = price; } public CartEntity(Integer id,String nameItem, int price) { this.id=id; this.nameItem = nameItem; this.price = price; } public CartEntity(Integer id) { this.id = id; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getNameItem() { return nameItem; } public void setNameItem(String nameItem) { this.nameItem = nameItem; } public Integer getPrice() { return price; } public void setPrice(Integer price) { this.price = price; } }
Итак, у Вас есть два примера классов сущностей. Создайте остальные, используя эти примеры. Такие поля как: модель, год публикации, имя, стоимость - все на Вашу фантазию. Включите обязательно поле Available(в переводе наличие). Оно Вам потом пригодится. Можете сделать его булевым и добавить столбец с именем количество. Это все нам пригодится.
Его смысл:
- Весь доступ к базе данных в системе производится через DAO для инкапсуляции.
- Каждый экземпляр DAO отвечает за один первичный доменный объект или сущность. Если доменный объект имеет независимый цикл жизни, он должен иметь свой собственный DAO.
- DAO отвечает за операции создания, чтения (по первичному ключу), обновления и удаления (то есть, CRUD (create, read, update, delete)) доменного объекта.
- DAO может разрешать запросы, основанные на критерии, отличном от первичного ключа. Я ссылаюсь на такие методы как finder или finders. Метод finder обычно возвращает коллекцию доменных объектов, за которые отвечает DAO.
- DAO не занимается обработкой транзакций, сессий или соединений. Это делается вне DAO для обеспечения гибкости.
Подробнее всегда расскажет гугл.
Мы пока напишем DAO для наших продуктов.
Итак, подумаем что нам вообще нужно. Таблица Product будет иметь 4 поля Id,nameProduct,available+amount+actionForServlet. Она нам будет нужна, чтобы создать на нашем сайте категории. Над последним полем пока не заморачиваемся. Единственное что нам нужно - это получение списка продуктов.
Пишем интерфейс
public interface ProductDAO {
ProductDAO INSTANCE_PRODUCT= new ProductDAOImpl();
List
Реализация нашего интерфейса. Пояснения смотрим в коде
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package edu.shop.model.dao;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.Session;
/**
*
* @author Mikhail Shumenko
*/
public class ProductDAOImpl implements ProductDAO {
@Override
public List
Итак, теперь у нас есть возможность получать данные из БД. Вы можете, используя скриплеты, создать незамысловатый цикл for-each и вывести свою продукцию на вашу страницу index.jsp
Категория | //INSTANCE_PRODUCT что это такое? //В ProductDAO описана такая переменная, отвечает за создание ProductDAOImpl //Ну у нас все будет по-другому, можете особо не запоминать это. //ProductDAO INSTANCE_PRODUCT= new ProductDAOImpl(); <% for (Product product:ProductDAO.INSTANCE_PRODUCT.getProducts()) {%>"><%=product.getName()%> | <%}%>
---|---|
Наличие | <% for (Product product: ProductDAO.INSTANCE_PRODUCT.getProducts()) {%><%=product.getAvailable()%> | <%}%>
Но это на первое время, а вообще так делать плохо. Это нарушает наш паттерн MVC. Как сделать правильно я объясню в следующем уроке, если мне дадут инвайт. Во втором уроке мы займемся Spring, в третьем коснемся паттерна Factory, и углубимся в хибернейт. Для особо нетерпеливых, покажу как нужно удалять из БД, сохранять в БД и удалять полностью все из БД. Ну, а как сделать, чтобы все это взаимодействовало в целом с нашим приложением и подробное рассмотрение оставим на потом.
Также Вам нужен будет файл настройки Hibernate. Создайте в Derby БД shop. Имя и пароль пользователя root и pass соответственно. Если не получится - не расстраивайтесь - я уделю еще этому время.
О том, как заполнять наши БД поговорим позже. Можете заполнить их вручную. Либо дождаться следующего урока.
JSP (Java server pages) — это технология, которая позволяет внедрять Java-код, а также EL (expression language) в статичное содержимое страницы) и позволяющая веб-разработчикам динамически генерировать HTML, XML и другие веб-страницы. JSP является составной частью единой технологии создания бизнес-приложений J2EE.
JSP — может выполняться практически на любом веб сервере, так как эта технология основана на языке программирования Java, который не зависит от платформы. Java server pages поддерживает теги HTML, Javascript, а также собственный набор тегов.
JSP — позволяет отделить динамическую часть страницы от статической. Эта технология предусматривает вставку Java кода в страницу. Мы не будем рассматривать такой вариант использования JSP поскольку эта технология считается устаревшей и несовершенной. Причина проста: разработчики дизайнеры, которые разрабатывают внешний вид страницы не всегда могут быть знакомы с Java и это может вызвать дополнительные трудности при редактировании или поддержке веб приложений.
Вместо вставки Java кода сейчас используется библиотека тегов jstl или Javascript для совсем продвинутых. Мы рассмотрим пример именно с jstl тегами. Это очень удобная библиотека, которая имеет почти весь функционал, который необходим при создании динамических страниц. Если нужно что-то специфическое, то всегда можно написать собственный тег и вставить его содержимое на страницу.
Мы уже частично знакомы с JSP по первым . Основная часть JSP страницы это HTML, в которую вставляются теги с динамическим содержимым.
Пример JSP страницы
Очень необходимым знанием, которым мы будем пользоваться является директива JSP.
Директива JSP — это сообщение, которое страница может послать соответствующему контейнеру с указанием действий. Синтаксис директивы:<% @ атрибут = «значение» %>
Есть три основных типа директив:
Так, как код в страницу мы вставлять не будем, рассмотрим последние две директивы.
Например у нас есть страницы, которые будут иметь одинаковую верхнюю и нижнюю часть. Очень распространенный шаблон, в котором футер и хедер одинаковы для всех страниц. Для того, чтобы не писать Код этих страниц в каждом JSP файле можно вынести их код в отдельный файлы и потом подключить в нужном нам месте с помощью директивы include.
Расположение файлов в проекте:
В коде выше можно проследить использование директивы taglib. С ее помощью мы подключили библиотеку тегов jstl. С помощью этой директивы можно подключить библиотеку собственных тегов: <%@ taglib uri=»/WEB-INF/mylib.tld» prefix=»test» %>.
Заметьте, что важным атрибутом taglib является prefix. Это обязательный к использованию атрибут. С помощью prefix можно вызывать библиотеку в коде. Имя prefix можно выбирать любое. К стати, вот и использование jstl тегов на деле:
< c: forEach items= "${accounts} " var = "account" >
< tr align= "center" >
< td> ${ account. number} td>
< td> ${ account. balance} td>
< td>< c: if test= "${!account.isBlocked}" > ${ statusActive } c: if>
< c: if test= "${account.isBlocked}" > ${ statusBlocked } c: if> td>
< td>< c: if test= "${!account.isBlocked}" >
< a href= "?command=blockaccount&accountId=${account.accountId}" > ${ block } a>
c: if> td>
< td>< a href= "?command=showinfo&accountId=${account.accountId}" > ${ showInfo } a> td>
tr>
c: forEach>
Код выше демонстрирует вывод всех элементов списка. О том, как мы его передали на страницу будет в следующих статьях. Его синтаксис:
Это код сайдбара, который подключался выше. Как видим, здесь используется разветвления, чтобы вывести только ту информацию, которая доступна определенном типу пользователя.
Синтаксис:
a equals b
Лучше всего рассматривать теги jstl при написании реального проекта, так как я не вижу смысла учить и запоминать весь синтаксис для каждого действия. Код выше должен послужить только примером, как это используется. Не нужно ничего заучивать. Когда Вы будете писать код, тогда и обратитесь к данному синтаксису.
К стати, код проекта, с которого был взят этот код, находится тут: https://github.com/caligula95/payment-systemapp
Я выложил проект на heroku: https://payment-systemapp.herokuapp.com/ — тут используется бесплатный аккаунт, так что для первого запроса нужно подождать пару минут, чтобы проект запустился.
Последнее обновление: 02.09.2018
Представляет технологию, которая позволяет создавать динамические веб-страницы. Изначально JSP (вместе с сервлетами) на заре развития Java EE являлись доминирующим подходом к веб-разработке на языке Java. И хотя в настоящее время они уступило свое место другой технологии - JSF, тем не менее JSP продолжают широко использоваться.
По сути Java Server Page или JSP представляет собой html-код с вкраплениями кода Java. В то же время станицы jsp - это не стандартные html-страницы. Когда приходит запрос к определенной странице JSP, то сервер обрабатывает ее, генерирует из нее код html и отправляет его клиенту. В итоге пользователь после обращения к странице JSP видит в своем браузере обычную html-страницу.
Как и обычные статические веб-страницы, файлы JSP необходимо размещать на веб-сервере, к которому обычные пользователи могут обращаться по протоколу http, например, набирая в адресной строке браузера нужный адрес. Однако чтобы сервер мог обрабатывать файлы JSP, он должен использовать движок JSP (), который также называют JSP-контейнером. Есть множество движков JSP, и все они реализуют одну и ту же спецификацию и в целом работают одинаково. Однако тем не менее при переносе кода с одного веб-сервера на другой могут потребоваться небольшие изменения.
В данном случае для работы с JSP мы будем использовать Apache Tomcat, который одновременно является и веб-сервером и контейнером сервлетов и JSP.
Создадим простейшую страницу JSP. Для этого где-нибудь на жестком диске определим файл index.jsp . Все станицы JSP имеют расширение jsp . Откроем этот файл в любом текстовом редакторе и определим в нем следующий код:
<% String header = "Apache Tomcat"; %>
Today <%= new java.util.Date() %>
С помощью тегов <% ... %> мы можем определить код Java на странице JSP. В данном случае мы просто определяем переменную типа String, которая называется header.
Затем идет стандартный код страницы html. Чтобы внедрить код java внутрь html-страницы применяются теги <%= %> - после знака равно указывается выражение Java, результат которого будет выводиться вместо этих тегов. В данном случае, используются две таких вставки. Первая вставка - значение переменной header, которая была определена выше. Вторая вставка - выражение new java.util.Date() , которое возвращает текущую дату.
Для тех, кто знаком с веб-разработкой на PHP, это может напоминать оформление файлов php, которые также содержать код html и код php.
Теперь поместим данный файл на сервер - в данном случае в контейнер Tomcat. Перейдем в Apache Tomcat к папке webapps\ROOT . Удалим из нее все содержимое и поместим нашу страницу index.jsp , которая была создана выше.
Запустим Apache Tomcat (если он не запущен), и обратимся к приложению по адресу http://localhost:xxxx/index.jsp , где xxxx - номер порта, по которому запущен Tomcat:
В итоге Tomcat получит запрос к странице index.jsp, обработает код на java, сгенерирует html-страницу и отправит ее пользователю.
По умолчанию Apache Tomcat настроен таким образом, что все запросы к корню приложения по умолчанию обрабатываются страницей index.jsp, поэтому мы также можем обращаться к ней по адресу