Содержание
Это третья статья из серии про употребление Java в Oracle. Напомню, что цель серии – показать, что средств
обыкновенной
штатной поставки Oracle Enterprise Edition или Standard
Edition хватает,
чтобы строить Java-приложения для Oracle, в том числе для использования в сети
web.
В качестве базового элемента операционной среды построения web-узлов на базе
своей СУБД фирма Oracle, начиная с версии 8.1.6 (и продолжая версией 9), выбрала
web-сервер Apache.
Для эффективного обслуживания большого числа одновременных запросов по internet
в web-сервере Apache имеется поддержка механизма сервлетов (servlets). Она
реализуется средствами так называемого сервера JServ, являющегося расширением
базовой поставки Apache (модулем сервлетов по терминологии, принятой в проекте
Apache), и предназначенного именно для сервлетов на Java. Нынешняя разработка
очередных версий Apache происходит в рамках более общего проекта Jakarta, и
в рамках того же проекта создается сервер поддержки сервлетов Tomcat, предлагаемый
на смену JServ.
В штатной поставке Oracle сервер Apache уже сконфигурирован с JServ. Тем не
менее, установка и того, и другого может быть при желании осуществлена самостоятельно
(см. http://java.apache.org/ и httpd.apache.org).
В примерах ниже значения настроек Apache и JServ соответствуют штатной поставке
Oracle. Эти настройки несколько разнятся в версиях 8.1 и 9. Например, в поставках
8.1 используется HTTP-порт № 80, а в версии 9 – порт № 7778. В примерах ниже
используется вариант порта версии 8.1, который, к тому же, обычно воспринимается
браузерами номером порта по умолчанию.
Имена каталогов в примерах также относятся к версии 8.1 и могут несколько
отличаться от версии 9.
Для дальнейшей работы удобно завести переменные среды окружения ОС:
set APACHE_HOME=%ORACLE_HOME%\Apache\Apache
set JSERV_HOME=%ORACLE_HOME%\Apache\Jserv
Java-сервлет представляет собой Java-программу, хранимую на web-сервере (точнее
– в модуле JServ или Tomcat), кешируемую и исполняемую там же. С точки зрения
Java, сервлет – это объект класса (прямо или опосредованно) javax.servlet.GenericServlet,
удовлетворяющего интерфейсу javax.servlet.Servlet. Сервлет обладает всеми возможностями
объектов Java, например, общения с данными Oracle.
Наборы классов и интерфейсов, удобных для создания сервлетов Java в web, содержатся
в двух пакетах: javax.servlet и javax.servlet.http. Согласно интерфейсу javax.servlet.Servlet
сервлет имеет жизненный цикл, диктуемый следующими методами:
public void init (ServletConfig config) throws ServletException;
Метод, используемый машиной сервлетов единожды для каждого конкретного сервлета
для того, чтобы загрузить его в память (в контейнер) и сделать доступным для
работы.
public void service (ServletRequest request, ServletResponse response)
throws ServletException, IOException;
Метод, которым машина сервлетов передает загруженному в память сервлету на
обработку пришедший запрос (request) и получает от него ответ (response) всякий
раз при обращении к работающему сервлету.
public void destroy();
Метод, используемый машиной сервлетов единожды для каждого конкретного сервлета
для удаления его из памяти, обычно по ненадобности, и освобождения ресурсов
сервера.
Интерфейс javax.servlet.ServletRequest, которому удовлетворяет поступающий
на обработку сервлетом запрос, содержит методы для получения сведений об источнике
поступления запроса и о параметрах, передаваемых запросом.
Интерфейс javax.servlet.ServletResponse, в соответствии с которым сервлет
формирует свой ответ, содержит методы для выдачи результатов и установки характеристик
выдачи.
На практике сервлеты web-сервера удобнее создавать как экземпляры класса javax.servlet.http.HttpServlet,
являющегося наследником GenericServlet,. Среди прочих, методы HttpServlet содержат
следующие:
protected void doGet (HttpServletRequest request,
HttpServletResponse response) throws ServletException,
IOException;
Метод, к которому обращается метод service класса, которому прнадлежит сервлет,
для обработки операции GET, пришедшей по протоколу HTTP.
protected void doPost (HttpServletRequest request,
HttpServletResponse response) throws ServletException,
IOException;
Метод, к которому обращается метод service класса, которому прнадлежит сервлет,
для обработки операции POST, пришедшей по протоколу HTTP.
Подробнее о технике Java Servlet см. на http://java.sun.com/products/servlet/.
Ниже приводится пример файла ,
программирующего Java-сервлет, выдающий в браузер перечень сотрудников из схемы
SCOTT
import java.io.*;
import java.sql.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class StaffByServletTransactional extends HttpServlet {
public void init(ServletConfig config) throws ServletException {
super.init(config);
try { Class.forName("oracle.jdbc.driver.OracleDriver").newInstance();
}
catch (Exception e) { }
}
public void doGet(
HttpServletRequest request, HttpServletResponse
response)
throws IOException, ServletException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<html>");
out.println("<head>");
out.println("<title>Servlet Per Transaction Connection</title>");
out.println("</head>");
out.println("<body>");
out.println("<pre>"); Connection cn = null;
try {
cn = DriverManager.getConnection(
"jdbc:oracle:thin:@localhost:1521:teacher", "scott", "tiger");
}
catch (Exception e) { }
Statement st = null;
ResultSet rs = null;
try {
st = cn.createStatement();
rs = st.executeQuery("SELECT empno, ename FROM emp");
while (rs.next()) {
out.println("Number=" + rs.getString(1) + " " +
"Name=" + rs.getString(2));
}
st.close();
cn.close();
}
catch (Exception e) { }
out.println("</pre>");
out.println("<hr>");
out.println("</body>");
out.println("</html>");
}
public void doPost(
HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
doGet(request, response);
}
} |
Трансляция сервлета:
SET CLASSPATH=%ORACLE_HOME%\lib\servlet.jar;.
javac StaffByServletTransactional.java
Прежде, чем выполнить обращение к сервлету, следует перенести полученный в
результате трансляции сервлета файл MyServletAgent.class в каталог %JSERV_HOME%\servlets.
После этого достаточно в строке источника документа для браузера указать http://localhost/servlet/StaffByServletTransactional (в версии 9 -- http://localhost:7778/servlet/StaffByServletTransactional).
Первое обращение к этому сервлету проинициализирует его и разместит в памяти
в web-сервера, так что последующие обращения окажутся значительно быстрее.
JavaServer Pages (JSP) – другая техника организации динамических web-страниц.
В отличие от Java Servlets, в JSP применяется не генерация HTML-кода из программы,
а вставки в HTML-код JSP-указаний, исполняемых, тем не менее, тоже на сервере.
При первом обращении к JSP-странице JServ автоматически транслирует ее в Java-сервлет
и впоследствии переадресует все запросы к нему.
(Подробнее о технике JavaServer Pages см. на http://java.sun.com/products/jsp/).
Для показа работы JSP-страницы составим файл с названием :
<html>
<head><title>MyJSPDemo JSP demo</title></head>
<body>
< h2>Hello, JSP World</h2>
whith date <%= new java.util.Date().toString() %> now
and User-Agent <%= request.getHeader("User-Agent") %>
< /body>
</html> |
Перенесем созданный файл в каталог %APACHE_HOME%\htdocs\demo.
Обратимся из браузера по адресу http://localhost/demo/MyJSPDemo.jsp (в версии
9 http://localhost:7778/demo/MyJSPDemo.jsp).
Обратим внимание, что в каталоге, обозначенном выше, появился подкаталог _pages\_demo
с файлами:
_MyJSPDemo$__jsp_StaticText.class
_MyJSPDemo.class
_MyJSPDemo.java
В случае JSP не существует единственного способа обращения страницы к базе
данных. Вместо этого имеется несколько возможных вариантов:
- прямое обращение
- обращение с использованием user actions (действий пользователя) в странице
- опосредованное обращение к БД из Bean-компоненты
- опосредованное обращение к БД путем вызова сервлета
Далее рассматриваются примеры обращения по первым двум вариантам.
Ниже приводится пример файла , программирующего JSP-страницу,
выдающую в браузер перечень сотрудников из схемы SCOTT прямым обращением к
базе:
<%@ page import="java.sql.*" %>
<html>
< head><title>Direct JDBC Query JSP</title></head>
< body>
< h3>JSP StaffByJSPDirect result:</h3>
< pre>
< %= StaffByJSPDirect() %>
< /pre>
< hr>
< /body>
< /html>
<%!
private String StaffByJSPDirect() throws SQLException {
Connection cn = null;
StringBuffer sb = new StringBuffer();
try {
cn = DriverManager.getConnection(
"jdbc:oracle:thin:@localhost:1521:teacher", "scott", "tiger");
}
catch (SQLException e) { };
Statement st = null;
ResultSet rs = null;
try {
st = cn.createStatement();
rs = st.executeQuery("SELECT empno, ename FROM emp");
while (rs.next()) {
sb.append("Number=" + rs.getString(1) + " " +
"Name=" + rs.getString(2) + "\n");
};
cn.close();
}
catch (SQLException e) { };
return sb.toString();
}
%> |
Ниже приводится пример файла , программирующего JSP-страницу,
выдающую в браузер перечень сотрудников из схемы SCOTT обращением к базе с
использованием «меток пользователя» (custom tags) из библиотеки в штатной поставке
Oracle (описание библиотеки – в файле %APACHE_HOME%\htdocs\WEB-INF\sqltaglib.tld):
<%@ taglib uri="/WEB-INF/sqltaglib.tld" prefix="jml" %>
<html>
< head>
< title>User Tag Lib JDBC Query JSP</title>
< /head>
< body>
< h3>JSP StaffByJSPTaglib result:</h3>
< jml:dbOpen URL="jdbc:oracle:thin:@localhost:1521:teacher"
user="scott" password="tiger">
<jml:dbQuery>
select * from emp
</jml:dbQuery>
< /jml:dbOpen>
< hr>
< /body>
< /html> |
Для построения web-приложений на основе Java часто используют подход («модель»)
Model-View-Controller (MVC), предложенный фирмой Xerox в 80-х годах для своего
языка Smalltalk-80. Согласно этому подходу приложение представляет собой в
общем случае организованный набор страниц HTML и JSP, а также сервлетов и компонент
JavaBeans и Enterprise JavaBeans (EJB). Задачи, которые решают эти элементы
web-приложения, разделяются на задачи моделирования прикладной области (Model),
представления данных приложения клиенту (View) и управления работой приложения
(Controller):