Лабораторная работа № 3
Цель работы: создание веб-приложения, использующего разработанные ранее классы
Задание к лабораторной работе:
1. Изучить приведенный пример реализации.
2. Выполнить последовательность действий, приведенную в разделе «
Ход работы», для своего варианта разрабатываемой системы.
3. Продемонстрировать работу системы, оформить отчет.
Используем версию NetBeans с опцией Java EE, чтобы можно было создавать JSP – страницы.
Нам также потребуется отдельная инсталляция сервера Apache Tomcat. Можно поставить в виде службы Windows, но лучше в виде консольного кроссплатформенного варианта. Во-первых, проще смотреть ошибки в консоли сервера; во-вторых лучше интегрируется со средой разработки. Среда сама может запускать/останавливать такой сервер.
Ставим второй вариант: из архива apache-tomcat-7.0.12.zip папку apache-tomcat-7.0.12 распаковываем в корень диска. Для работы Apache Tomcat в системе должна быть установлена виртуальная Java -машина (JDK), путь к которой надо задать в переменной среды JAVA_HOME. Проверяем правильность указания переменной:
c:\apache-tomcat-7.0.12\bin>echo %JAVA_HOME%
c:\Java\jdk1.6.0_20
В папке c:\Java\jdk1.6.0_20 уже находится папка bin.
Стартуем сервер: запускаем startup.bat из c:\apache-tomcat-7.0.12\bin, он выводит:
Using CATALINA_BASE: "C:\apache-tomcat-7.0.12"
Using CATALINA_HOME: "C:\apache-tomcat-7.0.12"
Using CATALINA_TMPDIR: "C:\apache-tomcat-7.0.12\temp"
Using JRE_HOME: "c:\Java\jdk1.6.0_20"
Using CLASSPATH: "C:\apache-tomcat-7.0.12\bin\bootstrap.jar;C:\apache-tomc
at-7.0.12\bin\tomcat-juli.jar"
На рисунке 1 показан как сервер запущен в отдельной консоли; на рисунке 2 зашли на адрес http://127.0.0.1:8080; на рисунке 3 – окно авторизаци; на рисунке 4 – вход в Manager App; на рисунке 5 – базовый синтаксис JSP; на рисунке 6 – перезапускаем tomcat, чтобы все настройки вступили в силу, идем по адресу http://127.0.0.1:8080/test1/; на рисунке 7 – создаем структуру каталогов; на рисунке 8 – страница отображает данные из базы, которые вытаскивает метод search класса Organization; на рисунке 9 - Заходим по адресу http://127.0.0.1:8080/test1/org_search.jsp; на рисунк 10 – поиск по части наименования; на рисунке 11 – поиск по части регистрационного номера.
Сервер запускается в отдельной консоли. Такое состояние свидетельствует об успешном запуске:
Рисунок 1 - сервер запускается в отдельной консоли
Как видно из этого лога, сервер стартовал на порту 8080. Задается это в conf\server.xml:
<!-- A "Connector" represents an endpoint by which requests are received
and responses are returned. Documentation at:
Java HTTP Connector: /docs/config/http.html (blocking & non-blocking)
Java AJP Connector: /docs/config/ajp.html
APR (HTTP/AJP) Connector: /docs/apr.html
Define a non-SSL HTTP/1.1 Connector on port 8080
-->
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
Идем браузером на этот адрес:
Рисунок 2 – зашли на адрес http://127.0.0.1:8080
Такая страница свидетельствует о том, что все сервер нормально.
В Apache Tomcat есть встроенное приложение для управления сервером и другими приложениями, т.н. manager application. Доступ к нему можно получить с главной страницы по ссылке “Manager App”. При нажатии всплывает окно авторизации:
Рисунок 3 – окно авторизации
Откуда взять логин и пароль:
Идем в каталог сервера apache-tomcat-7.0.12\webapps\manager\WEB-INF, там есть файл web.xml, это конфигурационный файл для приложения manager. В нем есть запись
<security-constraint>
<web-resource-collection>
<web-resource-name>HTML Manager interface (for humans)</web-resource-name>
<url-pattern>/html/*</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>manager-gui</role-name>
</auth-constraint>
</security-constraint>
указывающая, что доступ к данному ресурсу предоставляется для пользователя с ролью manager-gui.
Теперь в каталоге конфигурации всего сервера apache-tomcat-7.0.12\conf находим файл tomcat-users.xml, в нем как раз задаются пользователи и роли. Раскомментируем xml -код в конце файла и добавим записи о роли
<role rolename=”manager-gui”/> и пользователе <user username=”manager” password=”manager” roles=”manager-gui”/>
<?xml version='1.0' encoding='utf-8'?>
<tomcat-users>
<role rolename="tomcat"/>
<role rolename="role1"/>
<role rolename="manager-gui"/>
<user username="tomcat" password="tomcat" roles="tomcat"/>
<user username="both" password="tomcat" roles="tomcat,role1"/>
<user username="role1" password="tomcat" roles="role1"/>
<user username="manager" password="manager" roles="manager-gui"/>
</tomcat-users>
Теперь с логином manager/manager можно войти в Manager App:
Рисунок 4 – вход в Manager App
В разделе Manager есть ссылка Server Status — детальное описание состояния сервера.
В разделе Applications перечислены веб-приложения, установленные на данном сервере, и есть кнопки для управления:
Start — запустить приложение, для приведенных уже “нажата” и потому не активна;
Stop — остановить приложение. Сам сервер и остальные приложения продолжат работу;
Reload — перезапустить приложение;
Undeploy — удалить приложение;
Expire sessions with idle >= … minutes — считать веб-сессии пользователей истекшими по прошествии стольких-то минут без активности.
Раздел Deploy предназначен для инсталляции приложения из war -файла.
Diagnostics позволяет найти утечки памяти и принудительно запустить сборку мусора в JVM.
Еще одно полезное встроенное приложение — Host Manager, также доступен по ссылке с главной страницы, адрес может быть такой: http://127.0.0.1:8080/manager/html. Также требуется авторизация, разобраться с ней рекомендуется самостоятельно, по аналогии.
Добавим простое приложение (одну JSP страницу) в tomcat без использования IDE и консоли управления:
1. В каталоге установки tomcat apache-tomcat-7.0.12\webapps создаем свою папку, test1.
2. В папке test1 создаем файл index.jsp с таким содержимым:
<html>
<head><title>Test 1</title></head>
<body>
<table border=1>
<% for(int i=0;i<5;i++)
{
%>
<tr><td>record number <%=i%></td></tr>
<%
}
%>
<table>
</body>
</html>
3. Томкат запущен, в браузере идем по адресу http://127.0.0.1:8080/test1 / и видим следующее:
Рисунок 5 – базовый синтаксис JSP
Этот простой пример демонстрирует базовый синтаксис JSP, а также, где находятся пользовательские приложения и как их можно создавать подручными средствами.
Во второй лабораторной соединение с базой устанавливалось в методе main один раз (вызовом DriverManager.getConnection(…)), после запуска приложения, и закрывалось перед его выходом. В среде веб-приложений такой подход к организации соединений к базе не всегда удобен по следующим причинам:
1. Установка соединения с базой — ресурсоемкая операция. Если выполнять ее для каждого http -запроса к веб-странице, то это значительно снизит производительность.
2. Если держать открытое соединение для каждой http -сессии, то при большом количестве пользователей веб-приложения это повлечет существенный расход памяти как на сервере приложений, так и в СУБД.
Эти проблемы решаются за счет использования пула соединений — некоторого количества открытых и готовых к работе соединений, которые динамически выдаются приложению для выполнения транзакций в СУБД. После выполнения транзакции приложение возвращает соединение в пул, но физически оно не закрывается. Это же соединение может быть выдано из пула для другой http -сессии в другой момент времени. В определенный момент времени каждое соединение в пуле может быть свободно или занято только одной http -сессией (обрабатывающимся запросом). Если приложение запрашивает соединение из пула, а в нем все соединения в данный момент заняты, то, в зависимости от конфигурации пула, запрос на получение соединения может быть поставлен в очередь, или количество соединений в пуле может быть увеличено. Такие опции позволяют управлять производительностью приложения при возрастающей нагрузке (увеличении интенсивности запросов при увеличении количества пользователей системы).
Конфигурация пулов описана в документации tomcat, которая в локальной инсталляции доступна по адресу http://127.0.0.1:8080/docs/jndi-datasource-examples-howto.html
Настроить пул можно и через интерфейс управления Host Manager (http://127.0.0.1:8080/host-manager/html). Мы сделаем это по документации вручную. Результат в любом случае должен быть одинаковым.
1. Копируем JDBC -драйвер (файл classes12.jar для Oracle) в каталог apache-tomcat-7.0.12\lib. Если библиотека с драйвером имеет расширение zip, просто переименовываем в jar.
2. В общий файл конфигурации сервера server.xml в секцию <GlobalNamingResources> добавляем:
<Resource name="jdbc/oracle_itc2011" auth="Container"
type="javax.sql.DataSource" driverClassName="oracle.jdbc.OracleDriver"
url="jdbc:oracle:thin:@127.0.0.1:1521:FMS"
username="itc2011" password="itc2011" maxActive="20" maxIdle="10"
maxWait="-1"/>
3. В каталоге тестового приложения webapps\test1 создаем папку конфигурации WEB-INF, в ней создаем файл web.xml со следующим содержимым:
<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd "
version="3.0"
metadata-complete="true">
<display-name>A test application</display-name>
<description>
A scriptable management web application for the Tomcat Web Server;
Manager lets you view, load/unload/etc particular web applications.
</description>
<resource-ref>
<description>Oracle itc2011 Datasource</description>
<res-ref-name>jdbc/oracle_itc2011</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
</web-app>
Этот файл скопирован из apache-tomcat-7.0.12\webapps\manager\WEB-INF\web.xml и в нем удалено все лишнее.
4. Рядом с WEB-INF создаем каталог test1\META-INF, там создаем файл context.xml со ссылкой на глобальный пул:
<?xml version="1.0" encoding="UTF-8"?>
<Context path="/test1" docBase="test1" debug="1" reloadable="true">
<ResourceLink global="jdbc/oracle_itc2011" name="jdbc/oracle_itc2011" type="javax.sql.DataSource"/>
</Context>
Возможно, одно из вышестоящих действий можно исключить.
5. В тестовую страницу index.jsp формируем следующим образом, проверим работу простого запроса:
<%@page import="javax.naming.*, javax.sql.*, java.sql.*" contentType="text/html; charset=Cp1251"%>
<html>
<head><title>Test 1</title></head>
<body>
<table border=1>
<%
//получаем JNDI -контекст
Context initContext = new InitialContext();
Context envContext = (Context)initContext.lookup("java:/comp/env");
//из контекста получаем пул соединений
DataSource ds = (DataSource)envContext.lookup("jdbc/oracle_itc2011");
//а из пула - соединение
Connection conn = ds.getConnection();
//создаем запрос
Statement stmt=conn.createStatement();
//выполняем его
ResultSet rs=stmt.executeQuery("select organization_id,name from organization order by organization_id");
//выводим результат
while(rs.next())
{
%>
<tr>
<td><%=rs.getInt("ORGANIZATION_ID")%></td>
<td><%=rs.getString("NAME")%></td>
</tr>
<%
}
//закрываем объекты - освобождаем ресурсы
stmt.close();
rs.close();
//а этот вызов фактически не закрывает соединение, а возвращает его в пул
conn.close();
%>
</table>
</body>
</html>
6. Перезапускаем tomcat, чтобы все настройки вступили в силу, идем по адресу http://127.0.0.1:8080/test1/, получаем результат:
Рисунок 6 – перезапускаем tomcat, чтобы все настройки вступили в силу, идем по адресу http://127.0.0.1:8080/test1/
Подключения классов к JSP -страницам
Описано подключение классов, созданные во второй лабораторной к JSP -странице, простым способом, без настройки подключения среды разработки к серверу Tomcat.
1. В папке WEB-INF нашего приложения создаем папку classes.
2. В нее копируем скомпилированные классы от второй лабораторной. Если классы объявлены в пакете (в примере — org_po), то создаем структуру каталогов, в соответствии с названием пакета:
Рисунок 7 – создаем структуру каталогов
3. Создаем новую страницу org_search.jsp в каталоге веб-приложения test1. В нее включим модифицированный код, который раньше использовался во второй лабораторной работе в Main.main(). Полный текст org_search.jsp:
<%@page import="javax.naming.*, javax.sql.*, java.sql.*, org_po.*" contentType="text/html; charset=Cp1251"%>
<jsp:useBean class="org_po.Organization" id="org" scope="session" />
<html>
<head><title>Test 1</title></head>
<body>
<table border=1>
<%
//получаем JNDI -контекст
Context initContext = new InitialContext();
Context envContext = (Context)initContext.lookup("java:/comp/env");
//из контекста получаем пул соединений
DataSource ds = (DataSource)envContext.lookup("jdbc/oracle_itc2011");
//а из пула - соединение
Connection conn = ds.getConnection();
// выполняем поиск организаций по параметрам (значение null условия не создают)
Organization[] orgs=org.search(conn, null, null);
out.println(orgs.length+" орг. найдено");
// выводим в цикле найденные организации, название и рег. номер
for(int i=0;i<orgs.length;i++)
{
System.out.println(orgs[i].name+" "+orgs[i].registration_num);
%>
<tr>
<td><%=orgs[i].name%></td>
<td><%=orgs[i].registration_num%></td>
</tr>
<%
}
//а этот вызов фактически не закрывает соединение, а возвращает его в пул
conn.close();
%>
</table>
</body>
</html
4. Стартуем томкат, идем по адресу http://127.0.0.1:8080/test1/org_search. jsp, получаем результат:
Рисунок 8 – страница отображает данные из базы, которые вытаскивает метод search класса Organization.
Дополняем JSP -страницы
Дополняем страницу org_search.jsp полями для ввода поисковых параметров. Исходный код с комментариями приведен ниже:
<%@page import="javax.naming.*, javax.sql.*, java.sql.*, org_po.*" contentType="text/html; charset=Cp1251"%>
<jsp:useBean class="org_po.Organization" id="org" scope="session" />
<html>
<head><title>Поиск организаций</title>
<link rel=stylesheet href="sample.css"/>
</head>
<body>
<%--
Форма ввода поисковых параметров, имеет 2 поля input типа text,
названия полей: org_name и org_reg_num. Эти же названия будут и у параметров запроса.
У тега form не указан атрибут action, в этом случае запрос будет формироваться к текущей странице.
--%>
<form method="get">
Наименование <input type=text name="org_name" value="<%=request.getParameter("org_name")%>"/>
ОГРН <input type=text name="org_reg_num" value="<%=request.getParameter("org_reg_num")%>"/>
<input type=submit value=" Искать ">
</form>
<table>
<%
//получаем JNDI -контекст
Context initContext = new InitialContext();
Context envContext = (Context)initContext.lookup("java:/comp/env");
//из контекста получаем пул соединений
DataSource ds = (DataSource)envContext.lookup("jdbc/oracle_itc2011");
//а из пула - соединение
Connection conn = ds.getConnection();
// Выполняем поиск организаций по параметрам,
// которые берем из http- запроса request вызовом метода getParameter.
// Имена параметров в запросе соответствуют их именам на форме.
Organization [] orgs=org.search(conn, request.getParameter("org_name"), request.getParameter("org_reg_num"));
%>
<tr>
<th colspan="3"><%=" Надейно организаций: "+orgs.length%></th>
</tr>
<tr class="yellow">
<td> Наимнование </td>
<td> ОГРН </td>
<td> ИНН </td>
</tr>
<%
// выводим в цикле найденные организации, название и рег. номер
for(int i=0;i<orgs.length;i++)
{
System.out.println(orgs[i].name+" "+orgs[i].registration_num);
%>
<tr>
<td><%=orgs[i].name%></td>
<td><%=orgs[i].registration_num%></td>
<td><%=orgs[i].vat_num%></td>
</tr>
<%
}
//а этот вызов фактически не закрывает соединение, а возвращает его в пул
conn.close();
%>
</table>
</body>
</html>
Чтобы корректно обрабатывались значения параметров в кириллице, открываем для редактирования apache-tomcat-7.0.12\conf\server.xml, в элемент Connector добавляем свойство URIEncoding со значением Cp1251:
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443"
URIEncoding="Cp1251"
/>
Заходим по адресу http://127.0.0.1:8080/test1/org_search.jsp:
Рисунок 9 - Заходим по адресу http://127.0.0.1:8080/test1/org_search.jsp
Проверяем поиск по части наименования:
Рисунок 10 – поиск по части наименования
Проверяем поиск по части регистрационного номера (ОГРН):
Рисунок 11 – поиск по части регистрационного номера
Вывод: научились создавать веб-приложения, использующего разработанные ранее классы; изучили приведенный пример реализации; выполнили последовательность действий, приведенную в разделе «Ход работы», для своего варианта разрабатываемой системы; продемонстрировали работу системы, оформили отчет.
Выполнил | Иванова Ю.В. | |
Проверил | Алексанян Г.К. |