В первой статье из этой серии, состоящей из двух частей, мы рассмотрели интеграцию Lotus Domino и IBM WebSphere с использованием Domino XML (называемую также DXL). DXL позволяет вам обращаться к Domino-объектам, не имея больших знаний о Lotus Domino. Однако для использования DXL-метода необходим определенный опыт работы с Java. Для разработчиков Notes-приложений с небольшим опытом в Java существует библиотека JSP-тегов Domino, поставляемая с Lotus Domino Toolkit для WebSphere Studio. Этот набор инструментальных программ доступен в Lotus Notes/Domino 6.0.2 и выше. Пользователи с Passport Advantage могут также загрузить этот набор инструментальных программ.
Lotus поставляется с двумя библиотеками JSP-тегов, начиная с выпуска Lotus Domino 6. Эти библиотеки предоставляют программистам возможность разрабатывать J2EE-приложения, которые взаимодействуют с Lotus Domino практически на любом J2EE-совместимом сервере приложений. До того, как эти библиотеки стали доступными, JSP-разработчики, желавшие подключить свои приложения к Lotus Domino, должны были использовать CORBA и IIOP-вызовы. Это приводило к сложному и, часто, зависимому от базы данных коду, который редко использовался повторно. По мере роста требований к возможности взаимодействия возникла необходимость в более развитом, более мощном решении.
Lotus отреагировал на эти требования созданием двух библиотек тегов, которые абстрагируют и инкапсулируют общие функции Lotus Domino и J2EE. Эти библиотеки определены в дескрипторах библиотек тегов domtag.tld и domutils.tld. Domutils.tld описывает служебные теги, обрабатывающие задачи, общие для всех J2EE-приложений. Эти теги не зависят от Lotus Domino и могут быть использованы в любом приложении (независимо от сервера Domino). Теги, описанные в domtag.tld, зависят от Lotus Domino. Они предоставляют программный доступ практически ко всем Domino-элементам, включая дизайн, списки управления доступом и документы. В данной статье мы рассмотрим специфичные для Domino теги (определенные в domtag.tld). Имея это в виду, мы будем ссылаться на них просто как на taglib.
Библиотека taglib требует более глубоких знаний Lotus Domino, чем XML-метод, рассмотренный в первой статье. Она использует терминологию и элементы управления, которые тесно встроены в интегрированную систему Domino. Для эффективного использования taglib важно иметь глубокие познания в Lotus Domino, а также в различных элементах дизайна и структурах данных, к которым вы обращаетесь. Просмотрите раздел "План действий" из первой части, чтобы определиться, какой метод более подходит вам и вашему приложению.
taglib соответствует спецификациям JSP 1.1 и Servlet 2.2 и поддерживает большинство J2EE-совместимых серверов приложений. Примеры в этой статье установлены на IBM WebSphere Application Server 5.1 и разработаны в WebSphere Studio Application Developer. В данной статье предполагается, что вы знакомы с Domino-объектами и терминологией, а также с основами J2EE-программирования с использованием WebSphere Studio Application Developer.
ПРИМЕЧАНИЕ: За исключением подготовки Lotus Domino для обработки IIOP, вам не нужны какие-либо знания в CORBA или IIOP-программировании при использовании taglib.
Требования к программному обеспечению таковы:
- WebSphere Application Server 5.x или другой J2EE-совместимый сервер приложений.
- Lotus Domino 6.x с установленной и разрешенной службой DIIOP.
taglib использует технологии CORBA (Command Object Request Broker Architecture) и IIOP (Internet Inter-ORB Protocol) для взаимодействия с Lotus Domino. Вы должны настроить сервер Domino на прослушивание IIOP-запросов. Во-первых, убедитесь, что DIIOP установлен. Выполните команду show task или load diiop в консоли Domino, для того чтобы определить, присутствует ли DIIOP. Если нет, установите его с установочного CD Domino.
Затем измените файл Notes.ini сервера Domino для автоматической загрузки DIIOP при старте Lotus Domino. Найдите строку, начинающуюся с ServerTasks. В конце этой строки добавьте diiop. Перезапустите сервер Domino и проверьте сообщения, выдаваемые сервером DIIOP.
Рисунок 1. DIIOP-процесс, запущенный при старте сервера
При запуске DIIOP-процесс создает IOR (Internet Object Reference) с именем diiop_ior.txt в корневом каталоге (root) Domino HTTP (C:\lotus\domino\data\domino\html по умолчанию для установки Domino в Windows). Ели вы используете Lotus Domino в качестве вашего HTTP-сервера, то можете пропустить следующий раздел.
Если вы не используете Lotus Domino в качестве HTTP-сервера, то необходимо указать DIIOP-процессу поместить файл в корневой HTML-каталог вашего HTTP-сервера.
- Откройте документ Domino Server.
- Выберите закладку Internet Protocols - DIIOP.
- В поле External HTML directory введите полный путь к корневому HTML-каталогу не Domino HTTP-сервера.
- Сохраните документ Server и перезапустите DIIOP.
Рисунок 2. Раздел DIIOP документа Server
Проверьте, доступен ли файл http://127.0.0.1/diiop_ior.txt из web-браузера.
Рисунок 3. Файл diiop_ior.txt в web-браузере
Настройка среды J2EE-приложения
Для использования taglib необходимы два JAR-файла: NCSO.jar или Notes.jar (см. вставку справа на странице) и domtag.jar.
- В Windows Explorer откройте [путь установки Notes]\Data\domino\java. Найдите и скопируйте domtags.jar и NCSO.jar в каталог WEB-INF/lib web-приложения.
ПРИМЕЧАНИЕ: Скопируйте эти файлы в каталог shared-libraries вашего сервера приложений, если у вас есть более одного web-приложения, использующего taglib.
Рисунок 4. Перспектива J2EE программы WebSphere Studio Application Developer
- В каталоге [путь установки Notes]\Data\domino\java найдите domtags.tld и скопируйте его в каталог WEB-INF проекта. Этот файл является дескриптором библиотеки тегов (Tag Library Descriptor, то есть, имеет расширение TLD). Он описывает теги по отношению к их Java-коду, для того чтобы сервер приложений мог понимать теги.
- Затем найдите и откройте файл web.xml web-приложения. Добавьте следующую ссылку taglib и сохраните изменения.
<taglib id="domtags"> <taglib-uri>domtags.tld</taglib-uri> <taglib-location>/WEB-INF/domtags.tld</taglib-location> </taglib>
Вот пример web.xml:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app id="WebApp"> <display-name>ArticleWeb</display-name> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> <taglib id="domtags"> <taglib-uri>domtags.tld</taglib-uri> <taglib-location>/WEB-INF/domtags.tld</taglib-location> </taglib> </web-app> |
Установка параметров по умолчанию
taglib имеет несколько параметров контекста (Context Parameters), которые вы можете установить в файле web.xml. Очень рекомендуется как можно полнее использовать эти параметры, влияющие на приложения, для увеличения переносимости и облегчения обслуживания в будущем.
В нашем примере мы установили хост (127.0.0.1) и базу данных (articleSample.nsf) как Context Parameters. Это lotus.domino.default.host и lotus.domino.default.dbname соответственно.
Для этого откройте web.xml, добавьте следующие строки и сохраните его.
<context-param id="dominohost"> <param-name>lotus.domino.default.host</param-name> <param-value>127.0.0.1</param-value> </context-param> <context-param id="dominodbname"> <param-name>lotus.domino.default.dbname</param-name> <param-value>articlesample.nsf</param-value> </context-param> |
В следующих разделах мы используем базу данных Car, с которой мы работали в предыдущей статье. Мы создадим четыре JSP-страницы, которые будут делать следующее:
- Отображать документ.
- Отображать содержимое представления Domino.
- Разрешать поиск в представлении Domino.
- Позволять пользователям создавать и редактировать документы.
Перед началом работы мы должны включить эту декларацию taglib во все JSP, которые используют taglib. Это указывает серверу приложений, что каждый тег, начинающийся со слова domino, является ссылкой на запись в описателе библиотеки тегов domtags, например, <domino:db> (хотя вы можете использовать и другой префикс, очень рекомендуется использовать domino).
<%@ taglib uri="domtags.tld" prefix="domino" %>
Сначала мы создадим простую JSP-страницу для отображения содержимого Notes-документа. Она принимает один параметр строки запроса страницы под названием unid, значение которого является уникальным ID запрашиваемого документа. В вашем редакторе JSP создайте новую JSP - disptagcar.jsp. Начните с ввода декларации taglib, упомянутой выше. Хорошей идеей также является включение строки import с lotus.domino.*, поскольку это позволяет обращаться к Domino-объектам напрямую. Мы обсудим это подробнее позже.
<%@ taglib uri="domtags.tld" prefix="domino" %>
<%@page import="lotus.domino.*"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<%@ page
language="java"
contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"
%>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Vehicle information using Domino Tag Library</title>
</head>
<body>
<h1>Vehicle information using Domino Tag Library for <%=
(String) request.getParameter("unid")%></h1>
<domino:document>
<table border="1" width="100%" cellspacing="0" cellpadding="0">
<tr bgcolor="#ccff00">
<th>Make</th>
<th>Model</th>
<th>Body Type</th>
<th>Engine</th>
<th>Year</th>
<th>Specifications</th>
</tr>
<tr>
<td>
<domino:item name="make"/>
</td>
<td>
<domino:item name="model"/>
</td>
<td>
<domino:item name="bodytype"/>
</td>
<td>
<domino:item name="enginetype"/>
</td>
<td>
<domino:item name="year"/>
</td>
<td>
<domino:item name="specifications" format="<LI>"/>
</td>
</tr>
</table>
</domino:document>
</body>
</html>
|
Тег <domino:document> предоставляет контекст Notes-документа. В нем ваш код имеет доступ практически ко всем элементам и свойствам конкретного документа. В некоторых случаях вы, возможно, захотите передать значения в атрибуты dbserver, dbname и unid в теге document. Но обратите внимание, что мы не сделали этого в нашем примере. Причина заключается в том, что необходимая информация уже указана в другом месте. Имя хоста сервера и имя файла базы данных уже определены в дескрипторе web-развертывания (Web Deployment Descriptor - web.xml). UNID неявно указывает, где присутствует параметр строки запроса страницы unid.
Если по каким-либо причинам вы не хотите отображать UNID в URL, необходимо явно предоставить его каким-то образом тегу document в атрибуте unid.
<% String unid = [[code that obtains the document unid]]; %> <domino:document unid=?<%= unid %>?> |
Тег <domino:item> отображает содержимое элемента, указанного в атрибуте name. Например, <domino:item name="make"/> отображает значение, хранящееся в элементе make. Тег последнего элемента, ссылающийся на поле specifications, имеет атрибут format. Этот атрибут указывает библиотеке тегов, как отображать значение в JSP. Значение, которое вы предоставляете этому атрибуту, называется ключевым словом. Вы можете использовать более одного ключевого слова в атрибуте format.
Вспомните, что поле specifications является многозначным полем; оно может содержать более одного значения. Ключевое слово <li> указывает тегу <domino:item> заключать каждое значение в specifications между тегами <li> и </li>.
Отображение содержимого представления
Представления Domino доступны через тег <domino:view>. Например, в нашем примере car у нас есть простое представление, называемое Cars\By VIN, которое содержит два столбца: vin и make. Представление имеет также псевдоним vins, на который мы ссылаемся в теге view.
Рисунок 5. Notes-клиент, отображающий представление VINs
Вот код JSP, отображающий представление VINs в виде HTML.
<%@ taglib uri="domtags.tld" prefix="domino" %>
<%@page import="lotus.domino.*"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<%@ page
language="java"
contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"
%>
<%
String count = "30";
if(request.getParameter("count")!=null);
count = (String)request.getParameter("count");
%>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Car List using Domino Tag Library</title>
</head>
<body>
<h1>Car List using Domino Tag Library</h1>
<domino:db>
<table border="1">
<tr bgcolor="#ffcccc">
<th>
VIN
</th>
<th>
Make
</th>
<th>
Model
</th>
</tr>
<domino:view viewname="vins" max="<%= count %>">
<domino:viewloop>
<tr>
<td>
<domino:formlink href="disptagcar.jsp" >
<domino:viewitem name="vin" />
</domino:formlink>
</td>
<td>
<domino:viewitem name="make" />
</td>
<td>
<domino:item name="model" />
</td>
</tr>
</domino:viewloop>
</domino:view>
</table>
</domino:db>
</body>
</html>
|
Рисунок 6. JSP-страница, отображающая содержимое представления VINs
Исследование JSP-страницы представления
Давайте исследуем предыдущую JSP-страницу. Мы используем ее для создания поисковой страницы в следующем разделе.
- Database
Тег <domino:db> предоставляет приложению контекст базы данных. Поскольку мы определили базу данных по умолчанию в файле web.xml, нам не нужно указывать ее здесь. Если вы не указываете базу данных по умолчанию в web.xml или хотите обратиться к базе данных, отличной от определенной в web.xml, необходимо предоставить информацию здесь, определив атрибут dbname и (если база данных находится на другом сервере) dbserver. - View
Размещение тега <domino:view> в контексте тега <domino:db> обеспечивает доступ к именованному представлению в этой базе данных. Вы должны предоставить название представления в виде атрибута viewname. Можно использовать псевдоним представления. Атрибут max управляет количеством записей, отображающихся на странице. - Viewloop
Этот тег обеспечивает итерацию по каждой записи в представлении. Итерация проходит по всему представлению и обеспечивает доступ к его содержимому. В примере мы просто распечатываем содержимое представления в теге viewitem, описанном далее. - Formlink
Тег <domino:formlink> динамически формирует ссылки <a href> на указанную JSP. Получаемая страница должна содержать код библиотеки тегов некоторой формы, который может отобразить содержимое документа. В нашем примере мы используем JSP-страницу, созданную нами в последнем разделе (disptagcar.jsp). - Viewitem
Тег <domino:viewitem> обеспечивает прямой доступ к записи представления. Атрибут name ссылается на столбец name в представлении. Значение name чувствительно к регистру символов и должно точно соответствовать заголовку столбца.<domino:viewitem name="vin" />
<domino:viewitem name="make" /> - Item
Тег <domino:item> обеспечивает доступ к полю, расположенному в документе. Атрибут name указывает извлекаемое поле.
Отличие между <domino:item> и <domino:viewitem> состоит в том, что <domino:item> должен открывать документ для извлечения значения, в то время как <domino:viewitem> использует любое значение, отображаемое в представлении. Везде, где возможно, избегайте использования тега item в контексте viewloop, поскольку производительность может сильно упасть.
В данном разделе мы рассмотрим, как изменить JSP-страницу представления, которую мы создали, для поддержки поисковых функций.
Для того чтобы полнотекстовый поиск работал правильно, должен быть включен полнотекстовый индекс базы данных Domino. Чтобы убедиться, индексирована ли база данных, откройте окно Database Properties и выберите закладку Search. Если база данных не индексирована, нажмите кнопку Create Index. В строке состояния Notes-клиента будет указано, поставлен ли ваш запрос в очередь на выполнение. Полнотекстовый индекс обычно создается быстро.
Рисунок 7. Закладка со свойствами полнотекстового индекса базы данных
Наша поисковая форма будет содержать три поля для настраиваемого поиска: запрос, максимальное количество возвращаемых результатов и количество записей, отображающихся на странице. Мы используем JSP-страницу представления из последнего раздела в качестве основы для поисковой JSP-страницы.
Фот фрагмент JSP-кода, обрабатывающего операцию поиска:
<domino:view viewname="vins" ftsearch='<%= query %>' max='<%= max %>'> <domino:page rows='<%= count %>'> <tr><td colspan="3" align="right">Go to page: <domino:pagebar navstyle="NextPrev" /> <domino:pagenext>Next></domino:pagenext></td></tr> <domino:viewloop> <tr> <td> <domino:formlink href="disptagcar.jsp" > <domino:viewitem name="vin" /> </domino:formlink> </td> <td> <domino:viewitem name="make" /> </td> <td> <domino:item name="model" /> </td> </tr> </domino:viewloop> <domino:novalues> <tr> <td> The search for <%= query %> found no matches. Use another keyword and try again. </td> </tr> </domino:novalues> <tr><td colspan="3" align="right">Go to page: <domino:pagebar navstyle="NextPrev" /> <domino:pagenext>Next></domino:pagenext></td></tr> </domino:page> </domino:view> |
Исследование JSP-страницы представления Search
Давайте рассмотрим более подробно JSP-страницу представления Search.
- View
Для создания поискового представления мы должны добавить два атрибута в тег <domino:view>: ftsearch и max. Ftsearch - это строка запроса, а max - максимальное количество возвращаемых результатов. - Page
Этот тег обеспечивает управление разбиением на страницы для отображения содержимого представления, а также результатов поиска. Его атрибут rows ограничивает количество записей на одной странице. Этот тег предоставляет контекст для тегов, обеспечивающих функции навигации. - Pagebar
В контексте тега page <domino:pagebar> автоматически генерирует ссылки на страницы, на которых отображаются результаты поиска. Ссылка на текущую страницу выделяется жирным шрифтом и является не нажимаемой. - Pagenext
Этот тег автоматически генерирует ссылку на следующую страницу. Тело этого тега является текстовым обозначением ссылки. В данном случае мы используем Next >. Вы можете использовать этот тег рядом со ссылками на страницы для создания страничной навигации, аналогичной изображенной на рисунке 8.
Рисунок 8. Строка навигации
- Novalues
Тело этого тега является текстом, отображающимся при отсутствии результатов поиска. В нашем примере мы отображаем сообщение "The search for [query] found no matches. Use another keyword and try again" ("Соответствия для [запрос] не найдены. Используйте другое ключевое слово и повторите попытку").
В этом последнем разделе мы создадим JSP-форму, при помощи которой пользователь может создавать и изменять Notes-документы. Для простоты наш пример базы данных позволяет анонимный доступ. В реальных приложениях, где защита данных действительно важна, более разумным подходом могло бы быть использование централизованного реестра пользователей (например LDAP) и реализация единой регистрации (single sign-on - SSO). Настройте WebSphere как доверенный контейнер для обработки аутентификации и авторизации для Lotus Domino. Более подробная информация по SSO для WebSphere и Lotus Domino приведена в WebSphere Application Server InfoCenter.
Наша форма предоставляет следующие функциональные возможности:
- Позволяет пользователям создавать документы. Отображает сообщение, указывающее на то, что пользователь создает новый документ.
- Позволяет пользователям изменять существующие документы. Отображает сообщение, указывающее на то, что пользователь изменяет существующий документ.
- Проверяет правильность введенной информации. Отображает специальное сообщение об ошибке при неудачной проверке.
- Перенаправляет пользователей на страницу с благодарностью (thank you page) при успешном подтверждении формы.
Полный исходный код Form JSP приведен в файле "Код Form JSP".
Тег <domino:form> предоставляет доступ для изменения указанного документа. Он поддерживает несколько атрибутов для расширенных действий. Мы использовали в примере наиболее общеупотребительные. Давайте их рассмотрим:
- Name
Это имя объекта формы. Это значение также будет использоваться в качестве имени HTML-формы. Оно должно быть уникальным в каждой JSP-странице. - Schema
Это значение соответствует имени Domino-формы, с которой документ должен быть сохранен. Над документом производится обработка Domino-формы перед сохранением (pre-save processing) (QuerySave). Установка этого значения также неявно помещает ее в поле form документа. - Editmode
Этот атрибут принимает три значения: display, edit и delete. Хотя вы можете жестко запрограммировать значение этого атрибута, возможно, наиболее полезной была бы установка значения этого атрибута на основе определенной логики в коде. - Validhref
Это значение является страницей назначения, на которую вы хотите направить пользователя после проверки и сохранения формы. - Clientvalidate
Установка этого значения в true вызывает проверку введенной пользователем информации в форму на основе validation-тегов. Напротив, установка значения в false вызывает игнорирование формой всех validation-тегов. - User
Указывает имя пользователя, который обращается к Domino-данным. По завершении аутентификации с использованием J2EE-контейнера, установите это значение в *webuser. Полная информация по защите taglib приведена в справке Domino Designer Help. - Unid
Если существует параметр unid в строке запроса JSP-страницы, тег form использует этот unid для открытия документа. В качестве альтернативы вы можете передать unid в атрибуте unid. - Input-теги
Input-теги создают HTML-поля ввода. Атрибут name указывает элемент, с которым значение должно быть сохранено. По умолчанию типом данных является text. В случае, когда требуется другой тип данных, укажите атрибут data type соответствующим типу данных поля в схеме формы. Для многозначных полей установите multivalue="true" и укажите разделитель значений при помощи mveditseparator и mvdisplayseparator. В нашем примере мы используем запятые для разделения значений при редактировании и точки с запятой при отображении. - Validation-теги
Эти теги служат для проверки введенных значений перед сохранением формы. Lotus предоставляет несколько validation-тегов для обработки проверки различных типов данных. В нашем примере мы использовали наиболее часто употребляемые теги validaterequired и validatepattern. Вы можете использовать более оного validation-тега в одном поле.
Теперь давайте рассмотрим используемые нами validation-теги:
- Validatesummary
Этот тег отображает значение атрибута message validation-тега, который обнаруживает неудачную проверку. Поместите этот тег вверху формы, для того чтобы пользователь мог сразу увидеть, что именно он/она заполнил не правильно. - Validaterequired
Этот тег определяет, равно ли значение поля атрибута name значению null. Если нет, тело этого тега будет отображаться на странице. Поместите этот тег сразу за полем, для точного указания пользователю, на что он/она должен обратить внимание. - Validatepattern
В ситуациях, когда базовых validation-тегов недостаточно, вы можете использовать этот тег для создания пользовательских проверок корректности. Этот тег основан на библиотеке Apache regexp, используемой при проверки введенных значений. Создайте регулярное выражение, описывающее ожидаемый формат значения и поместите его в атрибут pattern. Тег будет сравнивать вводимую пользователем информацию с регулярным выражением. В нашем примере тег validatepattern проверяет, что поле year является цифровым и имеет четыре символа.
Тег <domino:document> предоставляет доступ к самому Notes-документу. Наличие атрибута id указывает библиотеке taglib назначить объект lotus.domino.Document с его именем в качестве значения тега id. Таким объектом в нашем примере является doc. Это дает программисту полный доступ к свойствам и методам объекта; дальнейшее расширение использования taglib - быть программируемой в обычном Java-коде. Эта мощная функциональная возможность доступна для большинства тегов в taglib. Для более подробного изучения Domino Java-классов обратитесь к справке Domino Designer Help.
В данной статье мы рассмотрели, как использовать библиотеку JSP-тегов Domino для создания мощных J2EE-приложений, работающих с Domino. Используя примеры, мы рассмотрели обычно используемые теги и исследовали концепции, лежащие в их основе. Информация, представленная в данной серии статей, должна помочь вам адаптировать J2EE в вашу существующую Domino-среду.
| Описание | Имя | Размер | Метод загрузки |
|---|---|---|---|
| Code sample to accompany this article | DominoJSPArticle.zip | 1.9 MB | FTP |
- Примите участие в обсуждении материала на форуме.
- Оригинал статьи "Lotus Domino and IBM WebSphere integration solutions: Domino JSP tag libraries".
- Прочтите первую часть данной серии статей "Интеграционные решения Lotus Domino и IBM WebSphere: Domino XML".
- Полный исходный код Form JSP приведен в присоединенном файле.
-
Информация по Lotus Domino Toolkit для WebSphere Studio приведена на странице продукта.
- Для более подробного изучения WebSphere посетите раздел WebSphere на developerWorks Россия. Вы найдете техническую документацию, статьи how-to, обучающие материалы, файлы для загрузки, информацию о продукте и многое другое.
- Подключайтесь к сообществу developerWorks, принимая участие в блогах developerWorks.
- Просмотрите список книг по этой и другим техническим темам.
Джефри Ло (Jeffrey Lo) - инженер-программист, консультант alphaWorks, ресурса IBM по новым технологиям. Джеф работает в IBM с 1999, посвящая свое время проектированию и созданию приложений для Lotus Domino и IBM WebSphere. В сферу его ответственности входит Web-сайт alphaWorks, его система управления контентом (содержимым) и несколько поддерживающих серверных приложений. В выходные он любит кататься на велосипеде по горам California Santa Cruz и фотографировать побережье Тихого океана.