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

Гибкость содержимого


Чтобы добиться гибкости внутреннего содержимого страницы, мы собираемся использовать форматирующий класс с именем ProductFormatter Этот класс выдает данные элемента XML product в формате, задаваемом с помощью списка имен полей, которому сопоставлен список стилей, применяемых к тексту каждого поля.

В качестве простого примера рассмотрим следующую ситуацию: для каждого товара требуется отобразить на странице его название в формате ch3 и цену в формате ch4. Для этого мы определяем два массива типа String:

Stnng[] elem = { "prname", "price" };

String[] shortSt = { "ch3", "ch4"

Также мы хотим, чтобы имя каждого товара было представлено в виде ссылки, щелчок на которой вызывает отображение полной информации о данном товаре. Для этого строковой переменной alink присваивается соответствующее значение, наподобие следующего:

"http://localhost/servlet/cattest?action=showproduct"

Также нам надо определить целочисленную переменную типа int с именем linkN, содержащую индекс (номер) поля, которое должно стать ссылкой. В нашем случае linkN0, так как такой ссылкой должно быть имя элемента (название товара). Когда эти параметры установлены, метод doOutput, приведенный в листинге 3.11, может форматировать данные для конкретного товара (элемента product), содержащиеся в документе XML catalog.xml. В результате выполнения метода doOutput получается строка, которую уже можно вставлять в HTML-страницу.

Листинг 3.11. Метод doOutput (productFormatter.java)

public String doOutput( Element el ){

StringBuffer sb = new StringBuffer( );

String pid = null ;

if( aLink != null ){



pid = "&id=" + el.getAttribute("id") ;

System.out.println("pid is " + pid );

}

else { System.out.println("aLink null");

}

for( int i = 0 ; i < elem.length ; i++ ){

if( i == linkN && pid != null ){

sb.append( "<a class=\"" );

sb.append( style[i] );

sb.append("\" href=\"");


sb.append( aLink );

sb.append( pid );

sb.append("\">");

addText( sb, elem[i], el );

sb.append( " </a>");

}

else {

sb.append( "<span class=\"");

sb.append( style[i] ); sb.append("\">");

addText( sb, elem[i], el );

sb.append( " </span>");

}

}

return sb.toString();

}

Например, для элемента product, данные о котором приведены в листинге 3.12, в результате выполнения метода doOutput получится следующая строка:

<а class="ch3" href= "http //localhost/servlet/cattest?action=showproduct">

Guide to Plants </a> <span class="ch4">price ea = $12 99 </span>



Листинг 3.12. Описание отдельного товара (элемента product) из каталога catalog.xml

<product id="bk0022" keywords='gardening, plants">

<name>Guide to Plants</name>

<description>

<paragraph>

<italics>Everything</italics>

you've ever wanted to know about plants.

</paragraph>

</description>

<price>$12 99</price>

<quantity_in_stock>4</quantity_in_stock>

<image format="gif" width="234" height="400" src="images/covers/plantsvl gif">

<caption>

<paragraph>This is the cover from the first edition </paragraph>

</caption>

</image>

<onsale_date>

<month>4</month>

<day_of_month>4</day_of_month>

<year>1999</year>

</onsale_date>

<shipping_infо type="UPS" value="l.0" />

</product>

До сих пор мы занимались форматированием данных для одного товара Теперь посмотрим, как создать на странице список товаров со ссылками на их полные описания В классе CatalogBean имеется массив ссылок на элементы с именем selected Метод setlmtialSelected (листинг 3 13) устанавливает, что будет содержаться в этом массиве — либо полный список всех товаров, либо список товаров какой-либо одной серии





Листинг 3.13. Метод setlmtialSelected из CatalogBean (CatalogBean.java)

public boolean setInitialSelect(String s){

boolean ret = false ;

if( s.equals("all") ){

selected = cat.getAllProduct(); ret = true ;

}

else {

selected = cat.getProductsByPL( s );

if( selected != null ) ret = true ;

else {

System.out.println("not working yet");

}

}

return ret ;

}

public String doOutput( int n ){

return pf.doOutput( selected[n] );

}

В классе Catal ogBean имеется также метод doOutput, который просто вызывает метод doOutput класса ProductFormatter Элемент (товар), к которому применяется последний метод, указывается как n-й элемент массива selected:

public String doOutput( int n ){

return pf doOutput( selected[n] );

}

Теперь мы можем объединить все написанные нами компоненты для создания форматированной HTML-страницы, отображающей весь каталог. В листинге 3 14 приведен метод сервлета doPost, который устанавливает заголовок страницы, затем создает теги <head> и <title>, за которыми следует строка, содержащая тег <link> для связывания HTML-страницы с таблицей стилей. Затем следует тег <boby> и вызывается метод completeCatalog Далее пишутся закрывающие теги и закрывается выходной поток PnntWnter



Листинг 3.14. Метод doPost сервлета, отображающий весь каталог (CatalogTestServ.java)

public void doPost(HttpServletRequest req, HttpServletResponse resp)

throws ServletException, IOException

{

resp.setContentType("text/html");

PrintWriter out = new PrintWriter(resp.getOutputStream());

String action = req.getParameter("action");

out.println("<html>");

out.println("<head><title>CatalogTestServ Output</title>");

out.println( cssLink );

out.println("</head>\r\n<body>");

try {

if( "showcatalog".equals( action )){

completeCatalog( out );

}

else if( "selectkeyword".equals( action )){

doKeywordSelect( out );

}



}catch( Exception e ){

e.printStackTrace( out );

}

out.println("</body>");

out.println("</html>");

out.close();

}

Как показано в листинге 3.15, метод completeCatalog использует теги HTML для создания таблицы с тремя столбцами. Каждый столбец заполняется информацией о товарах одной из серий, причем данные по каждому из товаров форматируются методом doOutput, приведенным в листинге 3.11.



Листинг 3.15. Метод completeCatalog для создания полного каталога товаров (CatalogTestServ.java)

public void completeCatalog( PrintWriter out ){

CatalogBean cb = new CatalogBean();

out.println("<h2>Complete Catalog</h2>");

out.println("<table width=\"90%\" border=\"3\" align=\"center\" >");

out.println("<thead><tr><th>Books</th><th>CDs</th> <th>Gadgets</th>" + "</tr></thead>");

out.println("<tbody><tr valign=\"top\"><td>");

String link = alias + "?action=showproduct" ;

cb.setInitialSelect("Books");

int ct = cb.getSelectedCount();

out.println("We have " + ct + " titles." + brcrlf );

cb.setOutput("short", link);

for( int i = 0 ; i < ct ; i++ ){

out.println( cb.doOutput(i) );

out.println( brcrlf );out.println( brcrlf );

}

out.println("</td><td>");

cb.setInitialSelect("CDs");

ct = cb.getSelectedCount();

out.println("We have " + ct + " CD titles." + brcrlf );

cb.setOutput("short", link);

for( int i = 0 ; i < ct ; i++ ){

out.println( cb.doOutput(i) );

out.println( brcrlf );out.println( brcrlf ); }

out.println("</td><td>");

cb.setInitialSelect("widgets");

ct = cb.getSelectedCount();

out.println("We have " + ct + " kinds." + brcrlf );

cb.setOutput("short", link );



for( int i = 0 ; i < ct ; i++ ){

out.println( cb.doOutput(i) );

out.println( brcrlf );out.println( brcrlf );

}

out.println("</td></tr></table>");

}

В листинге З 16 приводится текст первой части получившейся HTML-страницы Обратите внимание, что многие строки разбиты на несколько частей, чтобы поместиться на страницу книги Несмотря на использование таблицы стилей, экономящей память, вся страница полностью занимает 17 213 байт



Листинг 3.16. Первая часть генерируемой сервлетом HTML-страницы

<html>

<head><title>CatalogTestServ Output</title>

<link rel="stylesheet" href= "http //localhost/XmlEcommBook/catalog.css" type="text/css" media="screen" >

</head>

<body>

<h2>Complete Catalog</h2>

<table width="90%" border="3" align='center" >

<thead><tr><th>Books</th><th>CDs</th>

<th>Gadgets</th></tr></thead>

<tbodyxtr valign="top"><td>

We have 28 titles <br />

<a class="ch3" href= "http //Iocalhost/servlet/cattest?action=showproduct">

Guide to Plants </a> <span class= "ch4">price ea = $12.99 </span>

<br />

<br />

<a class="ch3" href= "http //localhost/servlet/cattest?action=showproduct">

Guide to Plants, Volume 2 </a> <span class= "ch4">price ea = $12.99 </span>

<br />

<br />

<a class="ch3" href= "http //Iocalhost/servlet/cattest?action=showproduct" >

The Genius's Guide to the 3rd Millenium </a>

<span class= "ch4'>price ea = $59.95 </span>

<br />

Конечный результат наших усилий — отображенная в браузере HTML-страница с каталогом товаров (рис 32)





Рис. 3.2. Отображение каталога товаров

В следующей главе мы расскажем, как можно расширить функциональность классов CatalogBean и ProductFormatter для создания представлений, необходимых при работе с корзиной покупателя.


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