“name”, “street”, “postal-code”, “locality”, “country”, “email” }return found == fields.length; } /** * save the order * @param request the request received from the client * @param resp
Trang 1“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 2writer = 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 3{MerchantCollection merchants = shop.getMerchants();
Merchant merchant = merchants.getMerchant(merchantid);
if(null != merchant)return merchant.getProduct(productid);
elsereturn null;
Trang 4Writer 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
Trang 5writer.write(“<FORM METHOD=\”POST\” ACTION=\””);
Trang 6protected void writeRow(String label,
String id,HttpServletRequest request,Writer writer)
throws IOException{
writer.write(“ VALUE=\””);
writer.write(value);
writer.write(“\””);
}writer.write(“></TD></TR>”);
}}Listing 12.13: HTTPPost.javapackage com.psol.xcommerce;
Trang 7public class HTTPPost{
/**
* properties
*/
protected URL url;
protected String query;
/**
* Creates a new HTTPPost
* @param url URL to connect to
* @parameters POST request parameter
* Creates a new HTTPPost
* @param url URL to connect to
* @parameters POST request parameter
* @exception MalformedURLException if the URL is invalid
*/
public HTTPPost(String url,Dictionary parameters)throws MalformedURLException
{this(new URL(url),parameters);
}
/**
* executes the post request
* @exception IOException error posting the data
*/
public void doRequest()throws IOException
continues
Trang 8{// this stupid thing does not default to 80
int port = url.getPort();
if(port == -1) port = 80;
Socket s = new Socket(url.getHost(),port);
PrintStream o = new PrintStream(s.getOutputStream());o.print(“POST “); o.print(url.getFile());
o.print(“ HTTP/1.0\r\n”);
o.print(“Accept: text/html text/xml\r\n”);
o.print(“Host: “); o.print(url.getHost()); o.print(“\r\n”);o.print(“Content-type: “);
o.print(“application/x-www-form-urlencoded\r\n”);
o.print(“Content-length: “); o.print(query.length());o.print(“\r\n\r\n”);
if(firstLine)if(c == ‘\r’ || c == ‘\n’)firstLine = false;
elsereply.append((char)c);
c = i.read();
}String stReply = reply.toString();
int returnCode = Integer.parseInt(stReply.substring(9,12));if(!(returnCode >= 200 && returnCode < 300))
throw new ProtocolException(stReply.substring(13)); }
/**
Listing 12.13: continued
Trang 9* format the request according to the proper encoding
* @param parameters query parameters
* @return string with the query properly formatted
*/
protected String buildQuery(Dictionary parameters){
StringBuffer request = new StringBuffer();
Enumeration keys = parameters.keys();
String key = null;
boolean first = true;
while(keys.hasMoreElements()){
if(!first)request.append(‘&’);
elsefirst = false;
}}
Encapsulating XML Tools
You use the DOM interface to encapsulate tools in XCommerce; however, there are holes in DOM In particular, there is no standard way to create or parse XML documents The XSL processor is even worse because it has no API at all.
The class XMLUtilencapsulates the vendor-specific part in the XML parser and XSL processor If you later decide to use another XML parser, XMLUtil
is the only class that needs updating XMLUtilis defined in Listing 12.14.
E X A M P L E
Trang 10Listing 12.14: XMLUtil.javapackage com.psol.xcommerce;
* XMLUtil isolates non-portable aspects of DOM, calling
* XSL processor and some utility functions.<BR>
* This version is for IBM’s XML for Java, to use another
* processor this is the only class to change
* parses a document with DOM
* @param systemID system id (URL) for the document
* @return DOM Document
* @exception ServletException error parsing the document
Trang 11public static Document parse(String systemID)throws ServletException
{try{DOMParser parser = new DOMParser();
parser.parse(systemID);
return parser.getDocument();
}catch(SAXException e){
throw new ServletException(e);
}catch(IOException e){
throw new ServletException(e);
}}
/**
* parses a document with DOM
* @param reader reader for the document
* @return DOM Document
* @exception ServletException error parsing the document
*/
public static Document parse(Reader reader)throws ServletException
{try{InputSource inputSource = new InputSource(reader);
DOMParser parser = new DOMParser();
parser.parse(inputSource);
return parser.getDocument();
}catch(SAXException e)
continues
Trang 12{throw new ServletException(e);
}catch(IOException e){
throw new ServletException(e);
}}
/**
* turns DOM tree in a string
* @param node root of the tree
case Node.ATTRIBUTE_NODE:
{Attr attr = (Attr)node;
{Document document = (Document)node;
Element topLevel = document.getDocumentElement();buffer.append(“<?xml version=\”1.0\”?>”);
buffer.append(toString(topLevel));
break;
Listing 12.14: continued
Trang 13}case Node.ELEMENT_NODE:
{Element element = (Element)node;
buffer.append(“<”);
buffer.append(element.getTagName());
NamedNodeMap attrs = element.getAttributes();
for(int i = 0;i < attrs.getLength();i++)buffer.append(toString(attrs.item(i)));
NodeList children = node.getChildNodes();
if(children.getLength() == 0)// shorthand for empty elementbuffer.append(“/>”);
else{buffer.append(“>”);
for(int i = 0;i < children.getLength();i++)buffer.append(toString(children.item(i)));
buffer.append(“</”);
buffer.append(element.getTagName());
buffer.append(“>”);
}break;
}case Node.TEXT_NODE:
{Text text = (Text)node;
buffer.append(text.getData());
break;
}default:
throw new NotImplementedError();
}return buffer.toString();
}
/**
continues
Trang 14* creates an empty DOM document
* @return DOM document
* creates a DOM document with a top-level element
* @param element top-level element
* @return DOM document
*/
public static Document createDocument(Element element){
Document document = createDocument();
Node celement = cloneNode(document,element);
document.appendChild(celement);
return document;
}
/**
* clone a DOM Node in the context of a Document<BR>
* Element.cloneNode() does not work when copying elements
* from one document to another, the clone remains attached
* to original document
* @param document document to attach the clone to
* @param node node to clone
* @return the clone
*/
public static Node cloneNode(Document document,
Node node){
// o = original// c = cloneswitch(node.getNodeType())Listing 12.14: continued
Trang 15{case Node.ATTRIBUTE_NODE:
{Attr o = (Attr)node,
c = document.createAttribute(o.getName());
c.setValue(o.getValue());
return c;
}case Node.ELEMENT_NODE:
{Element o = (Element)node,
c = document.createElement(o.getTagName());
NodeList children = o.getChildNodes();
for(int i = 0;i < children.getLength();i++){
Node n = cloneNode(document,children.item(i));
c.appendChild(n);
}NamedNodeMap attrs = o.getAttributes();
for(int i = 0;i < attrs.getLength();i++){
Attr a = (Attr)cloneNode(document,attrs.item(i));
c.setAttributeNode(a);
}return c;
}case Node.TEXT_NODE:
{Text o = (Text)node,
c = document.createTextNode(o.getData());
return c;
}default:
throw new NotImplementedError();
}}
continues
Trang 16* apply a style sheet and prints the result
* @param document original document
* @param xsl style sheet
* @param writer output writer
* @param encoding character encoding
*/
public static void transform(Document document,
Document xsl,PrintWriter writer,String encoding)throws ServletException
{XML4JLiaison4dom liaison = new XML4JLiaison4dom();
XSLTInputSource documentIn = new XSLTInputSource(document),
xslIn = new XSLTInputSource(xsl);
XSLTResultTarget result = new XSLTResultTarget(writer);try
{XSLProcessor xslProcessor = new XSLProcessor(liaison);xslProcessor.process(documentIn,xslIn,result);
}catch(Exception e){
throw new ServletException(e);
}}
/**
* retrieve elements in the children of a node<BR>
* it assumes no recursive structure, in other
* word in products/product/related/product,
* it would NOT find the second product
* @param element top of treeListing 12.14: continued
Trang 17* @param name element we are looking for
* @return an enumeration of the elements found
* retrieve the first element in the children of a node
* @param element top of tree
* @param name element we are looking for
* @return an enumeration of the elements found
*/
public static Element extractFirst(Element element,
String name){
Vector vector = new Vector();
extract(element,name,vector); // not optimizedif(vector.size() > 0)
return (Element)vector.firstElement();
elsereturn null;
}
/**
* helper method for extract
* @param node top of tree
* @param name element we are looking for
* @return an enumeration of the elements found
*/
protected static void extract(Node node,
String name,Vector vector)
continues
Trang 18{if(node.getNodeType() == Node.ELEMENT_NODE){
if(node.getNodeName().equals(name))// we stop, so it does not work with// recursive structures
vector.addElement(node);
else{NodeList children = node.getChildNodes();for(int i = 0;i < children.getLength();i++)extract(children.item(i),name,vector);}
}}
/**
* returns the text in the node
* @param node the node to read from
* @return the text in the node
NodeList children = node.getChildNodes();for(int i = 0;i < children.getLength();i++){
Node n = children.item(i);
if(n.getNodeType() == Node.TEXT_NODE){
Text t = (Text)n;
text.append(t.getData());
}}}Listing 12.14: continued
Trang 19return text.toString();
}
/**
* check if a string is empty
* @param string string to test
* @return true if empty, false otherwise
*/
public static boolean isEmpty(String string){
if(null != string)return string.trim().length() == 0;
elsereturn true;
}
/**
* Write the input in XML (or HTML) by escaping what
* must be escaped
* @param writer write on this
* @param string string to write
* @exception IOException error writing
*/
public static void writeInXML(Writer writer,String string)throws IOException
{for(int i = 0;i < string.length();i++){
char c = string.charAt(i);
if(c == ‘<’)writer.write(“<”);
else if(c == ‘&’)writer.write(“&”);
elsewriter.write(c);
}}}
Trang 20XMLUtilthrows a NotImplementedErrorexception when it hits something that is currently not implemented It is better to debug applications that clearly report their limits NotImplementedErroris defined in Listing 12.15
Listing 12.15: NotImplementedError.javapackage com.psol.xcommerce;
/**
* As the name implies, it signals that something is not yet
* implemented It is cleaner than hijacking some other error
* core In particular, it saves on debugging! No trying to
* figure out why something failed when it’s not there yet
* constructs a NotImplementedError with no specified detail message
*/
public NotImplementedError(){
super();
}
/**
* constructs a NotImplementedError with a detail message
* @param st detail message
*/
public NotImplementedError(String st){
super(st);
}}
Trang 21The Data Tier
Listing 12.16 shows the data tier for Emailaholic This data tier can ate a list of products in response to GETrequests It also accepts orders sent with POSTrequests For security purposes, the database username and password must be provided.
gener-Listing 12.16: XMLServer.javapackage com.psol.xcommerce;
* process GET request
* @param request HTTP request
* @param response hold the response
* @exception ServletException error processing the request
* @exception IOException error writing the result
E X A M P L E
continues
Trang 22protected void doGet(HttpServletRequest request,
HttpServletResponse response)throws ServletException, IOException
{response.setContentType(“application/xml”);
Writer writer = response.getWriter();
String sqlDriver = getInitParameter(“sql.driver”),sqlURL = getInitParameter(“sql.url”),sqlUser = getInitParameter(“sql.user”),sqlPassword = getInitParameter(“sql.password”),merchant = getInitParameter(“merchant”);
Connection connection =DriverManager.getConnection(sqlURL,
sqlUser,sqlPassword);
try{Statement stmt = connection.createStatement();
try{ResultSet rs =stmt.executeQuery(“select id, name, “ +
“manufacturer, img, warranty, “ +
“description, price from products”);
while(rs.next()){
writer.write(“<product id=\””);
writer.write(String.valueOf(rs.getInt(1)));
writer.write(“\” xmlns:em=\”http://www.emailaholic”);Listing 12.16: continued
Trang 23}}catch(ClassNotFoundException e){
throw new ServletException(e);
}catch(SQLException e){
throw new ServletException(e);
}writer.write(“</products>”);
writer.flush();
}
continues
Trang 24* process POST request
* @param request HTTP request
* @param response hold the response
* @exception ServletException error processing the request
* @exception IOException error writing the result
*/
protected void doPost(HttpServletRequest request,
HttpServletResponse response)throws ServletException, IOException
{// there is no error checking at all// if incorrect, throws an exception:
// it goes to a computer so it’s for technicians anywayString sqlDriver = getInitParameter(“sql.driver”),sqlURL = getInitParameter(“sql.url”),sqlUser = request.getParameter(“user”),sqlPassword = request.getParameter(“password”),xmlData = request.getParameter(“xmldata”);
Reader reader = new StringReader(xmlData);
Document orderDocument = XMLUtil.parse(reader);
Element orderElement = orderDocument.getDocumentElement(),
buyerElement =XMLUtil.extractFirst(orderElement,”buyer”),productElement =
XMLUtil.extractFirst(orderElement,”product”);String name = buyerElement.getAttribute(“name”),
street = buyerElement.getAttribute(“street”),region = buyerElement.getAttribute(“region”),postal_code =
buyerElement.getAttribute(“postal-code”),locality = buyerElement.getAttribute(“locality”),country = buyerElement.getAttribute(“country”),email = buyerElement.getAttribute(“email”),productid = productElement.getAttribute(“id”),productname = productElement.getAttribute(“name”),Listing 12.16: continued
Trang 25productprice = productElement.getAttribute(“price”),productquantity =
productElement.getAttribute(“quantity”);
try{Class.forName(sqlDriver);
Connection connection =DriverManager.getConnection(sqlURL,
sqlUser,sqlPassword);
try{PreparedStatement stmt =connection.prepareStatement(
“insert into orders (name,street,region,” +
stmt.setString(11,productquantity);
stmt.executeUpdate();
connection.commit();
continues
Trang 26}}finally{connection.close();
}}catch(ClassNotFoundException e){
throw new ServletException(e);
}catch(SQLException e){
throw new ServletException(e);
}catch(ParseException e){
throw new ServletException(e);
}response.setStatus(HttpServletResponse.SC_OK);
Listing 12.17 is XMLServerConsole, a simple management interface for the database.
Listing 12.16: continued