Страница InternetBeans среды JBuilder содержит компоненты, позволяющие заменять на этапе выполнения сервлета "пустые" данные на данные, предоставляемые модулем данных.
Компонент IxPageProducer предназначен для связывания HTML-файла с используемым модулем данных.
Компонент IxControl позволяет связать элемент управления из IxControl.
Компонент IxTable позволяет отображать в HTML-документах динамически генерируемые таблицы набора данных.
Процесс разработки сервлета, выполняющего публикацию данных на HTML-страницы с применением компонентов страницы InternetBeans, состоит из следующих этапов:
File|New и выбирая на вкладке Web пиктограмму Servlet ). Для возможности обработки GET и POST HTTP-запросов в мастере Servlet Wizard на панели Implement methods следует установить флажки для методов doGet и doPost.IxPageProducer и IxControl, реализующих связь формируемого HTML-документа с модулем данных и элемента управления - с объектом сервлета.doPost и doGet, формирующих возвращаемую web-сервером HTML-страницу.Модуль данных - это Java-класс, реализующий интерфейс DataModule. Модуль данных можно рассматривать как централизованный контейнер для всех компонентов доступа к данным. Модуль данных предоставляет методы, позволяющие работать с наборами данных.
Для создания модуля данных выполните следующие действия:
File|New и на вкладке General выберите пиктограмму Data Module.Class name будет отображаться имя создаваемого модуля данных (по умолчанию - DataModule1).
При включенном флажке Invoke Data Modeler после завершения данного диалога будет предложен диалог Data Modeler для определения SQL-запросов к подключаемой посредством JDBC базе данных.Database|Add Connection URL или команду меню Database|Open Connection URL.Driver, выбрав это значение из предлагаемого списка
(например, (рис 14.1) Диалог Data Modeler - страница Columns
File|Save, а затем завершить диалог Data Modeler, выполнив команду меню File|Exit.Диалог Data Modeler позволяет определить соединение с источником данных и автоматически сформировать SQL-оператор, выполняющий запрос данных.
Для формирования запроса на панели Available columns следует выбрать имена столбцов и скопировать их на панель Selected columns. Страница Where диалога Data Modeler позволяет сформировать условие, а страницы Order By и Group By служат для задания порядка сортировки и группирования данных, получаемых в результирующем наборе.
Для того чтобы просмотреть результат сформированного запроса, следует перейти на страницу Test диалога Data Modeler и щелкнуть по кнопке Execute Query.
При создании модуля данных JBuilder автоматически формирует код класса модуля данных, реализующего интерфейс DataModule.
Например:
package myservlet_database1;
import java.awt.*;
import java.awt.event.*;
import com.borland.dx.dataset.*;
import com.borland.dx.sql.dataset.*;
public class DataModule1 implements DataModule {
static private DataModule1 myDM;
private Database database1 = new Database();
private QueryDataSet customer = new QueryDataSet();
// Переменная customer будет применяться как ссылка
// на используемый набор данных
public static DataModule1 getDataModule() {
// Статической метод getDataModule используется для
// создания объекта типа DataModule1
if (myDM == null) { myDM = new DataModule1(); }
return myDM;
}
public DataModule1() { // конструктор
try { jbInit(); }
catch(Exception e) { e.printStackTrace(); }
}
private void jbInit() throws Exception {
customer.setQuery(
new com.borland.dx.sql.dataset.QueryDescriptor(
database1, "SELECT CUSTOMER.CUST_NO, CUSTOMER.CUSTOMER,
CUSTOMER.PHONE_NO, CUSTOMER.CITY " +
"FROM CUSTOMER", null, true, Load.ALL));
// Метод setQuery устанавливает значение свойства query
// компонента типа QueryDataSet
database1.setConnection(
new com.borland.dx.sql.dataset.ConnectionDescriptor
"jdbc:borland:dslocal:C:\\JBuilder8\\samples\\JDataStore\\
datastores\\employee.jds", "Sample", "", false,
"com.borland.datastore.jdbc.DataStoreDriver"));
}
// Метод setConnection определяет соединение с источником данных
public Database getDatabase1() { return database1; }
public QueryDataSet getCustomer() { return customer; }
}
Для создания HTML-файла, отображающего форму, используемую при публикации данных, выполните следующие действия:
<html> <body><h1> Таблица Customer</h1> <table id="tbl1" align="CENTER" border="1" > <tr><th>Поле1</th></tr> <tr><td>-</td></tr></table> <form method="POST"> Pole1:</p> <input type="text" id="P1" name="Col1" size="30"> <input type="submit" name="submit" value="Submit"> </p></form> </body></html>
Для того чтобы определить используемый модуль данных, следует:
Wizards|Use DataModule.Опция Create New Instance of Data Module диалога Use DataModule Wizard используется в том случае, если предполагается использовать модуль данных для одной формы.
Опция Share (Static) Instance of DataModule позволяет использовать модуль данных несколькими формами приложения, разделяя один экземпляр модуля.
Опция позволяет использовать для одной формы несколько модулей данных, выполняя соответствующую настройку в окне дизайнера.
В результате добавления модуля данных в файле Servlet1 появится объявление переменной dataModule11 типа DataModule1 (например: DataModule1 dataModule11; ), а в метод jbInit будет добавлен вызов метода getDataModule, используемого для создания объекта модуля данных (например, dataModule11 = myservlet_database1.DataModule1.getDataModule(); ).
Для реализации доступа к данным можно использовать компоненты страницы InternetBeans палитры компонентов.
На вкладке Design окна редактора следует добавить в окно структуры компонент IxPageProducer со страницы InternetBeans палитры компонентов.
Объект ixPageProducer1 будет помещен в секцию Other окна структуры (рис. 14.2).
(рис 14.2) Компонент IxPageProducer страницы InternetBeans
При этом в код модуля добавляется строка:
IxPageProducer ixPageProducer1 = new IxPageProducer();
Для определения связи с модулем данных установите значения следующих свойств объекта ixPageProducer1:
dataModule должно указывать используемый модуль данных (например, DataModule11 );htmlFile должно определять имя HTML-файла, содержащего шаблон.Обратите внимание, что свойство rootPath автоматически будет установлено равным полному пути к указанному имени HTML-файла.
Одновременно с этим в код модуля будет добавлен вызов метода ixPageProducer1.setHtmlFile("C:\\ File1.html");.
Компонент IxControl позволяет устанавливать связь между
На вкладке Design окна редактора следует добавить в окно структуры компонент IxControl со страницы InternetBeans палитры компонентов.
Объект ixControl1 будет помещен в секцию Other окна структуры.
Одновременно с этим в код модуля добавляется следующая строка:
IxControl ixControl1 = new IxControl();
Для связывания элемента управления с полем набора данных установите значения следующих свойств объекта ixControl1:
dataset должно указывать используемый набор данных (например, customer );columnName должно определять имя поля набора данных;pageProducer должно указывать компонент типа IxPageProducer (например, ixPageProducer1 );controlName должно определять элемент управления формы и устанавливается равным атрибуту name тега input.Для каждого поля набора данных следует добавить свой компонент типа IxControl.
Компонент IxControl может выполнять обработку событий. Так, если данный компонент связан с командной кнопкой Submit, то для обработки события следует перейти на вкладку Events и создать обработчик события submitPerformed.
Например:
ixControl2.addSubmitListener(new
com.borland.internetbeans.SubmitListener() {
public void submitPerformed(SubmitEvent e) {
ixControl2_submitPerformed(e);
}
});
:
void ixControl2_submitPerformed(SubmitEvent e) {
}
Вставьте в тело метода обработчика события submitPerformed следующий код:
// Запрос текущего модуля данных:
DataModule1 dm = (DataModule1) ixPageProducer1.getSessionDataModule(e.getSession());
// передача и сохранение данных, введенных пользователем,
// в источнике данных, определенным модулем данных:
dm.getCustomer().post();
dm.getCustomer().saveChanges();
// Метод getCustomer - это автоматически сформированный метод модуля
//данных DataModule1.java, возвращающий объект типа QueryDataSet
Методы post и saveChanges класса QueryDataSet используются для передачи и сохранения изменений в базе данных.
Компонент IxTable определяет динамически генерируемый набор данных.
Для определения набора данных установите значения следующих свойств объекта IxTable:
pageProducer должно указывать объект типа IxPageProducer ;dataset должно определять набор данных;elementId определяет таблицу HTML-файла и устанавливается равным атрибуту id тега table.Методы doPost и doGet кода сервлета используются для обработки HTTP-запроса и формирования возвращаемой HTML-страницы.
При использовании компонента IxPageProducer в тело метода doGet следует вставить только одну строку:
ixPageProducer1.servletGet(this, request, response);
Метод servletGet класса IxPageProducer выполняет следующие начальные действия по обработке GET HTTP-запроса:
HttpSession ;При использовании компонента IxPageProducer в тело метода doPost могут быть вставлены следующие строки:
// Получение объекта модуля данных:
DataModule1 dm = (DataModule1)
ixPageProducer1.getSessionDataModule(request.getSession());
ixPageProducer1.servletPost(this, request, response);
// Отображение данных, переданных из формы
doGet(request, response);
Метод doPost в данном примере используется для обработки параметров запроса. Для динамического формирования HTML-документа вызывается метод doGet.
Метод servletPost класса IxPageProducer выполняет начальные действия по обработке POST HTTP-запроса и, если была нажата кнопка submit, то вызывает обработчик события submitPerformed.
В состав JBuilder Enterprise входит сервер IAS (версия сервера зависит от версии среды JBuilder), по умолчанию инсталлируемый в каталог \Inprise\AppServer.
Данный WEB-сервер содержит в каталоге Inprise\AppServer\examples\beans\inpriseexamples\beans файлы JDBCBean.java и HttpJDBCBean.java, которые можно использовать для упрощения процесса публикации данных на JSP-страницах. Файл JDBCBean.java представляет собой бин, содержащий свойства, определяющие подключение к базе данных, и выполняемый SQL-оператор. Файл HttpJDBCBean.java применяется для определения параметров, используемых бином JDBCBean.
Для того, чтобы выполнить публикацию данных на JSP-странице с использованием существующих файлов с классами бинов, следует:
JavaBean, выполнив команду меню File|New, а затем на вкладке New указав пиктограмму JavaBean.ClassName ввести имя создаваемого бина (например, JDBCBean).java.lang.Object.package, указав имя текущего пакета проекта.Перейти на вкладку Bean окна содержания и в редакторе бинов перейти на вкладку Properties.
Эта вкладка содержит следующие свойства бина, позволяющие выполнить SQL-запрос:
classname - имя используемого JDBC-драйвера;
url - расположение источника данных;
username - имя пользователя, подключаемого к базе данных;
password - пароль пользователя;
query - выполняемый SQL-оператор.
Для каждого из перечисленных свойств существует get-метод и set-метод.
Свойства cols и rows (число столбцов и строк в результирующем наборе) используются как простые переменные только внутри бина. Для доступа к их значениям служат свойства columnCount и , имеющие get-методы.
Свойство result используется для формирования отображаемого результата.
Создать второй компонент JavaBean и аналогичным образом скопировать в него файл HttpJDBCBean.java.
Класс HttpJDBCBean наследует классу JDBCBean.
Бин HttpJDBCBean использует свой метод processRequest для обработки запроса. Этот метод должен быть непосредственно вызван из JSP-файла для определения значений всех свойств бина JDBCBean.
JDBCBean и HttpJDBCBean.В файле JDBCBean.java выполнение SQL-запроса осуществляется методом go на основе значений, установленных для свойств данного бина. Так, этот метод реализует следующие основные действия:
Class.forName(classname);
url:Connection con=DriverManager.getConnection(url,username,password);
Statement:Statement stmt = con.createStatement();
query:ResultSet rs = stmt.executeQuery(query);
cols, rows и result метаданные текущего запроса:ResultSetMetaData rsmd = rs.getMetaData(); cols = rsmd.getColumnCount(); rows = 0;
В файле HttpJDBCBean.java. метод processRequest выполняет присвоение значений всем свойствам бина JDBCBean, получая эти значения из параметров запроса.
Метод processRequest определяет значения параметров запроса через объект request типа HttpServletRequest:
if ((_p = request.getParameter("classname")) != null) {
classname = _p;
}
Так, если параметр classname определен, то значение одноименного свойства устанавливается равным его значению.
Если все необходимые параметры заданы, то вызывается метод go бина JDBCBean: this.go();
JSP-директивы используются для указания процессору JSP, каким образом следует выполнять преобразование JSP-файла в сервлет, какие файлы следует включить в состав JSP-документа, где находится библиотека дескрипторов.
JSP-директива указывается между символами <%@ и %>.
JSP-директива page позволяет указать, какие файлы следует подключать, и определить некоторую информацию об JSP-файле.
Директива page имеет ряд атрибутов, включая следующие:
contentType - определяет используемый набор символов и MIME-тип ответа ( contentType="text/html; charset=windows-1251" );import - определяет список импортируемых классов и пакетов. Директива page с атрибутом import может быть вставлена в JSP-файл несколько раз;session - значение true данного атрибута указывает, что при выполнении JSP-файла осуществляется поддержка сеанса;info - данные о JSP-файле, которые доступны посредством вызова Servlet .getServletInfo().Так, автоматически формируемая при создании JSP-файла строка
<%@ page contentType="text/html; charset=windows-1251" %>
использует JSP-директиву page для определения типа возвращаемого документа и типа кодировки.
Для того чтобы создать новый JSP-файл, использующий рассмотренный выше бин, выполните следующие действия:
File|New, а затем на вкладке Web выбрав пиктограмму JavaServer Page.В окне редактора после тега <body> введите следующий код:
<jsp:useBean id="jdbc_bean" scope="application" class="myjspjdbc1.HttpJDBCBean" />
JSP-действие jsp:useBean создает объект типа HttpJDBCBean с идентификатором jdbc_bean
Атрибут class определяет класс создаваемого объекта, квалифицированный именем пакета.
<%@ page import = "myjspjdbc1.*" session="false" %>
processRequest класса HttpJDBCBean:<% jdbc_bean.processRequest(request, response); %>В качестве параметров метода указываются предопределенные переменные request и response, используемые для доступа к параметрам запроса и к формированию ответа.
<p><center><font size=2><b>JSP</b></font></center></p> <p >Доступ к базе данных через JDBC</p><hr></p>Атрибут
size тега font определяет размер шрифта, а тег hr используется для отображения горизонтальной линии.FORM для создания формы, в которую будут помещаться результаты SQL-запроса. Например, введите следующий код:<FORM action=Jsp1.jsp method=post> </FORM>При обработке формы будет использоваться этот же файл Jsp1.jsp.
<TABLE>, разместите в форме таблицу, первый столбец которой будет содержать имя запрашиваемого параметра, а второй столбец - текстовое поле, предназначаемое для ввода значения. Каждое текстовое поле создаваемой таблицы будет соответствовать свойству бина JDBCBean.Например:
<table>
<tr> <td> JDBC-драйвер:</td>
<td><input type="text" name="classname" value="
<%= jdbc_bean.getClassname() %>" size="40"></td>
<td></td> </tr>
<!- JSP-выражение <%= jdbc_bean.getClassname() %>" формирует начальное значение текстового поля, вызывая метод getClassname для определения значения свойства classname объекта с идентификатором jdbc_bean. ->
<tr> <td></td> <td><i>sun.jdbc.odbc.JdbcOdbcDriver</i></td> </tr>
<! - Класс sun.jdbc.odbc.JdbcOdbcDriver реализует JDBC-ODBC драйвер для доступа к источнику данных. Загрузка драйвера выполняется на ПК, на котором запущен Web-сервер.-->
<tr>
<td>JDBC URL-адрес источника данных:</td>
<td><input type="text" name="url" value="
<%= jdbc_bean.getUrl() %>" size="40"></td> </tr>
<tr> <td></td>>
<td><i>jdbc:odbc:MyDB</i></td> </tr>
<tr>
<td>Имя пользователя:</td>
<td><input type="text" name="username" value="
<%= jdbc_bean.getUsername() %>" size="25"></td>
</tr>
<tr>
<td>Пароль:</td>
<td><input type="text" name="password" value="
<%= jdbc_bean.getPassword() %>" size="25"></td>
</tr>
<tr>
<td>Выполняемый SQL-оператор:</td>
<td><textarea cols=35 rows=3 name="query" wrap="soft">
<%= jdbc_bean.getQuery() %></textarea></td>
<!-- Тег textarea используется для создания текстовой области. Атрибуты cols и rows определяют размер создаваемой области. -->
</tr></table>
Тег input с атрибутом type="text" определяет текстовое поле. Атрибут name тега input определяет имя параметра, передаваемого JSP-файлу при обработки формы. Формируемый POST-запрос будет содержать список параметров, указываемых атрибутами name, со значениями, указываемыми атрибутами value.
Например:
<input type="submit" name="submit" value="Выполнить SQL-оператор">
В результате выполненных действий WEB-сервер получит POST-запрос, который будет обработан указанным в теге FORM JSP-файлом. При этом как результат выполнения SQL-оператора будет создан результирующий набор. Далее JSP-файл, используя методы бина, может получить доступ к сформированной информации.
Для того чтобы отобразить на формируемой HTML-странице данные результирующего набора, выполните следующие действия:
Определите число столбцов и выведите строку заголовка таблицы, в которой будет отображаться результирующий набор.
Например:
<% if (jdbc_bean.getColumnCount() != 0){ %><% -- JSP-скриплет --%>
<table cellspacing="0" cellpadding="5" border="0" BGCOLOR=#EDECE5>
<% for (int i=0; i<jdbc_bean.getColumnCount(); i++){
String str0 = jdbc_bean.getColumnLabels(i);
%>
<!-- Метод getColumnLabels бина JDBCBean возвращает заголовок столбца с указанным индексом --><th><%= str0 %></th> <% } %> <% } %>
Запишите JSP-скриплет, формирующий строки результирующего набора в формате HTML.
Например:
<% for (int row=1; row<jdbc_bean.getRowCount(); row++) {%>
<tr></tr>
<% for (int col=0; col<jdbc_bean.getColumnCount(); col++) {
String str1 = jdbc_bean.getCell(col, row);
%>
<td ><%= str1 %></td>
<% } %>
<% } %>
</table>
Приведенный выше JSP-скриплет использует метод getRowCount бина JDBCBean для выполнения цикла по количеству строк, а метод getColumnCount - для выполнения цикла по количеству столбцов. Метод getCell бина JDBCBean возвращает массив строк, содержащий значения всех полей одной записи результирующего набора.
Перед выполнением JSP-файла следует откомпилировать классы используемых бинов.
В JBuilder для компиляции данных классов в проект следует добавить библиотеку Project|Project Properties и на вкладке Paths выберите страницу Required Libraries. Далее для добавления новой библиотеки щелкните мышью на кнопке Add и в секции Project выберите библиотеку
Добавленная библиотека будет отображена в списке библиотек на вкладке Required Libraries.
Для выполнения JSP-файла на Web-сервере Tomcat выделите в окне проекта имя JSP-файла и выполните для него команду контекстного меню Web Run.
После введения значений в отображаемый на вкладке Web View окна содержания результат выполнения JSP-файла, web-сервер формирует HTML-страницу (рис. 14.3), содержащую результат выполнения JSP-скриптов.
(рис 14.3) Результат выполнения web-сервером JSP-файла
Далее приводится код используемых классов ( JDBCBean и HttpJDBCBean ):
// Код файла JDBCBean.java:
package myjspjdbc1;
import java.io.*;
import java.util.*;
import java.sql.*;
public class JDBCBean {
String classname ; // JDBC-драйвер
String url ;
String username ;
String password ;
String query ; // SQL-оператор.
int rows, cols; // Число строк и столбцов результирующего набора
Vector result;
public void setClassname(String classname) {
this.classname = classname; }
public String getClassname() { return classname; }
public void setUrl(String url) {
this.url = url;
}
public String getUrl(){ return url; }
public void setUsername(String username) {
this.username = username; }
public String getUsername() { return username; }
public void setPassword(String password) {
this.password = password; }
public String getPassword() { return password; }
public void setQuery(String query) { this.query = query; }
public String getQuery() { return query; }
protected void go() // Подключение к БД и выполнение запроса
throws ClassNotFoundException, SQLException
{
// Загрузка JDBC-драйвера
Class.forName(classname);
// Создание соединения с базой данных
Connection con = DriverManager.getConnection(url,
username,
password);
// Создание и выполнение запроса
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery(query);
ResultSetMetaData rsmd = rs.getMetaData();
cols = rsmd.getColumnCount();
rows = 0;
result = new Vector();
String s[] = new String[cols];
for (int i=1; i<=cols; i++) {
s[i-1] = rsmd.getColumnLabel(i) ;
}
result.addElement(s);
rows ++;
// Извлечение данных
while (rs.next()) {
s = new String[cols];
for (int i=1; i<=cols; i++) {
s[i-1] = helper(rs, rsmd.getColumnType(i), i);
}
result.addElement(s);
rows ++;
}
}
public static void main (String[] args)
{
JDBCBean jdbcBean = new JDBCBean();
String classname = "com.imaginary.sql.msql.MsqlDriver";
//String url = "jdbc:msql://gaby.eng:4333/demo";
String url = "jdbc:msql://ridgetop.eng:1114/test";
String username = "lfu";
String password = "password";
//String query = "select * from details";
String query = "select * from table1";
jdbcBean.setClassname(classname);
jdbcBean.setUrl(url);
jdbcBean.setUsername(username);
jdbcBean.setPassword(password);
jdbcBean.setQuery(query);
try {
jdbcBean.go();
System.out.println("Seems okay");
} catch (Exception ex) {
ex.printStackTrace();
}
}
public int getColumnCount() { return cols; }
public int getRowCount() { return rows; }
public String getColumnLabels(int col) {
String[] s = (String[])result.firstElement();
return s[col];
}
public String getCell(int col, int row) {
String[] s = (String[])result.elementAt(row);
return s[col];
}
protected String helper (ResultSet rs, int dataType, int col)
throws SQLException
{ String retVal = null; Integer intObj;
// Запрос данных в зависимости от их типа
switch(dataType) {
case Types.DATE:
java.sql.Date date = rs.getDate(col);
retVal = date.toString();
break;
case Types.TIME:
java.sql.Time time = rs.getTime(col);
retVal = time.toString();
break;
case Types.TIMESTAMP:
java.sql.Timestamp timestamp = rs.getTimestamp(col);
retVal = timestamp.toString();
break;
case Types.CHAR:
case Types.VARCHAR:
case Types.LONGVARCHAR:
retVal = rs.getString(col);
break;
case Types.NUMERIC:
case Types.DECIMAL:
java.math.BigDecimal numeric = rs.getBigDecimal(col, 10);
retVal = numeric.toString();
break;
case Types.BIT:
boolean bit = rs.getBoolean(col);
Boolean boolObj = new Boolean(bit);
retVal = boolObj.toString();
break;
case Types.TINYINT:
byte tinyint = rs.getByte(col);
intObj = new Integer(tinyint);
retVal = intObj.toString();
break;
case Types.SMALLINT:
short smallint = rs.getShort(col);
intObj = new Integer(smallint);
retVal = intObj.toString();
break;
case Types.INTEGER:
int integer = rs.getInt(col);
intObj = new Integer(integer);
retVal = intObj.toString();
break;
case Types.BIGINT:
long bigint = rs.getLong(col);
Long longObj = new Long(bigint);
retVal = longObj.toString();
break;
case Types.REAL:
float real = rs.getFloat(col);
Float floatObj = new Float(real);
retVal = floatObj.toString();
break;
case Types.FLOAT:
case Types.DOUBLE:
double longreal = rs.getDouble(col);
Double doubleObj = new Double(longreal);
retVal = doubleObj.toString();
break;
case Types.BINARY:
case Types.VARBINARY:
case Types.LONGVARBINARY:
byte[] binary = rs.getBytes(col);
retVal = new String(binary);
break;
}
return retVal;
}
}
// Код файла HttpJDBCBean.java:
package myjspjdbc1;
import java.io.*;
import java.util.*;
import javax.servlet.http.*;
import java.sql.*;
public class HttpJDBCBean extends JDBCBean {
public void processRequest(HttpServletRequest request,
HttpServletResponse response)
throws IOException
{
// Получение значений параметров, если они заданы
String _p ;
if ((_p = request.getParameter("classname")) != null) {
classname = _p;
}
if ((_p = request.getParameter("url")) != null) {
url = _p;
}
if ((_p = request.getParameter("username")) != null) {
username = _p;
}
if ((_p = request.getParameter("password")) != null) {
password = _p;
}
if ((_p = request.getParameter("query")) != null) {
query = _p;
}
// Если параметры не заданы, то отображать только форму
boolean form_only = false;
if (classname == "" || classname == null) form_only = true;
if (url == "" || url == null) form_only = true;
if (username == null) form_only = true;
if (password == null) form_only = true;
if (query == null) form_only = true;
if (form_only) {
return;
}
try {
this.go(); // Вызов метода, выполняющего запрос
} catch (ClassNotFoundException ex) {
PrintWriter writer = response.getWriter(); // Поток вывода
writer.println("class " + classname + " not found.");
} catch (SQLException ex) {
PrintWriter writer = response.getWriter();
writer.println("Message: " + ex.getMessage());
writer.println("Error code: " + ex.getErrorCode());
ex.printStackTrace(writer);
} catch (Exception ex) {
PrintWriter writer = response.getWriter();
ex.printStackTrace(writer);
}
} }
Среда Delphi позволяет создавать приложения, выполняемые на web-сервере, с целью формирования HTML-страницы, публикующей данные их базы данных. Это могут быть приложения следующих типов:
web-браузер по указанному URL-адресу запрашивает данные от WEB-сервера. При выполнении запроса устанавливается TCP/IP соединение с сервером, и данные передаются в формате HTML. После завершения передачи данных TCP/IP соединение разрывается.
При этом передаваемая HTML-страница может быть как HTML-файлом, так и результатом выполнения на web-сервере некоторого приложения.
web-браузер посылает в качестве запроса URL-адрес серверного приложения, а Web-сервер запускает это приложение и передает ему параметры запроса. Сформированная в результате выполнения серверного приложения HTML-страница возвращается WEB-браузеру web-сервером.
Для того, чтобы создать серверное приложение (например CGI), следует:
File|New|Other, вкладка New, пиктограмма Web В результате будет создан проект, содержащий главный файл приложения и модуль Unit1, имеющий следующий код:
{Модуль Unit1.pas}
unit Unit1;
interface
uses SysUtils, Classes, HTTPApp;
type
TWebModule1 = class(TWebModule)
private { Private declarations }
public { Public declarations }
end;
var
WebModule1: TWebModule1;
implementation
{$R *.DFM}
end.
Для того чтобы добавить код, формирующий HTML-страницу, следует:
TWebModule1 выполнить двойной щелчок мышью на свойстве Action.Editing WebModule1.Actions создать новый элемент (кнопка Add New ).WebActionItem1 обработчик события OnAction. При этом автоматически будет сформирован следующий код:procedure TWebModule1.WebModule1WebActionItem1Action(
Sender: TObject;
Request: TWebRequest; // Объект запроса -
// позволяет получать данные о выполняемом запросе
Response: TWebResponse; // Объект ответа -
// используется для формирования ответа
// (HTML-страницы
var Handled: Boolean);
begin
end;
Сформировать в созданном обработчике события код, формирующий текст HTML-страницы. Этот текст должен быть записан в свойство Content объекта Response.
Свойству Content можно присваивать значение, оформленное как массив строк. Это может быть реализовано следующимспособом:
посредством конкатенаций нескольких строковых значений;
Например:
Response.Content:='<I><База данных MyDB </I> '+
<P> <B> Таблица TBL1 </B></P>;
с применением переменной типа TStringList, реализующей работу с массивом строк. В этом случае следует объявить переменную данного типа, создать ее, а затем, используя метод add, добавить в нее все строки формируемой HTML-страницы.
Например:
var
aPage : TStringList;
i: integer;
begin
aPage:= TStringList.Create;
aPage.Add(' База данных MyDB '+ '<BR>');
aPage.Add(Таблица TBL1 ' + '<BR>');
aPage.Add('f1 = ' + DataSource1.DataSet.FieldByName('F1').AsString+ '<BR>');
// Последовательно записываем в созданный массив строк
// все значения из открытого набора данных
Response.Content := aPage.Text;
aPage.Free;
После размещения созданного серверного приложения в каталог web-сервера, предназначенный для исполняемых файлов, web-браузер может формировать запрос, указывая URL-адрес данного CGI-приложения.
Например: http://localhost/webpub/ProjectDB.exe.
В том случае, если необходимо реализовать не только публикацию данных, но и предоставить средства их редактирования, отображение данных следует выполнять внутри формы в компонентах типа "поле ввода". Кнопка типа submit должна будет вызывать серверное приложение, которое будет использовать получаемые из запроса данные для обновления таблицы базы данных.
Для публикации данных из базы данных на HTML-страницы можно использовать следующие классы:
TQueryTableProducer - для создания HTML-страницы, содержащей таблицу с данными, являющимися результатом выполнения SQL-запроса. Параметры выполняемого SQL-запроса передаются в HTTP-запросе.TDataSetTableProducer - для создания HTML-страницы, содержащей таблицу с данными из сформированного набора данных.Компонент типа TDataSetTableProducer при формировании HTML-страницы, как правило, обрабатывает следующие события:
OnCreateContent - при создании содержимого HTML-страницы;OnFormatCell - при формировании содержимого отдельной ячейки таблицы;OnGetTableCaption - при получении заголовка создаваемой таблицы.Для того чтобы создать серверное приложение, отображающее на HTML-странице поля таблицы базы данных, следует:
File|New|Other, пиктограмма Web Table (или компонент Query ) со страницы Table1 (DatabaseName и TableName).Table1 вызвать Query - сформировать значение свойства SQL).DataSetTableProducer со страницы Internet палитры компонентов.DataSet компонента DataSetTableProducer1 равным Table1, выбрав значение из предлагаемого списка.Caption компонента DataSetTableProducer1 можно использовать для определения заголовка, отображаемого перед таблицей. Для формирования начальных и завершающих тегов HTML-страницы используются значения свойств Header и Footer. Содержание самой таблицы определяется свойством Columns.Header следующие строки:<HTML> <HEAD> <TITLE> Запрос данных из таблицы </TITLE> </HEAD> <BODY>Тег
BODY открывает область, в которой размещается отображаемое содержимое HTML-страницы.Footer следующие строки:</BODY> </HTML>
Далее можно вызывать редактор свойства Column. Для этого или в инспекторе объектов выполните двойной щелчок мышью на значении свойства Column компонента DataSetTableProducer1, или в web-модуле выполните двойной щелчок мышью на компоненте DataSetTableProducer1.
Для добавления всех столбцов в диалоге Editing.DataSetTableProducer1.Columns выполните команду контекстного меню Add All Fields. Каждый добавленный столбец может быть доступен как DataSetTableProducer1.Columns[номер_столбца_начиная_с_0].
WebModule1 и в диалоге Editing WebModule1.Actions добавьте новый элемент действия (кнопка Add New).WebActionItem1 следует создать обработчик события OnAction и ввести в него код, определяющий значение свойства Content объекта ответа. Например: Response.Content:= DataSetTableProducer1.Content ;
Свойство Content объекта DataSetTableProducer1 содержит текст сформированной таблицы с соответствующими HTML-тегами.Сформированная HTML-страница будет отображать таблицу с набором данных, который определен компонентами Table и DataSetTableProducer.
Серверные ASP-страницы реализуются как текстовые HTML-файлы с расширением asp, которые содержат сценарии на языке JScript или VBScript. ASP-сценарии записываются между тегами <% и %>.
Доступ к базам данных выполняется из серверных ASP-сценариев посредством вызова методов интерфейса ADO (
При создании ASP-сценариев можно использовать следующие объекты:
Application - определяет общедоступные переменные.Request - позволяет получить доступ к информации, передаваемой в HTTP-запросе.Response - формирует данные, передаваемые WEB-браузеру.Server - содержит методы, позволяющие создавать объекты и выполнять ASP-файлы.Session - объект, описывающий сеанс конкретного пользователя.Для работы с базами данных в ASP-файлах удобно использовать объектный интерфейс ADO, который создан на базе OLE DB. Объектная модель ADO представляется набором последовательно используемых объектов, включая следующие:
Connection - объект, используемый для соединения с источником данных;Command - объект, используемый для выполнения команд (SQL-операторов) и хранимых процедур;Recordset - объект "результирующий набор", который создается в результате выполнения команды;Field - объект, позволяющий реализовать доступ к столбцу результирующего набора;Parameters - объект, позволяющий работать с входными и выходными параметрами команд и хранимых процедур;Errors - объект, используемый для описания возникающих ошибок.При применении ADO для соединения с базой данных в ASP-сценарии следует использовать объект ADODB.Connection, а для работы с результирующим набором - объект ADODB.Recordset.
Следующий пример иллюстрирует ASP-сценарий, выполняющий отображение записей из таблицы базы данных:
<%
var con,rs;
con=Server.CreateObject("ADODB.Connection");
con.Open ("MyDB", "User1", "");
srtSQL="Select * from t1";
rs= Server.CreateObject("ADODB.Recordset");
rs.Open (strSQL, con);
%>
<TABLE>
while (! rs.EOF)
{
%>
<TR> <TD> <%= rs.Fields("field1")%> </TD>
<TD><%= rs.Fields("field2")%> </TD>
</TR>
<% rs.MoveNext();
}
%>
</TABLE>
<%
rs.Close;
con.Close;
%>
Метод CreateObject ASP-объекта Server создает объект, указываемый параметром. Метод Open ADO-объекта Connection устанавливает соединение с базой данных. Метод MoveNext объекта Recordset выполняет переход к следующей записи.
Объект Recordset позволяет выполнять модификацию записей, используя методы:
AddNew - добавление новой записи;Delete - удаление записи;Update - обновление записи.Например:
<%
rs.AddNew;
rs("field1")="123";
rs.Update;
%>
Для реализации поиска указываемого значения в столбце результирующего набора следует использовать методы объекта Recordset:
Find - поиск на основе заданного условия;Seek - поиск по ключевому полю.Для наложения на открытый результирующий набор некоторого фильтра вызывается метод Filter объекта Recordset.
Для создания результирующего набора можно использовать метод Execute объекта Command.
Например:
<%@LANGUAGE=VBSCRIPT%>
<! ASP-файл >
<html>
<body>
<%
dim con, rs, sql1
sql1="SELECT * FROM Tbl1;"
set con = Server.CreateObject("ADODB.Connection")
con.Open "DSN = MyDB" ' Устанавливаем соединение
set rs = con.execute(sql1) ' Открываем результирующий набор
if rs.BOF and rs.EOF then ' Результирующий набор пустой
Response.Write("Нет строк")
else rs.MoveFirst
Do While Not rs.EOF
' Доступ по имени столбца
Response.Write(rs("F1") " " rs("F2") "<br>")
rs.MoveNext
Loop
end if
rs.close
set rs = nothing
%>
</body>
</html>
Доступ к значениям столбцов может быть реализован через объект типа Recordset как по имени столбца, так и по его номеру. Отображаемые значения в ASP-сценариях указываются после оператора =.
Например:
<TABLE border = 1>
<%
Do while (Not rs.eof) %>
<tr>
<% For Index=0 to (rs.fields.count-1) %>
<td ><% = rs(Index)%></td> ' Доступ по номеру
' столбца
<% Next %> ' Цикл по столбцам
</tr>
<% rs.MoveNext
Loop ' Цикл по строкам результирующего набора
%>
</TABLE>
Страница InternetBeans среды JBuilder содержит компоненты, позволяющие заменять на этапе выполнения сервлета "пустые" данные на данные, предоставляемые модулем данных.
Компонент IxPageProducer предназначен для связывания HTML-файла с используемым модулем данных.
Компонент IxControl позволяет связать элемент управления из IxControl.
Компонент IxTable позволяет отображать в HTML-документах динамически генерируемые таблицы набора данных.
Процесс разработки сервлета, выполняющего публикацию данных на HTML-страницы с применением компонентов страницы InternetBeans, состоит из следующих этапов:
File|New и выбирая на вкладке Web пиктограмму Servlet ). Для возможности обработки GET и POST HTTP-запросов в мастере Servlet Wizard на панели Implement methods следует установить флажки для методов doGet и doPost.IxPageProducer и IxControl, реализующих связь формируемого HTML-документа с модулем данных и элемента управления - с объектом сервлета.doPost и doGet, формирующих возвращаемую web-сервером HTML-страницу.Модуль данных - это Java-класс, реализующий интерфейс DataModule. Модуль данных можно рассматривать как централизованный контейнер для всех компонентов доступа к данным. Модуль данных предоставляет методы, позволяющие работать с наборами данных.
Для создания модуля данных выполните следующие действия:
File|New и на вкладке General выберите пиктограмму Data Module.Class name будет отображаться имя создаваемого модуля данных (по умолчанию - DataModule1).
При включенном флажке Invoke Data Modeler после завершения данного диалога будет предложен диалог Data Modeler для определения SQL-запросов к подключаемой посредством JDBC базе данных.Database|Add Connection URL или команду меню Database|Open Connection URL.Driver, выбрав это значение из предлагаемого списка
(например, (рис 14.1) Диалог Data Modeler - страница Columns
File|Save, а затем завершить диалог Data Modeler, выполнив команду меню File|Exit.Диалог Data Modeler позволяет определить соединение с источником данных и автоматически сформировать SQL-оператор, выполняющий запрос данных.
Для формирования запроса на панели Available columns следует выбрать имена столбцов и скопировать их на панель Selected columns. Страница Where диалога Data Modeler позволяет сформировать условие, а страницы Order By и Group By служат для задания порядка сортировки и группирования данных, получаемых в результирующем наборе.
Для того чтобы просмотреть результат сформированного запроса, следует перейти на страницу Test диалога Data Modeler и щелкнуть по кнопке Execute Query.
При создании модуля данных JBuilder автоматически формирует код класса модуля данных, реализующего интерфейс DataModule.
Например:
package myservlet_database1;
import java.awt.*;
import java.awt.event.*;
import com.borland.dx.dataset.*;
import com.borland.dx.sql.dataset.*;
public class DataModule1 implements DataModule {
static private DataModule1 myDM;
private Database database1 = new Database();
private QueryDataSet customer = new QueryDataSet();
// Переменная customer будет применяться как ссылка
// на используемый набор данных
public static DataModule1 getDataModule() {
// Статической метод getDataModule используется для
// создания объекта типа DataModule1
if (myDM == null) { myDM = new DataModule1(); }
return myDM;
}
public DataModule1() { // конструктор
try { jbInit(); }
catch(Exception e) { e.printStackTrace(); }
}
private void jbInit() throws Exception {
customer.setQuery(
new com.borland.dx.sql.dataset.QueryDescriptor(
database1, "SELECT CUSTOMER.CUST_NO, CUSTOMER.CUSTOMER,
CUSTOMER.PHONE_NO, CUSTOMER.CITY " +
"FROM CUSTOMER", null, true, Load.ALL));
// Метод setQuery устанавливает значение свойства query
// компонента типа QueryDataSet
database1.setConnection(
new com.borland.dx.sql.dataset.ConnectionDescriptor
"jdbc:borland:dslocal:C:\\JBuilder8\\samples\\JDataStore\\
datastores\\employee.jds", "Sample", "", false,
"com.borland.datastore.jdbc.DataStoreDriver"));
}
// Метод setConnection определяет соединение с источником данных
public Database getDatabase1() { return database1; }
public QueryDataSet getCustomer() { return customer; }
}
Для создания HTML-файла, отображающего форму, используемую при публикации данных, выполните следующие действия:
<html> <body><h1> Таблица Customer</h1> <table id="tbl1" align="CENTER" border="1" > <tr><th>Поле1</th></tr> <tr><td>-</td></tr></table> <form method="POST"> Pole1:</p> <input type="text" id="P1" name="Col1" size="30"> <input type="submit" name="submit" value="Submit"> </p></form> </body></html>
Для того чтобы определить используемый модуль данных, следует:
Wizards|Use DataModule.Опция Create New Instance of Data Module диалога Use DataModule Wizard используется в том случае, если предполагается использовать модуль данных для одной формы.
Опция Share (Static) Instance of DataModule позволяет использовать модуль данных несколькими формами приложения, разделяя один экземпляр модуля.
Опция позволяет использовать для одной формы несколько модулей данных, выполняя соответствующую настройку в окне дизайнера.
В результате добавления модуля данных в файле Servlet1 появится объявление переменной dataModule11 типа DataModule1 (например: DataModule1 dataModule11; ), а в метод jbInit будет добавлен вызов метода getDataModule, используемого для создания объекта модуля данных (например, dataModule11 = myservlet_database1.DataModule1.getDataModule(); ).
Для реализации доступа к данным можно использовать компоненты страницы InternetBeans палитры компонентов.
На вкладке Design окна редактора следует добавить в окно структуры компонент IxPageProducer со страницы InternetBeans палитры компонентов.
Объект ixPageProducer1 будет помещен в секцию Other окна структуры (рис. 14.2).
(рис 14.2) Компонент IxPageProducer страницы InternetBeans
При этом в код модуля добавляется строка:
IxPageProducer ixPageProducer1 = new IxPageProducer();
Для определения связи с модулем данных установите значения следующих свойств объекта ixPageProducer1:
dataModule должно указывать используемый модуль данных (например, DataModule11 );htmlFile должно определять имя HTML-файла, содержащего шаблон.Обратите внимание, что свойство rootPath автоматически будет установлено равным полному пути к указанному имени HTML-файла.
Одновременно с этим в код модуля будет добавлен вызов метода ixPageProducer1.setHtmlFile("C:\\ File1.html");.
Компонент IxControl позволяет устанавливать связь между
На вкладке Design окна редактора следует добавить в окно структуры компонент IxControl со страницы InternetBeans палитры компонентов.
Объект ixControl1 будет помещен в секцию Other окна структуры.
Одновременно с этим в код модуля добавляется следующая строка:
IxControl ixControl1 = new IxControl();
Для связывания элемента управления с полем набора данных установите значения следующих свойств объекта ixControl1:
dataset должно указывать используемый набор данных (например, customer );columnName должно определять имя поля набора данных;pageProducer должно указывать компонент типа IxPageProducer (например, ixPageProducer1 );controlName должно определять элемент управления формы и устанавливается равным атрибуту name тега input.Для каждого поля набора данных следует добавить свой компонент типа IxControl.
Компонент IxControl может выполнять обработку событий. Так, если данный компонент связан с командной кнопкой Submit, то для обработки события следует перейти на вкладку Events и создать обработчик события submitPerformed.
Например:
ixControl2.addSubmitListener(new
com.borland.internetbeans.SubmitListener() {
public void submitPerformed(SubmitEvent e) {
ixControl2_submitPerformed(e);
}
});
:
void ixControl2_submitPerformed(SubmitEvent e) {
}
Вставьте в тело метода обработчика события submitPerformed следующий код:
// Запрос текущего модуля данных:
DataModule1 dm = (DataModule1) ixPageProducer1.getSessionDataModule(e.getSession());
// передача и сохранение данных, введенных пользователем,
// в источнике данных, определенным модулем данных:
dm.getCustomer().post();
dm.getCustomer().saveChanges();
// Метод getCustomer - это автоматически сформированный метод модуля
//данных DataModule1.java, возвращающий объект типа QueryDataSet
Методы post и saveChanges класса QueryDataSet используются для передачи и сохранения изменений в базе данных.
Компонент IxTable определяет динамически генерируемый набор данных.
Для определения набора данных установите значения следующих свойств объекта IxTable:
pageProducer должно указывать объект типа IxPageProducer ;dataset должно определять набор данных;elementId определяет таблицу HTML-файла и устанавливается равным атрибуту id тега table.Методы doPost и doGet кода сервлета используются для обработки HTTP-запроса и формирования возвращаемой HTML-страницы.
При использовании компонента IxPageProducer в тело метода doGet следует вставить только одну строку:
ixPageProducer1.servletGet(this, request, response);
Метод servletGet класса IxPageProducer выполняет следующие начальные действия по обработке GET HTTP-запроса:
HttpSession ;При использовании компонента IxPageProducer в тело метода doPost могут быть вставлены следующие строки:
// Получение объекта модуля данных:
DataModule1 dm = (DataModule1)
ixPageProducer1.getSessionDataModule(request.getSession());
ixPageProducer1.servletPost(this, request, response);
// Отображение данных, переданных из формы
doGet(request, response);
Метод doPost в данном примере используется для обработки параметров запроса. Для динамического формирования HTML-документа вызывается метод doGet.
Метод servletPost класса IxPageProducer выполняет начальные действия по обработке POST HTTP-запроса и, если была нажата кнопка submit, то вызывает обработчик события submitPerformed.
В состав JBuilder Enterprise входит сервер IAS (версия сервера зависит от версии среды JBuilder), по умолчанию инсталлируемый в каталог \Inprise\AppServer.
Данный WEB-сервер содержит в каталоге Inprise\AppServer\examples\beans\inpriseexamples\beans файлы JDBCBean.java и HttpJDBCBean.java, которые можно использовать для упрощения процесса публикации данных на JSP-страницах. Файл JDBCBean.java представляет собой бин, содержащий свойства, определяющие подключение к базе данных, и выполняемый SQL-оператор. Файл HttpJDBCBean.java применяется для определения параметров, используемых бином JDBCBean.
Для того, чтобы выполнить публикацию данных на JSP-странице с использованием существующих файлов с классами бинов, следует:
JavaBean, выполнив команду меню File|New, а затем на вкладке New указав пиктограмму JavaBean.ClassName ввести имя создаваемого бина (например, JDBCBean).java.lang.Object.package, указав имя текущего пакета проекта.Перейти на вкладку Bean окна содержания и в редакторе бинов перейти на вкладку Properties.
Эта вкладка содержит следующие свойства бина, позволяющие выполнить SQL-запрос:
classname - имя используемого JDBC-драйвера;
url - расположение источника данных;
username - имя пользователя, подключаемого к базе данных;
password - пароль пользователя;
query - выполняемый SQL-оператор.
Для каждого из перечисленных свойств существует get-метод и set-метод.
Свойства cols и rows (число столбцов и строк в результирующем наборе) используются как простые переменные только внутри бина. Для доступа к их значениям служат свойства columnCount и , имеющие get-методы.
Свойство result используется для формирования отображаемого результата.
Создать второй компонент JavaBean и аналогичным образом скопировать в него файл HttpJDBCBean.java.
Класс HttpJDBCBean наследует классу JDBCBean.
Бин HttpJDBCBean использует свой метод processRequest для обработки запроса. Этот метод должен быть непосредственно вызван из JSP-файла для определения значений всех свойств бина JDBCBean.
JDBCBean и HttpJDBCBean.В файле JDBCBean.java выполнение SQL-запроса осуществляется методом go на основе значений, установленных для свойств данного бина. Так, этот метод реализует следующие основные действия:
Class.forName(classname);
url:Connection con=DriverManager.getConnection(url,username,password);
Statement:Statement stmt = con.createStatement();
query:ResultSet rs = stmt.executeQuery(query);
cols, rows и result метаданные текущего запроса:ResultSetMetaData rsmd = rs.getMetaData(); cols = rsmd.getColumnCount(); rows = 0;
В файле HttpJDBCBean.java. метод processRequest выполняет присвоение значений всем свойствам бина JDBCBean, получая эти значения из параметров запроса.
Метод processRequest определяет значения параметров запроса через объект request типа HttpServletRequest:
if ((_p = request.getParameter("classname")) != null) {
classname = _p;
}
Так, если параметр classname определен, то значение одноименного свойства устанавливается равным его значению.
Если все необходимые параметры заданы, то вызывается метод go бина JDBCBean: this.go();
JSP-директивы используются для указания процессору JSP, каким образом следует выполнять преобразование JSP-файла в сервлет, какие файлы следует включить в состав JSP-документа, где находится библиотека дескрипторов.
JSP-директива указывается между символами <%@ и %>.
JSP-директива page позволяет указать, какие файлы следует подключать, и определить некоторую информацию об JSP-файле.
Директива page имеет ряд атрибутов, включая следующие:
contentType - определяет используемый набор символов и MIME-тип ответа ( contentType="text/html; charset=windows-1251" );import - определяет список импортируемых классов и пакетов. Директива page с атрибутом import может быть вставлена в JSP-файл несколько раз;session - значение true данного атрибута указывает, что при выполнении JSP-файла осуществляется поддержка сеанса;info - данные о JSP-файле, которые доступны посредством вызова Servlet .getServletInfo().Так, автоматически формируемая при создании JSP-файла строка
<%@ page contentType="text/html; charset=windows-1251" %>
использует JSP-директиву page для определения типа возвращаемого документа и типа кодировки.
Для того чтобы создать новый JSP-файл, использующий рассмотренный выше бин, выполните следующие действия:
File|New, а затем на вкладке Web выбрав пиктограмму JavaServer Page.В окне редактора после тега <body> введите следующий код:
<jsp:useBean id="jdbc_bean" scope="application" class="myjspjdbc1.HttpJDBCBean" />
JSP-действие jsp:useBean создает объект типа HttpJDBCBean с идентификатором jdbc_bean
Атрибут class определяет класс создаваемого объекта, квалифицированный именем пакета.
<%@ page import = "myjspjdbc1.*" session="false" %>
processRequest класса HttpJDBCBean:<% jdbc_bean.processRequest(request, response); %>В качестве параметров метода указываются предопределенные переменные request и response, используемые для доступа к параметрам запроса и к формированию ответа.
<p><center><font size=2><b>JSP</b></font></center></p> <p >Доступ к базе данных через JDBC</p><hr></p>Атрибут
size тега font определяет размер шрифта, а тег hr используется для отображения горизонтальной линии.FORM для создания формы, в которую будут помещаться результаты SQL-запроса. Например, введите следующий код:<FORM action=Jsp1.jsp method=post> </FORM>При обработке формы будет использоваться этот же файл Jsp1.jsp.
<TABLE>, разместите в форме таблицу, первый столбец которой будет содержать имя запрашиваемого параметра, а второй столбец - текстовое поле, предназначаемое для ввода значения. Каждое текстовое поле создаваемой таблицы будет соответствовать свойству бина JDBCBean.Например:
<table>
<tr> <td> JDBC-драйвер:</td>
<td><input type="text" name="classname" value="
<%= jdbc_bean.getClassname() %>" size="40"></td>
<td></td> </tr>
<!- JSP-выражение <%= jdbc_bean.getClassname() %>" формирует начальное значение текстового поля, вызывая метод getClassname для определения значения свойства classname объекта с идентификатором jdbc_bean. ->
<tr> <td></td> <td><i>sun.jdbc.odbc.JdbcOdbcDriver</i></td> </tr>
<! - Класс sun.jdbc.odbc.JdbcOdbcDriver реализует JDBC-ODBC драйвер для доступа к источнику данных. Загрузка драйвера выполняется на ПК, на котором запущен Web-сервер.-->
<tr>
<td>JDBC URL-адрес источника данных:</td>
<td><input type="text" name="url" value="
<%= jdbc_bean.getUrl() %>" size="40"></td> </tr>
<tr> <td></td>>
<td><i>jdbc:odbc:MyDB</i></td> </tr>
<tr>
<td>Имя пользователя:</td>
<td><input type="text" name="username" value="
<%= jdbc_bean.getUsername() %>" size="25"></td>
</tr>
<tr>
<td>Пароль:</td>
<td><input type="text" name="password" value="
<%= jdbc_bean.getPassword() %>" size="25"></td>
</tr>
<tr>
<td>Выполняемый SQL-оператор:</td>
<td><textarea cols=35 rows=3 name="query" wrap="soft">
<%= jdbc_bean.getQuery() %></textarea></td>
<!-- Тег textarea используется для создания текстовой области. Атрибуты cols и rows определяют размер создаваемой области. -->
</tr></table>
Тег input с атрибутом type="text" определяет текстовое поле. Атрибут name тега input определяет имя параметра, передаваемого JSP-файлу при обработки формы. Формируемый POST-запрос будет содержать список параметров, указываемых атрибутами name, со значениями, указываемыми атрибутами value.
Например:
<input type="submit" name="submit" value="Выполнить SQL-оператор">
В результате выполненных действий WEB-сервер получит POST-запрос, который будет обработан указанным в теге FORM JSP-файлом. При этом как результат выполнения SQL-оператора будет создан результирующий набор. Далее JSP-файл, используя методы бина, может получить доступ к сформированной информации.
Для того чтобы отобразить на формируемой HTML-странице данные результирующего набора, выполните следующие действия:
Определите число столбцов и выведите строку заголовка таблицы, в которой будет отображаться результирующий набор.
Например:
<% if (jdbc_bean.getColumnCount() != 0){ %><% -- JSP-скриплет --%>
<table cellspacing="0" cellpadding="5" border="0" BGCOLOR=#EDECE5>
<% for (int i=0; i<jdbc_bean.getColumnCount(); i++){
String str0 = jdbc_bean.getColumnLabels(i);
%>
<!-- Метод getColumnLabels бина JDBCBean возвращает заголовок столбца с указанным индексом --><th><%= str0 %></th> <% } %> <% } %>
Запишите JSP-скриплет, формирующий строки результирующего набора в формате HTML.
Например:
<% for (int row=1; row<jdbc_bean.getRowCount(); row++) {%>
<tr></tr>
<% for (int col=0; col<jdbc_bean.getColumnCount(); col++) {
String str1 = jdbc_bean.getCell(col, row);
%>
<td ><%= str1 %></td>
<% } %>
<% } %>
</table>
Приведенный выше JSP-скриплет использует метод getRowCount бина JDBCBean для выполнения цикла по количеству строк, а метод getColumnCount - для выполнения цикла по количеству столбцов. Метод getCell бина JDBCBean возвращает массив строк, содержащий значения всех полей одной записи результирующего набора.
Перед выполнением JSP-файла следует откомпилировать классы используемых бинов.
В JBuilder для компиляции данных классов в проект следует добавить библиотеку Project|Project Properties и на вкладке Paths выберите страницу Required Libraries. Далее для добавления новой библиотеки щелкните мышью на кнопке Add и в секции Project выберите библиотеку
Добавленная библиотека будет отображена в списке библиотек на вкладке Required Libraries.
Для выполнения JSP-файла на Web-сервере Tomcat выделите в окне проекта имя JSP-файла и выполните для него команду контекстного меню Web Run.
После введения значений в отображаемый на вкладке Web View окна содержания результат выполнения JSP-файла, web-сервер формирует HTML-страницу (рис. 14.3), содержащую результат выполнения JSP-скриптов.
(рис 14.3) Результат выполнения web-сервером JSP-файла
Далее приводится код используемых классов ( JDBCBean и HttpJDBCBean ):
// Код файла JDBCBean.java:
package myjspjdbc1;
import java.io.*;
import java.util.*;
import java.sql.*;
public class JDBCBean {
String classname ; // JDBC-драйвер
String url ;
String username ;
String password ;
String query ; // SQL-оператор.
int rows, cols; // Число строк и столбцов результирующего набора
Vector result;
public void setClassname(String classname) {
this.classname = classname; }
public String getClassname() { return classname; }
public void setUrl(String url) {
this.url = url;
}
public String getUrl(){ return url; }
public void setUsername(String username) {
this.username = username; }
public String getUsername() { return username; }
public void setPassword(String password) {
this.password = password; }
public String getPassword() { return password; }
public void setQuery(String query) { this.query = query; }
public String getQuery() { return query; }
protected void go() // Подключение к БД и выполнение запроса
throws ClassNotFoundException, SQLException
{
// Загрузка JDBC-драйвера
Class.forName(classname);
// Создание соединения с базой данных
Connection con = DriverManager.getConnection(url,
username,
password);
// Создание и выполнение запроса
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery(query);
ResultSetMetaData rsmd = rs.getMetaData();
cols = rsmd.getColumnCount();
rows = 0;
result = new Vector();
String s[] = new String[cols];
for (int i=1; i<=cols; i++) {
s[i-1] = rsmd.getColumnLabel(i) ;
}
result.addElement(s);
rows ++;
// Извлечение данных
while (rs.next()) {
s = new String[cols];
for (int i=1; i<=cols; i++) {
s[i-1] = helper(rs, rsmd.getColumnType(i), i);
}
result.addElement(s);
rows ++;
}
}
public static void main (String[] args)
{
JDBCBean jdbcBean = new JDBCBean();
String classname = "com.imaginary.sql.msql.MsqlDriver";
//String url = "jdbc:msql://gaby.eng:4333/demo";
String url = "jdbc:msql://ridgetop.eng:1114/test";
String username = "lfu";
String password = "password";
//String query = "select * from details";
String query = "select * from table1";
jdbcBean.setClassname(classname);
jdbcBean.setUrl(url);
jdbcBean.setUsername(username);
jdbcBean.setPassword(password);
jdbcBean.setQuery(query);
try {
jdbcBean.go();
System.out.println("Seems okay");
} catch (Exception ex) {
ex.printStackTrace();
}
}
public int getColumnCount() { return cols; }
public int getRowCount() { return rows; }
public String getColumnLabels(int col) {
String[] s = (String[])result.firstElement();
return s[col];
}
public String getCell(int col, int row) {
String[] s = (String[])result.elementAt(row);
return s[col];
}
protected String helper (ResultSet rs, int dataType, int col)
throws SQLException
{ String retVal = null; Integer intObj;
// Запрос данных в зависимости от их типа
switch(dataType) {
case Types.DATE:
java.sql.Date date = rs.getDate(col);
retVal = date.toString();
break;
case Types.TIME:
java.sql.Time time = rs.getTime(col);
retVal = time.toString();
break;
case Types.TIMESTAMP:
java.sql.Timestamp timestamp = rs.getTimestamp(col);
retVal = timestamp.toString();
break;
case Types.CHAR:
case Types.VARCHAR:
case Types.LONGVARCHAR:
retVal = rs.getString(col);
break;
case Types.NUMERIC:
case Types.DECIMAL:
java.math.BigDecimal numeric = rs.getBigDecimal(col, 10);
retVal = numeric.toString();
break;
case Types.BIT:
boolean bit = rs.getBoolean(col);
Boolean boolObj = new Boolean(bit);
retVal = boolObj.toString();
break;
case Types.TINYINT:
byte tinyint = rs.getByte(col);
intObj = new Integer(tinyint);
retVal = intObj.toString();
break;
case Types.SMALLINT:
short smallint = rs.getShort(col);
intObj = new Integer(smallint);
retVal = intObj.toString();
break;
case Types.INTEGER:
int integer = rs.getInt(col);
intObj = new Integer(integer);
retVal = intObj.toString();
break;
case Types.BIGINT:
long bigint = rs.getLong(col);
Long longObj = new Long(bigint);
retVal = longObj.toString();
break;
case Types.REAL:
float real = rs.getFloat(col);
Float floatObj = new Float(real);
retVal = floatObj.toString();
break;
case Types.FLOAT:
case Types.DOUBLE:
double longreal = rs.getDouble(col);
Double doubleObj = new Double(longreal);
retVal = doubleObj.toString();
break;
case Types.BINARY:
case Types.VARBINARY:
case Types.LONGVARBINARY:
byte[] binary = rs.getBytes(col);
retVal = new String(binary);
break;
}
return retVal;
}
}
// Код файла HttpJDBCBean.java:
package myjspjdbc1;
import java.io.*;
import java.util.*;
import javax.servlet.http.*;
import java.sql.*;
public class HttpJDBCBean extends JDBCBean {
public void processRequest(HttpServletRequest request,
HttpServletResponse response)
throws IOException
{
// Получение значений параметров, если они заданы
String _p ;
if ((_p = request.getParameter("classname")) != null) {
classname = _p;
}
if ((_p = request.getParameter("url")) != null) {
url = _p;
}
if ((_p = request.getParameter("username")) != null) {
username = _p;
}
if ((_p = request.getParameter("password")) != null) {
password = _p;
}
if ((_p = request.getParameter("query")) != null) {
query = _p;
}
// Если параметры не заданы, то отображать только форму
boolean form_only = false;
if (classname == "" || classname == null) form_only = true;
if (url == "" || url == null) form_only = true;
if (username == null) form_only = true;
if (password == null) form_only = true;
if (query == null) form_only = true;
if (form_only) {
return;
}
try {
this.go(); // Вызов метода, выполняющего запрос
} catch (ClassNotFoundException ex) {
PrintWriter writer = response.getWriter(); // Поток вывода
writer.println("class " + classname + " not found.");
} catch (SQLException ex) {
PrintWriter writer = response.getWriter();
writer.println("Message: " + ex.getMessage());
writer.println("Error code: " + ex.getErrorCode());
ex.printStackTrace(writer);
} catch (Exception ex) {
PrintWriter writer = response.getWriter();
ex.printStackTrace(writer);
}
} }
Среда Delphi позволяет создавать приложения, выполняемые на web-сервере, с целью формирования HTML-страницы, публикующей данные их базы данных. Это могут быть приложения следующих типов:
web-браузер по указанному URL-адресу запрашивает данные от WEB-сервера. При выполнении запроса устанавливается TCP/IP соединение с сервером, и данные передаются в формате HTML. После завершения передачи данных TCP/IP соединение разрывается.
При этом передаваемая HTML-страница может быть как HTML-файлом, так и результатом выполнения на web-сервере некоторого приложения.
web-браузер посылает в качестве запроса URL-адрес серверного приложения, а Web-сервер запускает это приложение и передает ему параметры запроса. Сформированная в результате выполнения серверного приложения HTML-страница возвращается WEB-браузеру web-сервером.
Для того, чтобы создать серверное приложение (например CGI), следует:
File|New|Other, вкладка New, пиктограмма Web В результате будет создан проект, содержащий главный файл приложения и модуль Unit1, имеющий следующий код:
{Модуль Unit1.pas}
unit Unit1;
interface
uses SysUtils, Classes, HTTPApp;
type
TWebModule1 = class(TWebModule)
private { Private declarations }
public { Public declarations }
end;
var
WebModule1: TWebModule1;
implementation
{$R *.DFM}
end.
Для того чтобы добавить код, формирующий HTML-страницу, следует:
TWebModule1 выполнить двойной щелчок мышью на свойстве Action.Editing WebModule1.Actions создать новый элемент (кнопка Add New ).WebActionItem1 обработчик события OnAction. При этом автоматически будет сформирован следующий код:procedure TWebModule1.WebModule1WebActionItem1Action(
Sender: TObject;
Request: TWebRequest; // Объект запроса -
// позволяет получать данные о выполняемом запросе
Response: TWebResponse; // Объект ответа -
// используется для формирования ответа
// (HTML-страницы
var Handled: Boolean);
begin
end;
Сформировать в созданном обработчике события код, формирующий текст HTML-страницы. Этот текст должен быть записан в свойство Content объекта Response.
Свойству Content можно присваивать значение, оформленное как массив строк. Это может быть реализовано следующимспособом:
посредством конкатенаций нескольких строковых значений;
Например:
Response.Content:='<I><База данных MyDB </I> '+
<P> <B> Таблица TBL1 </B></P>;
с применением переменной типа TStringList, реализующей работу с массивом строк. В этом случае следует объявить переменную данного типа, создать ее, а затем, используя метод add, добавить в нее все строки формируемой HTML-страницы.
Например:
var
aPage : TStringList;
i: integer;
begin
aPage:= TStringList.Create;
aPage.Add(' База данных MyDB '+ '<BR>');
aPage.Add(Таблица TBL1 ' + '<BR>');
aPage.Add('f1 = ' + DataSource1.DataSet.FieldByName('F1').AsString+ '<BR>');
// Последовательно записываем в созданный массив строк
// все значения из открытого набора данных
Response.Content := aPage.Text;
aPage.Free;
После размещения созданного серверного приложения в каталог web-сервера, предназначенный для исполняемых файлов, web-браузер может формировать запрос, указывая URL-адрес данного CGI-приложения.
Например: http://localhost/webpub/ProjectDB.exe.
В том случае, если необходимо реализовать не только публикацию данных, но и предоставить средства их редактирования, отображение данных следует выполнять внутри формы в компонентах типа "поле ввода". Кнопка типа submit должна будет вызывать серверное приложение, которое будет использовать получаемые из запроса данные для обновления таблицы базы данных.
Для публикации данных из базы данных на HTML-страницы можно использовать следующие классы:
TQueryTableProducer - для создания HTML-страницы, содержащей таблицу с данными, являющимися результатом выполнения SQL-запроса. Параметры выполняемого SQL-запроса передаются в HTTP-запросе.TDataSetTableProducer - для создания HTML-страницы, содержащей таблицу с данными из сформированного набора данных.Компонент типа TDataSetTableProducer при формировании HTML-страницы, как правило, обрабатывает следующие события:
OnCreateContent - при создании содержимого HTML-страницы;OnFormatCell - при формировании содержимого отдельной ячейки таблицы;OnGetTableCaption - при получении заголовка создаваемой таблицы.Для того чтобы создать серверное приложение, отображающее на HTML-странице поля таблицы базы данных, следует:
File|New|Other, пиктограмма Web Table (или компонент Query ) со страницы Table1 (DatabaseName и TableName).Table1 вызвать Query - сформировать значение свойства SQL).DataSetTableProducer со страницы Internet палитры компонентов.DataSet компонента DataSetTableProducer1 равным Table1, выбрав значение из предлагаемого списка.Caption компонента DataSetTableProducer1 можно использовать для определения заголовка, отображаемого перед таблицей. Для формирования начальных и завершающих тегов HTML-страницы используются значения свойств Header и Footer. Содержание самой таблицы определяется свойством Columns.Header следующие строки:<HTML> <HEAD> <TITLE> Запрос данных из таблицы </TITLE> </HEAD> <BODY>Тег
BODY открывает область, в которой размещается отображаемое содержимое HTML-страницы.Footer следующие строки:</BODY> </HTML>
Далее можно вызывать редактор свойства Column. Для этого или в инспекторе объектов выполните двойной щелчок мышью на значении свойства Column компонента DataSetTableProducer1, или в web-модуле выполните двойной щелчок мышью на компоненте DataSetTableProducer1.
Для добавления всех столбцов в диалоге Editing.DataSetTableProducer1.Columns выполните команду контекстного меню Add All Fields. Каждый добавленный столбец может быть доступен как DataSetTableProducer1.Columns[номер_столбца_начиная_с_0].
WebModule1 и в диалоге Editing WebModule1.Actions добавьте новый элемент действия (кнопка Add New).WebActionItem1 следует создать обработчик события OnAction и ввести в него код, определяющий значение свойства Content объекта ответа. Например: Response.Content:= DataSetTableProducer1.Content ;
Свойство Content объекта DataSetTableProducer1 содержит текст сформированной таблицы с соответствующими HTML-тегами.Сформированная HTML-страница будет отображать таблицу с набором данных, который определен компонентами Table и DataSetTableProducer.
Серверные ASP-страницы реализуются как текстовые HTML-файлы с расширением asp, которые содержат сценарии на языке JScript или VBScript. ASP-сценарии записываются между тегами <% и %>.
Доступ к базам данных выполняется из серверных ASP-сценариев посредством вызова методов интерфейса ADO (
При создании ASP-сценариев можно использовать следующие объекты:
Application - определяет общедоступные переменные.Request - позволяет получить доступ к информации, передаваемой в HTTP-запросе.Response - формирует данные, передаваемые WEB-браузеру.Server - содержит методы, позволяющие создавать объекты и выполнять ASP-файлы.Session - объект, описывающий сеанс конкретного пользователя.Для работы с базами данных в ASP-файлах удобно использовать объектный интерфейс ADO, который создан на базе OLE DB. Объектная модель ADO представляется набором последовательно используемых объектов, включая следующие:
Connection - объект, используемый для соединения с источником данных;Command - объект, используемый для выполнения команд (SQL-операторов) и хранимых процедур;Recordset - объект "результирующий набор", который создается в результате выполнения команды;Field - объект, позволяющий реализовать доступ к столбцу результирующего набора;Parameters - объект, позволяющий работать с входными и выходными параметрами команд и хранимых процедур;Errors - объект, используемый для описания возникающих ошибок.При применении ADO для соединения с базой данных в ASP-сценарии следует использовать объект ADODB.Connection, а для работы с результирующим набором - объект ADODB.Recordset.
Следующий пример иллюстрирует ASP-сценарий, выполняющий отображение записей из таблицы базы данных:
<%
var con,rs;
con=Server.CreateObject("ADODB.Connection");
con.Open ("MyDB", "User1", "");
srtSQL="Select * from t1";
rs= Server.CreateObject("ADODB.Recordset");
rs.Open (strSQL, con);
%>
<TABLE>
while (! rs.EOF)
{
%>
<TR> <TD> <%= rs.Fields("field1")%> </TD>
<TD><%= rs.Fields("field2")%> </TD>
</TR>
<% rs.MoveNext();
}
%>
</TABLE>
<%
rs.Close;
con.Close;
%>
Метод CreateObject ASP-объекта Server создает объект, указываемый параметром. Метод Open ADO-объекта Connection устанавливает соединение с базой данных. Метод MoveNext объекта Recordset выполняет переход к следующей записи.
Объект Recordset позволяет выполнять модификацию записей, используя методы:
AddNew - добавление новой записи;Delete - удаление записи;Update - обновление записи.Например:
<%
rs.AddNew;
rs("field1")="123";
rs.Update;
%>
Для реализации поиска указываемого значения в столбце результирующего набора следует использовать методы объекта Recordset:
Find - поиск на основе заданного условия;Seek - поиск по ключевому полю.Для наложения на открытый результирующий набор некоторого фильтра вызывается метод Filter объекта Recordset.
Для создания результирующего набора можно использовать метод Execute объекта Command.
Например:
<%@LANGUAGE=VBSCRIPT%>
<! ASP-файл >
<html>
<body>
<%
dim con, rs, sql1
sql1="SELECT * FROM Tbl1;"
set con = Server.CreateObject("ADODB.Connection")
con.Open "DSN = MyDB" ' Устанавливаем соединение
set rs = con.execute(sql1) ' Открываем результирующий набор
if rs.BOF and rs.EOF then ' Результирующий набор пустой
Response.Write("Нет строк")
else rs.MoveFirst
Do While Not rs.EOF
' Доступ по имени столбца
Response.Write(rs("F1") " " rs("F2") "<br>")
rs.MoveNext
Loop
end if
rs.close
set rs = nothing
%>
</body>
</html>
Доступ к значениям столбцов может быть реализован через объект типа Recordset как по имени столбца, так и по его номеру. Отображаемые значения в ASP-сценариях указываются после оператора =.
Например:
<TABLE border = 1>
<%
Do while (Not rs.eof) %>
<tr>
<% For Index=0 to (rs.fields.count-1) %>
<td ><% = rs(Index)%></td> ' Доступ по номеру
' столбца
<% Next %> ' Цикл по столбцам
</tr>
<% rs.MoveNext
Loop ' Цикл по строкам результирующего набора
%>
</TABLE>
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.