Электронный магазин на Java и XML




Глава 6. Обслуживание виртуального каталога


    Глава 6. Обслуживание виртуального каталога
    Глава 6. Обслуживание виртуального каталога В главе 2 мы создали определение типа документа (DTD) каталога товаров для нашего гипотетического сетевого магазина XMLGifts.com. В главе 3 мы создали J...
    Общие принципы редактирования каталога
    Общие принципы редактирования каталога Так как данные в нашем каталоге представлены в виде кода XML, одним из способов редактирования является использование обычного текстового или XML- редактора....
    Рис. 6.1. Общие принципы решения...
    Рис. 6.1. Общие принципы решения задачи редактирования каталога Первым шагом в создании приложения является конструирование объектов XML для представления информации каталога. В этих объектах буду...
    Объекты данных
    Объекты данных Иногда взаимодействие с документом XML на уровне анализатора оказывается непростым делом. Если документ имеет достаточно сложную структуру, то работа с каждым элементом и атрибутом...
    Рис. 6.2. UML-диаграмма классов
    Рис. 6.2. UML-диаграмма классов Посмотрев на DTD из главы 2, вы обнаружите довольно много элементов, не представимых простыми классами. Элементы catalog, product_1ine, product, image, clip и onsal...
    Класс Catalog
    Класс Catalog Класс Catalog представляет корневой элемент DTD каталога, приведенного ниже: !ELEMENT catalog (product_line*) У этого элемента нет атрибутов и имеется только один многократно повторя...
    Листинг 6.1. Первая часть кода...
    Листинг 6.1. Первая часть кода для объявления класса Catalog (Catalog.java) package com.XmlEcomBook.Chap06; import javax.xml.parsers.*; import java.util.*; import java.io.*; import org.w3c.dom.*;...
    Листинг 6.2. Конструктор класса Catalog (Catalog.java)
    Листинг 6.2. Конструктор класса Catalog (Catalog.java) public Catalog( String filename) throws IOException { Document document = null; DocumentBuilderFactory factory = DocumentBuilderFactory.newIn...
    Листинг 6.З. Добавление новых...
    Листинг 6.З. Добавление новых серий товаров — элементов ProductLine (Catalog .Java) public void addProductLine( ProductLine productLine ) { productLines.addEleraent( productLine ); } Далее, вам ну...
    Листинг 6.4. Поиск объекта ProductLine (Catalog.java)
    Листинг 6.4. Поиск объекта ProductLine (Catalog.java) public ProductLine getProductLine( String name ) { Enumeration enum = productLines.elements(); while( enum.hasMoreElements() ) { ProductLine p...
    Листинг 6.5. Поиск товара в каталоге (Catalog.java)
    Листинг 6.5. Поиск товара в каталоге (Catalog.java) public Product getProduct( String id ) { Enumeration enum = productLines.elements(); while( enum.hasMoreElements() ) { ProductLine pl = (Product...
    Листинг 6.6. Удаление товара из каталога (Catalog.java)
    Листинг 6.6. Удаление товара из каталога (Catalog.java) public Product deleteProduct( String id ) { Enumeration enum = productLines.elements(); while( enum.hasMoreElements() ) { ProductLine pl = (...
    Листинг 6.7. Запись каталога в...
    Листинг 6.7. Запись каталога в виде документа XML (Catalog.java) public void toXML( XMLWriter writer ) throws IOException { writer.writeln( catalog ); writer.indent(); Enumeration enum = productLi...
    Класс XMLWriter
    Класс XMLWriter Класс XMLWriter — это служебный класс, используемый для записи выходных данных в формате XML. Этот класс записывает данные в выходной поток Output - Stream, который задается констр...
    Листинг 6.8. Начало кода для класса...
    Листинг 6.8. Начало кода для класса XMLWriter (XMLWriter.java) package com.XmlEcomBook.Chap06; import java.io.*; public class XMLWriter { static private final byte[] LINE_SEPARATOR = System.getPro...
    Листинг 6.9. Конструктор XMLWriter (XMLWriter.java)
    Листинг 6.9. Конструктор XMLWriter (XMLWriter.java) public XMLWriter( OutputStream newOut ) { out = newOut; } Вам необходимо иметь возможность регулировки размера отступа в тексте с выходными данн...
    Листинг 6.10. Регулировка размера отступа (XMLWriter.java)
    Листинг 6.10. Регулировка размера отступа (XMLWriter.java) public void indent() { currentIndent++; } public void unindent() { currentIndent--; } Наконец, необходимо осуществить фактическую запись...
    Листинг 6.11. Запись выходных данных (XMLWriter.java)
    Листинг 6.11. Запись выходных данных (XMLWriter.java) public void write( String s ) throws IOException { if( newLine ) { for( int i = 0; i currentIndent; i++ ) { out.write( INDENT ); } } out.write...
    Класс ProductLine
    Класс ProductLine Следующий класс, ProductLine, основан на определении DTD для элемента productline: !ELEMENT product_line (product*) !ATTLIST product_line name CDATA #IMPLIED Как и в элементе cat...
    Листинг 6.12. Начало кода класса...
    Листинг 6.12. Начало кода класса ProductLine (ProductLine.java) package com.XmlEcomBook.Chap06; import java.util.*; import java.io.*; import org.w3c.dom.*; public class ProductLine extends Object...
    Листинг 6.13. Конструкторы ProductLine (ProductLine.java)
    Листинг 6.13. Конструкторы ProductLine (ProductLine.java) public ProductLine() { } public ProductLine( Element element ) { name = element.getAttribute( name ); NodeList productNodes = element.getE...
    Листинг 6.14. Методы для получения...
    Листинг 6.14. Методы для получения и модификации элементов Product (ProductLine.java) public void addProduct( Product product ) { products.addElement( product ); } public Product deleteProduct( St...
    Листинг 6.15. Методы для получения...
    Листинг 6.15. Методы для получения и модификации имени элементов Product (ProductLine.java) public String getName(){ return name; } public void setName( String newName ) { name = newName; } Наконе...
    Листинг 6.16. Запись данных ProductLine...
    Листинг 6.16. Запись данных ProductLine в формате XML (ProductLine.java) public void toXML( XMLWriter writer ) throws IOException { writer.write( product_line ); if( name != null ) writer.write( n...
    Класс Product
    Класс Product Элемент product сложнее, чем элементы catalog и product_line, которые мы уже рассматривали. Ниже приводится DTD для этого элемента: !ELEMENT product (name.author*,artist*.description...
    Листинг 6.17. Начало кода класса Product (Product.java)
    Листинг 6.17. Начало кода класса Product (Product.java) package com.XmlEcomBook.Chap06; import java.io.*; import java.util.*; import java.text.*; import org.w3c.dom.*; public class Product { priva...
    Листинг 6.18. Конструкторы класса Product (Product.java)
    Листинг 6.18. Конструкторы класса Product (Product.java) public Product() { } public Product( Element productElement ) { id = productElement.getAttribute( id ); keywords = productElement.getAttrib...
    Листинг 6.19. Методы extractName...
    Листинг 6.19. Методы extractName, extractAuthors и extractArtists (Product.java) private void extractName( Element productElement ) { name = Util.extractTextFrom( name, productElement ); } private...
    Листинг 6.20. Метод extractDescription (Product.java)
    Листинг 6.20. Метод extractDescription (Product.java) private void extractDescription( Element productElement ) { NodeList desc = productElement.getElementsByTagName( description ); if( desc.getLe...
    Листинг 6.21. Метод extractPrice (Product.java)
    Листинг 6.21. Метод extractPrice (Product.java) private void extractPrice( Element productElement ) { String s = Util.extractTextFrom( price, productElement ); NumberFormat nf = NumberFormat.getCu...
    Листинг 6.22. Метод extractQuantitylnStock (Product.java)
    Листинг 6.22. Метод extractQuantitylnStock (Product.java) private void extractQuantityInStock( Element productElement ) { String s = Util.extractTextFrom ( quantity_in_stock, productElement ); qua...
    Листинг 6.23. Методы extractlmages...
    Листинг 6.23. Методы extractlmages и extractClips (Product.java) private void extractImages( Element productElement ) { NodeList descNode = productElement.getElementsByTagName( image ); for( int i...
    Листинг 6.24. Метод extractDate (Product.java)
    Листинг 6.24. Метод extractDate (Product.java) private void extractDate( Element productElement ) { NodeList date = productElement.getElementsByTagName( onsale_date ); if( date.getLength() 0 ) { o...
    Листинг 6.25. Методы getName и setName (Product.java)
    Листинг 6.25. Методы getName и setName (Product.java) public String getName() { return name; } public void setName( String newName ) { name = newName; } Поле authors относится к типу Vector, поэто...
    Листинг 6.26. Операции над элементами...
    Листинг 6.26. Операции над элементами Author и Artist (Product.java) public void addAuthor( String newAuthor ) { authors.addElement( newAuthor ); } public void removeAllAuthors() { authors.removeA...
    Листинг 6.27. Преобразование Product в XML (Product.java)
    Листинг 6.27. Преобразование Product в XML (Product.java) public void toXML( XMLWriter writer ) throws IOException { writer.write( product id=' + id + ' ); if( keywords != null ) writer.write( key...
    Класс Image
    Класс Image Очередной класс, который мы рассмотрим, — это класс Image. Он основан на следующем определении DTD: !ELEMENT image (caption?) !ATTLIST image format (gif|png|jpg) #REQUIRED width CDATA...
    Листинг 6.28. Начало кода класса Image (Image.java)
    Листинг 6.28. Начало кода класса Image (Image.java) package com.XmlEcomBook.Chap06; import java.io.*; import org.w3c.dom.*; public class Image { private String format; private Integer width; priva...
    Листинг 6.29. Конструкторы класса Image (Image.java)
    Листинг 6.29. Конструкторы класса Image (Image.java) public Image( Element imgElement) { format = imgElement.getAttribute( format ); width = Util.getInteger( imgElement.getAttribute( width ) ); he...
    Листинг 6.30. Преобразование Image в XML (Image.java)
    Листинг 6.30. Преобразование Image в XML (Image.java) public void toXML( XMLWriter writer ) throws IOException { writer.write( image ); writer.write( format=' + format + ' ); if( width != null ) w...
    Класс Clip
    Класс Clip Элемент clip очень похож на элемент image, что видно из его DTD: !ELEMENT clip (titie,description?) !ATTLIST clip format (mp3|mpeg|mov|rm) #REQUIRED length CDATA #IMPLIED size CDATA #IM...
    Листинг 6.31. Начало кода класса Clip (Clip.java)
    Листинг 6.31. Начало кода класса Clip (Clip.java) package com.XmlEcomBook.Chap06; import org.w3c.dom.*; import java.io.*; public class Clip extends Object { private String format; private String l...
    Листинг 6.32. Конструкторы класса Clip (Clip.java)
    Листинг 6.32. Конструкторы класса Clip (Clip.java) public Clip() { } public Clip( Element clipElement ) { format = clipElement.getAttribute( format ); length = clipElement.getAttribute( length );...
    Листинг 6.33. Преобразование класса Clip в XML (Clip.java)
    Листинг 6.33. Преобразование класса Clip в XML (Clip.java) public void toXML( XMLWriter writer ) throws IOException { writer.write( clip ); writer.write( format=' + format + ' ); if( length != nul...
    Класс DateTime
    Класс DateTime Класс DateTime используется для представления даты. Он основан на следующем фрагменте DTD: !ENTITY % date_time (day_of_week?.month?,day_of_month?, year?,(hour,minute,seconds?)?) !EL...
    Листинг 6.34. Начало кода класса...
    Листинг 6.34. Начало кода класса DateTime (DateTime.java) package com.XmlEcomBook.Chap06; import org.w3c.dom.Element; import java.util.StringTokenizer; import java.io.IOException; import java.io.O...
    Листинг 6.35. Метод fromString...
    Листинг 6.35. Метод fromString (DateTime.java) public void fromString( String newDate ) { StringTokenizer tokenizer = new StringTokenizer( newDate, ); while( tokenizer.hasMoreTokens() ) { String n...
    Листинг 6.36. Метод toXML (DateTime.java)...
    Листинг 6.36. Метод toXML (DateTime.java) public void toXML( XMLWriter writer ) throws IOException { writer.writeln( onsale_date ); writer.indent(); if( dayOfWeek != null ) writer.writeln( day_of_...
    Класс Util
    В классе Util имеется несколько удобных служебных методов, которые вызываются как из объекта данных, так и из классов представления. Все они являются открытыми и статическими, поэтому их можно выз...
    Листинг 6.37. Начало кода класса...
    Листинг 6.37. Начало кода класса Util и методы extractTextFrom и extractlntFrom (Util.java) package com.XmlEcomBook.Chap06; import org.w3c.dom.*; import java.io.*; public class Util { static publi...
    Листинг 6.38. Метод extractMarkupAsText...
    Листинг 6.38. Метод extractMarkupAsText (Util.java) static public String extractMarkupAsText( NodeList nodeList ) { //recursively extract String text = ; if( nodeList != null ) { for( int i = 0; i...
    Листинг 6.39. Методы notNull (Util.java)...
    Листинг 6.39. Методы notNull (Util.java) static public String notNull( String s ) { if( s == null ) { return ; } return s; } static public String notNull( Integer i ) { if( i == null ) { return ;...
    Листинг 6.40. Преобразование строки...
    Листинг 6.40. Преобразование строки в значение (Util.java) static public int getInt( String s ) { if( s == null || s.equals( ) ) { return 0; } return Integer.parseInt( s ); } static public Integer...
    Код для представления информации пользователю
    Теперь нам нужен код для представления пользователю всей информации, содержащейся в классах данных. Необходимо также обеспечить пользователю возможность создавать, редактировать и удалять элементы...
    Главная HTML-страница
    Главная HTML-страница На главной HTML-странице пользователю предлагаются три возможности: добавить товар, редактировать товар или удалить товар. Существует также возможность отменить все изменения...
    Листинг 6.41. Начало HTML-страницы...
    Листинг 6.41. Начало HTML-страницы (main.html) html headtitleCatalog Upkeep/title/head body Каждая из пяти операций, предложенных пользователю, представлена специальной формой на странице. Первую...
    Листинг 6.42. Форма для добавления...
    Листинг 6.42. Форма для добавления товара (main.html) form action=servlet/Main h3Add Product:/h3 input type=hidden name=operation value=add / Product ID:input name=productid / Product Line:input n...
    Листинг 6.43. Формы Delete Product...
    Листинг 6.43. Формы Delete Product и Edit Product (main.html) hr / form action=servlet/Hain h3Delete Product:/h3 input type=hidden name=operation value=delete / Product ID:input name=productid / i...
    Листинг 6.44. Формы Cancel All...
    Листинг 6.44. Формы Cancel All Changes и Save All Changes (main.html) hr / form action=servlet/Main input type=hidden name=operation value=refresh / input type=submit value=Cancel All Changes/ /fo...
    Класс Main сервлета
    Класс Main сервлета Класс Main сервлета, в котором обрабатывается информация, введенная пользователем на главной HTML-странице (main.html), показан в листинге 6.45. Центральной точкой входа в этот...
    Листинг 6.45. Начало кода класса...
    Листинг 6.45. Начало кода класса Main и метод doGet (Main.java) import java.io.*; import javax.servlet.*; import javax.servlet.http.*; import com.XmlEcomBook.Chap06.*; public class Main extends Ht...
    Листинг 6.46. Проверка ошибок...
    Листинг 6.46. Проверка ошибок во введенных параметрах (Main.java) String operation = req.getParameter(operation); String productID = req.getParameter(productid); String productLine = req.getParame...
    Листинг 6.47. Обработка различных...
    Листинг 6.47. Обработка различных операций (Main.java) if( operation.equals( add ) || operation.equals( edit ) ) { getServletContext().getRequestDispatcher (/Edit.jsp).forward(req, res); } if( ope...
    Листинг 6.48. Отображение страницы...
    Листинг 6.48. Отображение страницы (Main.java) private void outputPage( PrintWriter out, String title, String text ) { out.println(htmlheadtitle + title ); out.println(/title/headbody); out.printl...
    JSP-страница Delete
    Страница Del ete, представленная в листинге 6.49, устроена довольно просто. Вы получаете идентификатор товара из встроенного объекта request. Это тот же самый объект, который был адресован JSP-стр...
    Листинг 6.49. JSP-страница Delete...
    Листинг 6.49. JSP-страница Delete (Delete.jsp) %@ page import=com.XmlEcomBook.Chap06.* % % String pid = request.getParameter( productid ); Catalog catalog = (Catalog)session.getValue( catalog ); c...
    JSP-страница Edit
    Страница Edit гораздо длиннее и сложнее, чем страница Delete. Она должна генерировать форму, в которой содержатся все данные о товаре в таком виде, который позволяет пользователю редактировать эти...
    Листинг 6.50. Начало JSP-страницы...
    Листинг 6.50. Начало JSP-страницы Edit (Edit.jsp) %@ page import=com.XmlEcomBook.Chap06.* % %@ page import=java.util.* % % String pid = request.getParameter( productid ); String operation = reques...
    Листинг 6.51. Начало кода элементов...
    Листинг 6.51. Начало кода элементов HTML-страницы (Edit.jsp) html headtitle%= name %/title/head body h1%= name % Product/h1 form action=/servlet/UpdateProduct input name=productline type=hidden va...
    Листинг 6.52. Отображение названия...
    Листинг 6.52. Отображение названия товара и ключевых слов (Edit.jsp) table tr tdProduct ID/td td%= product.getId() %/td tdName/td tdinput name=name value=%= Util.notNull(product.getName()) % //td...
    Листинг 6.53. Отображение элементов...
    Листинг 6.53. Отображение элементов Author и Artist (Edit.jsp) % Enumeration authors = product.getAuthors(); for( int i = 0; authors.hasMoreElements(); i++ ) { out.print( outputAuthor( + i, (Strin...
    Листинг 6.54. Отображение цены...
    Листинг 6.54. Отображение цены, количества экземпляров, даты начала продаж и описания товара (Edit.jsp) trtdPrice/td tdinput name=price value=%= product.getPrice() % / /td tdDiscount/td tdinput na...
    Листинг 6.55. Отображение элементов...
    Листинг 6.55. Отображение элементов Image, Clip и кнопки Submit (Edit.jsp) trtdPrice/td tdinput name=price value=%= product.getPrice() % / /td tdDiscount/td tdinput name=discount value=%= Util.not...
    Листинг 6.56. Вывод объекта Image...
    Листинг 6.56. Вывод объекта Image (Edit.jsp) %! private String outputImage(String i, Image image) { String s; s = trtd + i + )/td; s += tdFormat/td; s += tdinput name='img + i + -format' value=' +...
    Листинг 6.57. Отображение объекта...
    Листинг 6.57. Отображение объекта Clip (Edit.jsp) %! private String outputClip( String i, Clip clip ) { String s; s = trtd + i + )/td; s += tdFormat/td; s += tdinput name='clip + i + -format' valu...
    Сервлет UpdateProduct
    Сервлет UpdateProduct вызывается из JSP-страницы Edit, когда пользователь заканчивает ввод в форму информации о товаре. Задача этого сервлета заключается в том, чтобы собрать данные из параметров...
    Листинг 6.58. Начало кода сервлета...
    Листинг 6.58. Начало кода сервлета UpdateProduct (UpdateProduct.java) import java.io.*; import javax.servlet.*; import javax.servlet.http.*; import com.XmlEcomBook.Chap06.*; public class UpdatePro...
    Листинг 6.59. Создание нового...
    Листинг 6.59. Создание нового объекта product, обновление ключевых слов и имени (UpdateProduct.java) if( product == null ) { //new product product = new Product(); product.setId( id ); String prod...
    Листинг 6.60. Добавление Author...
    Листинг 6.60. Добавление Author и Artist (UpdateProduct.java) product.removeAllAuthors(); for( int i = 0; getAuthor( + i, req, product ); i++ ) ;//do nothing getAuthor( New, req, product ); produc...
    Листинг 6.61. Добавление остальных...
    Листинг 6.61. Добавление остальных характеристик товара (UpdateProduct.java) String price = req.getParameter( price ); price = price.replace( '$', ' ' ); product.setPrice( Util.getDouble( price )...
    Листинг 6.62. Метод getAuthor (UpdateProduct.java)
    Листинг 6.62. Метод getAuthor (UpdateProduct.java) boolean getAuthor( String i, HttpServletRequest req, Product product ) { String author = req.getParameter( author + i ); if( author == null || au...
    Листинг 6.63. Методы getArtist...
    Листинг 6.63. Методы getArtist, getlmage и getClip (UpdateProduct.java) boolean getArtist( String i, HttpServletRequest req, Product product ) { String artist = req.getParameter( artist + i ); if(...









Начало