* @author Benoît Marchal */ public class Shopextends HttpServlet{ /** * the merchant list and the shopping cart */ protected MerchantCollection merchants; protected Comlet checkout; merc
Trang 1Figure 12.1: Creating the Data Source in ODBC
Before you can use the XML server, you need to create the database schema and insert a few products in the database This is what XMLServerConsoleis for Point your browser to localhost:81/console First click Create Tables, (see Figure 12.2) Enter the product information, as shown in Figure 12.3
Figure 12.2: Creating the database schema
Trang 2Figure 12.3: Creating products in the database
The Middle Tier
As explained in Chapter 11, “N-Tiered Architecture and XML,” the middle tier server is a servlet that manages various XML documents There is a document for the list of merchants or another for the list of products, and more The servlet applies style sheets to them.
The middle tier server is made of the Shopclass, shown in Listing 12.5.
Shopdecodes the URL and routes the requests to the appropriate object.
Listing 12.5: Shop.javapackage com.psol.xcommerce;
Trang 3* @author Benoît Marchal <bmarchal@pineapplesoft.com>
*/
public class Shopextends HttpServlet{
/**
* the merchant list and the shopping cart
*/
protected MerchantCollection merchants;
protected Comlet checkout;
merchants = new MerchantCollection(this);
checkout = new Checkout(this);
}
/**
* handle GET request
* @param request the request received from the client
* @param response interface to the client
* @exception IOException error writing the reply
* @exception ServletException error in processing the request
*/
continues
Trang 4protected void doGet(HttpServletRequest request,
HttpServletResponse response)throws IOException, ServletException
{Comlet comlet = translateURL(request);
if(null != comlet)comlet.doGet(request,response);
elseresponse.sendError(HttpServletResponse.SC_NOT_FOUND); }
/**
* handle POST request
* @param request the request received from the client
* @param response interface to the client
* @exception IOException error writing the reply
* @exception ServletException error in processing the request
*/
protected void doPost(HttpServletRequest request,
HttpServletResponse response)throws IOException, ServletException
{Comlet comlet = translateURL(request);
if(null != comlet)comlet.doPost(request,response);
elseresponse.sendError(HttpServletResponse.SC_NOT_FOUND);}
/**
* Returns the time it was last modified
* @param request the request received from the client
* @return time in milliseconds since January 1, 1970 midnight
*/
protected long getLastModified(HttpServletRequest request) {
tryListing 12.5: continued
Trang 5{Comlet comlet = translateURL(request);
if(null != comlet)return comlet.getLastModified();
elsereturn -1;
}catch(ServletException e){
return -1;
}}
/**
* decode the URL and select the Comlet that will
* handle the request
* @param request the request received from the client
* @return the Comlet identified in the request
* @exception problem loading one of the object
*/
protected Comlet translateURL(HttpServletRequest request) throws ServletException
{String merchantID = null,pathInfo = request.getPathInfo();
StringTokenizer tokenizer = null;
if(null != pathInfo){
tokenizer = new StringTokenizer(pathInfo,”/”);
if(tokenizer.hasMoreTokens())merchantID = tokenizer.nextToken();
}if(null == merchantID)return merchants;
if(merchantID.equals(“checkout”))return checkout;
Merchant merchant = merchants.getMerchant(merchantID);
continues
Trang 6String productID = null;
if(tokenizer.hasMoreTokens())productID = tokenizer.nextToken();
if(null == merchant || null == productID)return merchant;
elsereturn merchant.getProduct(productID);
}}
The objects that really handle the request are derived from Comlet, defined
in Listing 12.6 Comletdefines methods for the GETand POSTrequests.
Listing 12.6: Comlet.javapackage com.psol.xcommerce;
* Comlet is a subset of the servlet interface, Shop
* delegates HTTP requests to Comlet descendants
/**
* properties
*/
protected ServletConfig servletConfig;
protected long lastModified = -1;
protected Shop shop;
Listing 12.5: continued
Trang 7* creates a new Comlet
* @param shop the shop it is part of
* convenience: implements ServletConfig
* @param name the parameter whose value is requested
* @return the parameter value
Trang 8* convenience: implements ServletConfig
* @return an enumeration of names
* convenience: implements ServletConfig
* @return the config object
* handle GET request
* @param request the request received from the client
* @param response interface to the client
* @exception IOException error writing the reply
* @exception ServletException error in processing the request
*/
public void doGet(HttpServletRequest request,
HttpServletResponse response)throws IOException, ServletException
{response.sendError(HttpServletResponse.SC_BAD_REQUEST);}
/**
* handle POST request
* @param request the request received from the client
* @param response interface to the client
* @exception IOException error writing the reply
* @exception ServletException error in processing the requestListing 12.6: continued
Trang 9public void doPost(HttpServletRequest request,
HttpServletResponse response)throws IOException, ServletException
{response.sendError(HttpServletResponse.SC_BAD_REQUEST);
MerchantCollection URLs in the form /shopare handled by MerchantCollection, which man- ages a list of merchants in XML See Listing 12.7 Listing 12.8 is the list of merchants and Listing 12.9 is the style sheet.
Listing 12.7: MerchantCollection.javapackage com.psol.xcommerce;
Trang 10* properties
*/
protected Dictionary merchants = new Hashtable();
protected Document merchantsDocument = null,
merchantsXSL = null;
/**
* creates a new Merchant object
* @param shop the shop it is part of
* @param ServletException error reading the merchant list
*/
public MerchantCollection(Shop shop)throws ServletException
{super(shop);
String fname = getInitParameter(“merchants.xml”);
if(null != fname)merchantsDocument = XMLUtil.parse(fname);
if(null == merchantsDocument)throw new UnavailableException(shop,”merchants.xml”);freshened();
Element topLevel = merchantsDocument.getDocumentElement();Enumeration enumeration =
XMLUtil.extract(topLevel,”merchant”);
while(enumeration.hasMoreElements()){
Listing 12.7: continued
Trang 11Element element =(Element)enumeration.nextElement();
Merchant merchant =new Merchant(element,shop);
merchants.put(merchant.getID(),merchant);
}}
* return the style sheet for the list of merchants
* @exception ServletException error reading the document
*/
protected Document getXSL()throws ServletException{
if(null == merchantsXSL){
String fname = getInitParameter(“merchants.xsl”);
if(null != fname)merchantsXSL = XMLUtil.parse(fname);
}return merchantsXSL;
Trang 12{return (Merchant)merchants.get(id);
}
/**
* handle GET request
* @param request the request received from the client
* @param response interface to the client
* @exception IOException error writing the reply
* @exception ServletException error in processing the request
*/
public void doGet(HttpServletRequest request,
HttpServletResponse response)throws IOException, ServletException
{XMLUtil.transform(getDocument(),
getXSL(),response.getWriter(),response.getCharacterEncoding());}
}Listing 12.8: Merchants.xml
<description>The largest electronic shop
All products delivered via email!</description>
<products update=”3600”
href=”http://localhost:81/xml”/>
Listing 12.7: continued
Trang 13<stylesheethref=”http://localhost:81/product.xsl”/>
E X A M P L E
Trang 14Listing 12.10: Merchant.javapackage com.psol.xcommerce;
/**
* properties
*/
protected Element merchantElement;
protected Dictionary products = null;
protected Document productsDocument = null,
productsXSL = null,productXSL = null;
protected String id;
protected long expire = Long.MAX_VALUE;
/**
* creates a new Merchant object
* @param element the merchant element
* @param shop the shop it is part of
*/
public Merchant(Element element,Shop shop){
super(shop);
Trang 15if(null != postElement)return postElement.getAttribute(“href”);
elsereturn null;
if(null != postElement)return postElement.getAttribute(“user”);
elsereturn null;
}
continues
Trang 16return postElement.getAttribute(“password”);
elsereturn null;
}
/**
* return the list of products
* @exception ServletException error reading the document
*/
protected Document getDocument()throws ServletException{
if(null == productsDocument ||
expire < System.currentTimeMillis()){
Element productsElement =XMLUtil.extractFirst(merchantElement,”products”);if(null != productsElement)
{String fname =productsElement.getAttribute(“href”);
String update =productsElement.getAttribute(“update”);if(!XMLUtil.isEmpty(fname))
{productsDocument = XMLUtil.parse(fname);freshened();
productXSL = null;
productsXSL = null;
Listing 12.10: continued
Trang 17long u = Long.parseLong(update) * 1000;
expire = System.currentTimeMillis() + u;
}}}return productsDocument;
}
/**
* return the style sheet for a list of products
* @exception ServletException error reading the document
*/
protected Document getXSL()throws ServletException{
if(null == productsXSL) {
Element productsXSLElement =XMLUtil.extractFirst(merchantElement,
“stylesheet-all”);
if(null != productsXSLElement){
String fname = productsXSLElement.getAttribute(“href”);
if(!XMLUtil.isEmpty(fname))productsXSL = XMLUtil.parse(fname);
}}return productsXSL;
}
/**
* return the style sheet for one product
* @exception ServletException error reading the document
continues
Trang 18public Document getProductXSL()throws ServletException{
if(null == productXSL) {
Element productXSLElement =XMLUtil.extractFirst(merchantElement,”stylesheet”);if(null != productXSLElement)
{String fname =productXSLElement.getAttribute(“href”);
if(!XMLUtil.isEmpty(fname))productXSL = XMLUtil.parse(fname);
}}return productXSL;
}
/**
* return a given product
* @param id product index
*/
public Product getProduct(String id)throws ServletException
{if(null == products ||
expire < System.currentTimeMillis()){
Document productsDocument = getDocument();
if(null != productsDocument) {
Element topLevel =productsDocument.getDocumentElement();
Enumeration enumeration =XMLUtil.extract(topLevel,”product”);
products = new Hashtable();
Listing 12.10: continued
Trang 19Element element =(Element)enumeration.nextElement();
Product product =new Product(element,this,shop);
products.put(product.getID(),product);
}}}// re-test: reading the product may failif(null != products)
return (Product)products.get(id);
elsereturn null;
}
/**
* handle GET request
* @param request the request received from the client
* @param response interface to the client
* @exception IOException error writing the reply
* @exception ServletException error in processing the request
*/
public void doGet(HttpServletRequest request,
HttpServletResponse response)throws IOException, ServletException
{XMLUtil.transform(getDocument(),
getXSL(),response.getWriter(),response.getCharacterEncoding());
}}
Trang 20Product Requests for a specific product take the form /shop/xmli/1 They are forwarded to Productobjects, as shown in Listing 12.11.
Listing 12.11: Product.javapackage com.psol.xcommerce;
/**
* properties
*/
protected Element productElement;
protected Document productDocument;
protected Merchant merchant;
/**
* creates a new product
* @param element XML description of the product
* @param merchant merchant owning this product
* @param shop the shop it is part of
*/
public Product(Element element,
Merchant merchant,Shop shop)
{
Trang 21return XMLUtil.getText(nameElement);
continues
Trang 22productDocument = XMLUtil.createDocument(productElement);Element element = productDocument.getDocumentElement();element.setAttribute(“merchant”,merchant.getID());}
return productDocument;
}
/**
* handle GET request
* @param request the request received from the client
* @param response interface to the client
* @exception IOException error writing the reply
* @exception ServletException error in processing the request
*/
public void doGet(HttpServletRequest request,
HttpServletResponse response)throws IOException, ServletException
{Listing 12.11: continued
Trang 23merchant.getProductXSL(),response.getWriter(),response.getCharacterEncoding());
Checkout Listing 12.12 handles requests to check out of the shop, which is used for purchases Checkoutcollects information about the buyer and creates an order in XML The order is either saved as a local file or posted to the mer- chant Web server Posting to a remote site is done through HTTPPost, defined in Listing 12.13.
Listing 12.12: Checkout.javapackage com.psol.xcommerce;
Trang 24public class Checkoutextends Comlet{
/**
* creates a new Checkout object
* @param shop the shop it is part of
* handle POST request
* @param request the request received from the client
* @param response interface to the client
* @exception IOException error writing the reply
* @exception ServletException error in processing the request
*/
public void doPost(HttpServletRequest request,
HttpServletResponse response)throws ServletException, IOException
{if(isAddressComplete(request))doSaveOrder(request,response);
elsedoCollectData(request,response);
}
/**
* return true if the address is complete
* @param request client request
Trang 25“name”, “street”, “postal-code”,
“locality”, “country”, “email”
}return found == fields.length;
}
/**
* save the order
* @param request the request received from the client
* @param response interface to the client
* @exception IOException error writing the reply
* @exception ServletException error in processing the request
*/
public void doSaveOrder(HttpServletRequest request,
HttpServletResponse response)throws ServletException, IOException
{String productid = request.getParameter(“product”),merchantid = request.getParameter(“merchant”);
Product product = getProduct(merchantid,productid);
if(null == product){
response.sendError(HttpServletResponse.SC_NOT_FOUND);
return;
}Merchant merchant = product.getMerchant();
String postURL = merchant.getPostURL();
Writer writer = null;
if(null != postURL)
continues
Trang 26writer = new StringWriter();
else{String directory = getInitParameter(merchant.getID()
+ “.orders”),// should be enough to avoid duplicatesfname = String.valueOf(System.currentTimeMillis())
+ “.xml”;
File file = new File(directory,fname);
writer = new FileWriter(file);
}writer.write(“<?xml version=\”1.0\”?>”);
Dictionary parameters = new Hashtable();
String user = merchant.getPostUser(),password = merchant.getPostPassword(),Listing 12.12: continued
Trang 27{MerchantCollection merchants = shop.getMerchants();
Merchant merchant = merchants.getMerchant(merchantid);
if(null != merchant)return merchant.getProduct(productid);
elsereturn null;
Trang 28Writer writer)throws IOException
{String value = request.getParameter(id);
if(!XMLUtil.isEmpty(value)){
/**
* collect buyer data
* @param request the request received from the client
* @param response interface to the client
* @exception IOException error writing the reply
* @exception ServletException error in processing the request
*/
public void doCollectData(HttpServletRequest request,
HttpServletResponse response)throws ServletException, IOException
{String productid = request.getParameter(“product”),merchantid = request.getParameter(“merchant”),quantity = request.getParameter(“quantity”);Product product = getProduct(merchantid,productid);
if(null == product){
response.sendError(HttpServletResponse.SC_NOT_FOUND);return;
}Writer writer = response.getWriter();
writer.write(“<HTML><HEAD><TITLE>Checkout</TITLE></HEAD>”);writer.write(“<BODY><P>Enter your name and address:”);Listing 12.12: continued