Класс NewsUpKeep
Классу NewsUpKeep передаются существующий объект DOM <Newsfile> и различные текстовые строки, которые составляют новый элемент <Newsitem>; он переписывает файл XML с сообщениями. Применить этот метод проще, чем создать элемент <Newsitem> и вставить его модель DOM, которая постоянно находится в памяти; кроме того, указанный метод гарантирует, что файл новостей будет обновлен правильным образом. Также при использовании этого метода исключается возможность того, что один из отображающих методов получит частично измененную модель DOM. В листинге 8.27 показано начало кода класса NewsUpKeep. Конструктор класса использует полное имя файла для получения DOM из DOMlibrary. Поскольку эта модель DOM не модифицируется при переписывании файла XML, вам не нужно беспокоиться по поводу возможности одновременного доступа к этому объекту класса NewsFormatter. Заметим, что в классе NewsUpKeep создается переменная rootNNM типа NamedNodeMap, которая содержит имена и значения атрибутов корневого элемента документа XML, <Newsfile>. Также конструктор помещает все узлы <Newsitem> в массив itemNodes. Листинг 27. Начало класса NewsUpKeep (NewsUpKeep.java)
- package com.XmlEcomBook.Chap08;
-
- import com.XmlEcomBook.DOMlibrary ;
- import java.io.*;
- import java.util.* ;
- import javax.servlet.*;
- import javax.servlet.http.*;
- import org.w3c.dom.* ;
-
- public class NewsUpKeep
- {
- File newsFile ;
- String newsFileName ;
- Node[] itemNodes ;
- NamedNodeMap rootNNM ; // для атрибутов корневого элемента
-
- public NewsUpKeep( File f) throws IOException {
- newsFile = f ;
- newsFileName = f.getAbsolutePath() ;
- DOMlibrary library = DOMlibrary.getLibrary();
- Document doc = library.getDOM( newsFileName );
- if( doc == null ){
- throw new FileNotFoundException( newsFileName );
- }
- Element re = doc.getDocumentElement();
- rootNNM = re.getAttributes();
- System.out.println("Root has " + rootNNM.getLength() + " attributes");
- NodeList newsItemNodes = doc.getElementsByTagName("Newsitem");
- int ct = newsItemNodes.getLength();
- itemNodes = new Node[ ct ];
- for( int i = 0 ; i < ct ; i++ ){
- itemNodes[i] = newsItemNodes.item( i );
- }
- }
В листинге 8.28 показаны некоторые вспомогательные методы, необходимые в классе NewsUpKeep. Метод formatTopics гарантирует, что строка, которая будет записана в качестве значения атрибута topic, имеет правильный формат. Листинг 28. Различные вспомогательные функции класса NewsUpKeep (NewsUpKeep.java)
- // проверяем отсутствие пробелов перед названиями
- // тематических категорий и после них, а также наличие запятых
- // между названиями, например: general, food, и т. д.
- private String formatTopics(String s ){
- if( s.indexOf(',') < 0 ) return s.trim();
- // единственным разделителем является запятая
- StringTokenizer st = new StringTokenizer( s, "," );
- StringBuffer sb = new StringBuffer( s.length() );
- while( st.hasMoreTokens() ){
- sb.append( st.nextToken().trim() );
- if( st.hasMoreTokens() ) sb.append(',');
- }
- return sb.toString();
- }
- // преобразует миллисекунды в дни
- private String timeInDays(){
- long t = System.currentTimeMillis() ;
- int tid = (int)(t / ( 1000 * 60 * 60 * 24 ));
- return Integer.toString( tid );
- }
-
- // предполагается, что s - это десятичное число,
- // используемое в <Newsitem id=
- private String incrementID(String s ){
- try{
- int n = Integer.parseInt( s );
- return Integer.toString( n + 2 );
- }catch(NumberFormatException e){
- return s + "a" ;
- }
- }
-
- public String toString(){
- StringBuffer sb = new StringBuffer("NewsUpKeep ");
- sb.append(" Newsitem count: " );
- sb.append( Integer.toString( itemNodes.length ));
- return sb.toString();
- }
Теперь мы подходим к основному рабочему методу, addItem. Сначала этот метод создает новый файл с временным именем и записывает туда стандартное объявление XML и комментарии. Затем создается тег <Newsfile>, куда записываются имена атрибутов и их значения из коллекции rootNNM. Как видно из листинга 8.29, атрибут nextid обрабатывается специальным образом. Сохраняется текущее значение, которое становится значением атрибута id нового элемента <Newsitem>, а увеличенное значение записывается в тег <Newsfile>. Листинг 29. Начало метода addItem (NewsUpKeep.java)
- // новые сообщения всегда добавляются в начало файла,
- // поэтому нужно переделать начало корневого элемента
- public void addItem(
- String head, String date, String topics, String author,
- String shrtStr,
- String longStr ) throws IOException {
- String idVal = "" ;
- String tmpfile = newsFileName + "$$" ;
- File f = new File( tmpfile );
- FileWriter fw = new FileWriter(f);
- PrintWriter out = new PrintWriter( new BufferedWriter( fw ) );
- out.println("<?xml version=\"1.0\" standalone=\"yes\" ?>");
- out.println("<!-- output by NewsUpKeep -->");
- int ct = rootNNM.getLength();
- if( ct == 0 ){
- out.println("<Newsfile>");
- }
- else {
- out.print("<Newsfile ");
- for( int i = 0 ; i < ct ; i++ ){
- Node an = rootNNM.item(i);
- String name = an.getNodeName();
- String val = an.getNodeValue();
- out.print( name + "=\"" );
- if( name.equals("nextid") ){
- idVal = val ;
- val = incrementID( val );
- }
- out.print( val + "\" ");
- }
- out.println(" >");
- }
Затем, как показано в листинге 8.30, пишется новый тег <NewsItem>, за которым следует заголовок сообщения, указывается дата и приводятся краткая и полная версии текста сообщения. Для того чтобы записать старые элементы <NewsItem>, вызывается метод writeNewsNode. После закрытия временного файла старый файл XML удаляется, а временный файл получает имя. Следующий раз, когда этот файл будет запрошен, класс DOMlibrary по изменившейся метке даты модификации файла (timestamp) определит, что нужно считывать новый файл. Листинг 30. Метод addItem, продолжение (NewsUpKeep.java)
- out.print("<Newsitem timestamp=\"");
- out.print( timeInDays() + "\" topic=\"");
- out.print( formatTopics( topics ) );
- out.println( "\" author=\"" + author + "\" id= \"" + idVal + "\" >");
- // конец <Newsitem .. >
- out.println("<head>" + head.trim() + "</head>" );
- out.println("<date>" + date.trim() + "</date>" );
- out.println("<short><![CDATA[");
- out.println( shrtStr.trim() );
- out.println("]]></short>");
- out.println("<long><![CDATA[");
- out.println( longStr ); out.println("]]></long>");
- out.println("</Newsitem>");
- for( int i = 0 ; i < itemNodes.length ; i++ ){
- writeNewsNode(out, (Element)itemNodes[i] );
- }
- out.println("</Newsfile>");
- out.flush(); out.close();
- File forig = new File( newsFileName );
- DOMlibrary library = DOMlibrary.getLibrary();
- // чтобы предотвратить перекрывание операций XML
- synchronized( library ){
- forig.delete();
- if( !f.renameTo( forig )){
- System.out.println("NewsUpKeep.addItem rename failed") ;
- }
- }
- }
Метод writeNewsNode, который записывает отдельный элемент <Newsitem>, показан в листинге 8.31. Листинг 31. Метод, который записывает отдельный элемент из DOM (NewsUpKeep.java)
- // записывает элемент <Newsitem>, воспроизводя все атрибуты
- public void writeNewsNode(PrintWriter out, Element e) {
- NamedNodeMap nnm = e.getAttributes();
- out.print("<Newsitem " ) ; //timestamp=\"");
- int i ;
- for( i = 0 ; i < nnm.getLength() ; i++ ){
- Attr na = (Attr) nnm.item(i); // Attr - это
- // узел под номером i
- String atr = na.getName();
- String val = na.getValue();
- out.print( atr ); out.print("=\"");
- out.print( val ); out.print("\" ");
- }
- out.println(">");
- NodeList nl = e.getChildNodes();
- int ct = nl.getLength();
- for( i = 0 ; i < ct ; i++ ){
- Node nde = nl.item( i );
- if( nde instanceof Element ){
- Element ce = (Element)nde;
- String name = ce.getTagName();
- out.print("<" + name + ">");
- NodeList chnl = ce.getChildNodes() ;
- if( chnl.getLength() == 0 ) continue ;
- Node chn = chnl.item(0);
- if( name.equals("long") || name.equals("short") ){
- out.print("<![CDATA[");
- out.println( chn.getNodeValue().trim() );
- out.print("]]>");
- }
- else { out.print( chn.getNodeValue() );
- }
- out.println("</" + name + ">");
- }
- } // цикл по дочерним узлам <Newsitem>
- out.println("</Newsitem>");
- }
-
- }
На основе нашего опыта добавления новых сообщений с помощью сервлета CompanyNewsServ вы можете сначала создать полный текст сообщения в текстовом редакторе, а затем при работе с формой HTML для ввода текста просто вставить его в форму с помощью команд вырезания и вставки.
Авторы: Брогден Б., Минник К.
Цель этой книги — познакомить разработчиков с технологиями использования XML в программах на Java для электронной коммерции. Для того чтобы построить эффективный коммерческий сайт, мало пройти долгий путь обучения программированию на Java — недостающим звеном останется XML, и эта книга содержит подробное описание методики объединения этих тесно связанных технологий. В ней рассматриваются последние версии интерфейсов API сервлетов и JSP и текущий стандарт XML, и подробно описываются все этапы, необходимые для построения хорошо организованного, динамичного и успешного сайта.
Авторы предполагают, что читатель на базовом уровне знаком с HTML, Java и web-серверами, и у него имеется доступ к компьютеру, на котором можно установить небольшой web-сервер, стандартный компилятор Java и другие служебные программы. Исходный код всех программ, в большом количестве иллюстрирующих материал книги, можно найти на прилагаемом компакт-диске.
Заказать книгу вы сможете в Издательском доме "Питер" - http://shop.piter.com/to_order.phtml?postid=978531800400&refer=10000
Содержание:
Благодарности
Введение
- XML и Java
- Сервлеты Java и JSP-страницы
- Кому стоит купить эту книгу
- Что вам потребуется
- Что содержится в этой книге
- Что содержится на компакт-диске
- Соглашения, используемые в этой книге
- Об авторах
- От издательства
Глава 1. Описание данных с помощью XML
- Введение в XML
- XML и электронная коммерция
- Области применения XML
- XML на стороне клиента
- XML на стороне сервера
- Использование XML для хранения данных
- Правила XML
- Определение правильно оформленного документа XML
- DTD и допустимость документа XML
- Объявления элементов
- Спецификация содержимого
- Объявления атрибутов
- Объявления сущностей
- Непроверенные символьные данные
- Разделы символьных данных
- Комментарии в XML
- Инструкции по обработке
- Схема XML
- Создание таблиц стилей с использованием XSL
- Использование XML в приложениях
- Модели программирования
- Программирование на основе DOM
- Программирование на основе SAX
- Краткий справочник по правилам XML
- Требования к правильно оформленному документу XML
- Элементы
- Применение
- Объявление
- Атрибуты
- Сущности
- Применение
- Объявления
Глава 2. Каталог товаров на XML
- Назначение web-сайта
- Требования
- Ограничения
- Покупка готового пакета - это быстрее и дешевле
- Сборка приложения из стандартных частей - это лучше и дешевле
- Разработка сервера web-приложений - это быстрее и лучше
- Достоинства XML
- Доступность инструментальных средств
- SOAP
- Гибкость инструментальных средств
- Совместимость инструментальных средств
- Поддержка Unicode
- Каталог товаров и DTD
- Организация данных
- Написание DTD
- Доработка DTD
- Создание первого чернового варианта DTD
- Уточнение чернового варианта
- Элементы catalog, product_line и product
- Элементы description, paragraph и general
- Элементы price, quantity_in_stock и image
- Элементы onsale_date, time, clip и title
- Элемент shipping
- Финальная версия
- Принципы разработки DTD
- Репрезентативный образец данных
- Избегайте субтрактивного уточнения
- Упрощайте DTD
- Элементы или атрибуты?
- Рассуждайте в терминах реальных процессов
- Шаблоны XML
- Краткое описание
- Задача
- Контекст
- Причины
- Решение
- Пример
- Обсуждение
- Близкие по назначению шаблоны
- Известные примеры применения
- Стандартизация DTD
Глава 3. Представление XML-каталога в сети
- Технологии представления
- Взаимодействие по протоколу HTTP
- Запрос браузера
- Ответ web-сервера
- API для сервлетов Java
- Классы и интерфейсы для сервлетов Java
- Обработка запросов сервлетами
- Простой пример сервлета
- Инициализация сервлета
- Генерирование ответа сервлетом
- Роль JavaBeans
- API для JSP-страниц
- Язык тегов JSP
- Пользовательские библиотеки тегов
- Обработка запросов JSP
- Встроенные переменные в JSP-страницах
- Организация каталога
- API для объектной модели документа
- Создание объектной модели документа для каталога товаров
- Интерфейс Node
- Интерфейс NodeList
- Интерфейс Document
- Индексация товаров
- Информация для представления каталога в сети
- Организация поиска по ключевым словам
- Форматирование описаний товаров
- Гибкость стилей
- Гибкость содержимого
Глава 4. Заполнение корзины покупателя
- Проблема корзины покупателя
- Использование объектов класса HttpSession
- API для класса HttpSession
- Интерфейс HttpSessionBindingListener
- Корзина покупателя на языке Java
- Классы CartItem и ShoppingCart
- Класс CatalogServ
- Инициализация сервлета
- Методы doGet и doPost
- Метод doPageEnd
- Метод doPageMid
- Отображение полной информации о товаре
- Использование класса cartListener
- Класс CatalogBean
- Использование объектов CartItem и ShoppingCart
- Класс ProductFormatter
- Методы, вызываемые методом doFullItem
- Метод doListOutput
- Метод addText
Глава 5. Оплата и подтверждение заказа
- Процесс оплаты
- Безопасность
- Доверие клиента
- Сбор информации о заказе
- Класс CustomerInfo
- Класс CreditInfo
- Класс Fullfilment
- Класс Authorization
- Класс Order
- Класс TestPaymentAuthorizer
- Класс ShippingCalculator
- Класс Emailer
- Страница CustomerInfo
- JSP-страница ShippingInfo
- JSP-страница CreditInfo
- JSP-страница ConfirmInfo
- Сервлет SubmitOrder
- JSP-страница Approved
- JSP-страница Declined
- Обновление информации о доставке
- JSP-страница OrderDateSelector
- JSP-страница SelectOrder
- JSP-страница ShowOrder
- JSP-страница UpdateFullfilment
Глава 6. Обслуживание виртуального каталога
- Общие принципы редактирования каталога
- Объекты данных
- Класс Catalog
- Класс XMLWriter
- Класс ProductLine
- Класс Product
- Класс Image
- Класс Clip
- Класс DateTime
- Класс Util
- Код для представления информации пользователю
- Главная HTML-страница
- Класс Main сервлета
- JSP-страница Delete
- JSP-страница Edit
- Сервлет UpdateProduct
Глава 7. Поиск своего покупателя с помощью опросов
- Обеспечение конфиденциальности
- Промышленные стандарты
- Общественные организации
- Создание системы опросов с помощью XML-сценария
- Определение последовательности вопросов
- Пример анкеты
- Сервлет управления опросом
- Код сервлета управления опросом
- Класс Interpreter
- Отображение вопросов
- Отображение введения
- Управление ветвлением опроса
- Обработка элемента Terminal
- Вспомогательные методы класса Interpreter
- Класс Recorder
- Варианты анализа анкеты
- Класс для создания файлов снимков
- Класс для создания таблиц
- Пример сервлета для просмотра результатов отчета
- Служебная библиотека документа XML
Глава 8. Новости на сайте
- Разработка системы показа новостей
- Гибкость отображения
- Элементы текстов сообщений
- Расположение сообщений в зависимости от их новизны
- Информация для управления сообщениями
- Корневой элемент документа
- Простота ввода данных
- Минимальная нагрузка на сервер
- Система показа новостей
- Внешний вид web-страницы
- Класс NewsFormatter
- Использование класса NewsFormatter
- Код для сервлета TheNewsServ
- Пример JSP-страницы
- Добавление свежих новостей
- Сервлет CompanyNewsServ
- Класс NewsUpKeep
Глава 9. Привлечение постоянных посетителей
- Источники новостей и стандарты
- Формат RSS
- NewsML и планы стандартизации
- Формат сообщений Moreover.com
- Получение файла XML
- Класс NewsModel
- Создание DOM
- Выбор заголовков
- Главный управляющий класс
- Классы для отображения заголовков
- Сервлет NetNewsServ
- Класс NetNewsBean
- Возможные усовершенствования
Глава 10. Web-приложения на Java
- Спецификации в интерфейсе API сервлетов Java
- Развертывание web-приложения
- Определение web-приложения
- Структура папок
- Содержимое папки WEB-INF
- Дескриптор развертывания web-приложения
- Параметры конфигурации
- Архивные файлы web-приложения
- Следующее поколение
- Следующее поколение XML
- Протокол SOAP
- Проблемы масштабирования
- Сохранность информации о сеансе
- J2EE и Enterprise JavaBean
- Альтернативное решение - Spaces
Приложение А. Интерфейсы API для сервлетов и JSP-страниц
- Параметры приложений
- Создание сервлета
- Методы класса HttpServlet
- Интерфейс ServletContext
- Получение информации о запросе
- Методы, добавляемые интерфейсом HttpServletRequest
- Методы, связанные с безопасностью
- Методы, связанные с сеансами и cookie
- Другие методы интерфейса ServletRequest
- Класс HttpSession и классы, связанные с cookie
- Методы класса HttpSession
- Методы интерфейса HttpSessionListener
- Методы класса Cookie
- Специальные объекты, связанные с запросом
- Формирование ответа пользователю
- Методы интерфейса ServletResponse
- Методы, добавляемые интерфейсом HttpServletResponse
- Выходные данные JSP-страниц
- Ошибки и исключения
- Ошибки и исключения JSP-страниц
- Коды состояний и ошибок HTTP
- Интерфейс API для JSP-страниц
- Класс PageContext
- Доступ к стандартным переменным
- Класс JspWriter
- Пакет javax.servlrt.jsp.tagext
- Класс BodyContent
|