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

Классы Cartltem и ShoppingCart


Минимальным требованием к объекту, представляющему товар в корзине покупателя, является наличие идентификатора данного товара и количества заказанных экземпляров. Название товара, его цену и другие сведения можно найти в каталоге — документе XML. Но мы решили не ограничиваться минимальными требованиями и добавили в Cartltem название товара, цену и информацию по доставке, как показано в листинге 4.1.

Следует отметить несколько важных моментов, касающихся класса Cartltem. Во-первых, конструктор работает непосредственно с объектом El ement структуры DOM, представляющим данный товар. Это упрощает добавление различных дополнительных переменных в XML-каталог. Во-вторых, класс Cartltem реализует интерфейс Serializable. Это позволяет посылать коллекцию объектов Cartltem, представляющую собой список заказанных товаров, другой программе Java, используя сериализацию данных. Сериализация также требуется, если процессору сервлетов приходится хранить сеанс или пересылать его на другой сервер. Наконец, названия методов доступа, например getld и setNumberOrdered, соответствуют соглашению об именах, принятому в JavaBeans, чтобы упростить использование объекта Cartltem в коде JSP-страницы.

Листинг 4.1. Класс Cartltem (cartltem.java) [Все представленные в книге тексты программ можно найти на сайте издательства по адресу www.piter.com. — Примеч. ред. ]

package com.XmlEcomBook.catalog;

import java.util.* ;

import java.io.* ;

import org.xml.sax.* ;

import org.w3c.dom.* ;

public class CartItem implements java.io.Serializable

{ // be sure to change this if substantive variables change

static final long serialVersionUID = 3260689382642549142L;

// these are set from the constructor

private String id ; // from product element



private String name ; // from name element

private String price ; // from price element

private String shippingType ; // from shipping_info element

private String shippingValue ; // may be null if type is special

// these may change

private int numberOrdered ; // changes


public String getId(){ return id ;}

public String getName(){ return name ; }

public String getPrice() { return price ; }

public String getShippingType() { return shippingType ; }

public String getShippingValue() { return shippingValue ; }

public int getNumberOrdered(){ return numberOrdered ; }

public void setId(String s){ id = s ; }

public void setName(String s){ name = s; }

public void setPrice(String s){ price = s ;}

public void setShippingType(String s ){shippingType = s ;}

public void setShippingValue(String s) { shippingValue = s ;}

public void setNumberOrdered( int n ){ numberOrdered = n ;

System.out.println("setNumberOrdered " + n );

}

// needed for operation as a Bean

public CartItem(){

}

// constructor uses a <product> org.w3c.dom.Element

public CartItem( Element pe ){

id = pe.getAttribute("id");

NodeList nl = pe.getElementsByTagName( "name" );

name = nl.item(0).getFirstChild().getNodeValue() ;

nl = pe.getElementsByTagName( "price" );

price = nl.item(0).getFirstChild().getNodeValue() ;

nl = pe.getElementsByTagName( "shipping_info" );

Element ship = (Element) nl.item(0);

shippingType = ship.getAttribute("type");

shippingValue = ship.getAttribute("value"); // may be ""

}

// handy for debugging

public String toString() {

StringBuffer sb = new StringBuffer("CartItem name:");

sb.append( name ); sb.append(" numberOrdered: ");

sb.append( Integer.toString( numberOrdered ));

return sb.toString();

}

}

Класс ShoppingCart достаточно прост, так как все, что от него требуется, — манипулирование объектами класса Cartltem. Как показано в листинге 4.2, мы храним ссылки на объекты Cartltem в двух местах — Vector и HashTable. Причина этого заключается в том, что порядок размещения ссылок в объекте HashTable непредсказуем и может меняться по мере добавления новых товаров. Представляется разумным хранить эти ссылки в предсказуемой и воспроизводимой последовательности в объекте Vector и в то же время иметь возможность доступа к товарам по их идентификаторам через хэш-таблицу.



Заметим, что класс ShoppingCart реализует интерфейс Serializable, так что вся корзина (то есть объект класса Shoppi ngCart) может пересылаться между программами Java или записываться в файл посредством сериализации.



Листинг 4.2. Начало кода класса ShoppingCart (ShoppingCart.java)

package com.XmlEcomBook.catalog;

import java.io.*;

import java.util.* ;

public class ShoppingCart implements java.io.Serializable

{ private Vector items ; // maintains order of selection of items

private Hashtable itemsById ;

public ShoppingCart(){

items = new Vector();

itemsById = new Hashtable();

}

// items vector may be empty

public Vector getItems(){ return items ; }

// returns CartItem for this id or null if not in list

public CartItem getProdById(String s ){

return (CartItem) itemsById.get( s );

}

// CartItem is assumed to be unique

public int addItem( CartItem x ){

items.addElement( x );

itemsById.put( x.getId() , x );

return items.size();

}

В листинге 4.3 показаны остальные методы класса ShoppingCart. Поскольку мы храним ссылки на объекты Cartltem в двух коллекциях, для удаления элемента из объекта HashTable применяется метод removeByld с указанием идентификатора товара и затем вызывается метод removeEl eraent вектора items.



Листинг 4.3. Остальная часть кода класса ShoppingCart (ShoppingCart.java)

// remove an item from the cart by product id

public CartItem removeById( String s ){

CartItem ret = (CartItem)itemsById.get( s );

if( ret == null ) return null ;

itemsById.remove(s); // remove by key

items.removeElement( ret );

return ret ;

}

// remove all CartItem for which the numberOrdered is zero

// returns the count of items left

public int removeEmptyItems(){

Enumeration keys = itemsById.keys();

while( keys.hasMoreElements()){

String key = (String)keys.nextElement();

CartItem ci = (CartItem)itemsById.get(key);

if( ci.getNumberOrdered() == 0 ){

removeById( key );

}

}

return items.size();

}

// mainly for debugging

public String toString()

{ StringBuffer sb = new StringBuffer( "ShoppingCart has " +

items.size() + " items.\r\n" ) ;

Enumeration e = items.elements();

while( e.hasMoreElements()){

sb.append("Item: ");

sb.append( e.nextElement().toString() );

sb.append("\r\n");

}

return sb.toString();

}

}




Содержание раздела