------------------------------------------------------------------------------------- package com.conway; import java.io.*; import java.net.*; import java.text.SimpleDateFormat; // Imports required for using JDOM import org.jdom.*; import org.jdom.input.SAXBuilder; import org.jdom.output.*; import org.jdom.xpath.XPath; // These are needed by JDOM for XPath processing. // Add these jars to your classpath - they come with JDOM: // jaxen-core.jar, jaxen-jdom.jar, saxpath.jar import org.jaxen.*; import org.jaxen.jdom.*; import org.saxpath.*; /** * Sample Java code for Con-way XML Bill of Lading * @author Web Customer Support * * REQUIRES: JDOM 1.0 which can be downloaded from http://jdom.org * JDOM provides a helpful abstraction layer for working with with XML within Java * * TODO: replace the USERNAME and PASSWORD String values in variables below * with your Con-way username and password * * Send questions to Con-way XML Support at web.support@Con-way.com */ public class XmlBol { // TODO: replace the USERNAME and PASSWORD String values in variables below // These could also be read in from a properties file private final static String username = "USERNAME"; private final static String password = "PASSWORD"; public final static String requestType = "BOLrequest"; public final static String responseType = "BOLresponse"; public final static String servletUri = "XMLj/X-BOL"; public final static String conwayUrl = "https://www.Con-way.com/"; public final static String postUrl = conwayUrl + servletUri; public final static String today = new SimpleDateFormat("MM/dd/yy").format(new java.util.Date()); // JDOM Builder to create JDOM document from HTTP POST response SAXBuilder saxb = new SAXBuilder(); // Create JDOM document for the Request XML Document inJdomDoc = new Document(new org.jdom.Element(requestType)); // Create JDOM document for the Response XML Document outJdomDoc = new Document(new org.jdom.Element(responseType)); Element inRootEl = inJdomDoc.getRootElement(); Element outRootEl = outJdomDoc.getRootElement(); XMLOutputter xmlOut = new XMLOutputter(Format.getPrettyFormat()); String xmlInput = null; XPath xpath = null; boolean error, success; /** * main() is here to demonstrate how to use this class. * In actual practice you may choose to have the main() * in another class which instantiates this class and * invokes its methods * * @param args java.lang.String[] */ public static void main(String[] args) { // Use this String array for the value you wish to retrieve from the response String[] respElements = {"Shipment","Status"}; /* For this sample code, we will simply hard code some dummy data. * In real practice, you could pass in the values in the String array arguments * and then use JDOM to build the input XML */ String xmlInString = "<BOLrequest testmode=\"Y\">" + "<RequesterUserId shipcode=\"S\">" + username + "</RequesterUserId>" + "<ChargeCode>P</ChargeCode>" + "<PRONmbr></PRONmbr>" + "<CustRefNmbrs>" + "<PurchaseOrderNmbr>3338889</PurchaseOrderNmbr>" + "<PurchaseOrderNmbr>3338890</PurchaseOrderNmbr>" + "<OtherRefNmbr refcode=\"SKU\" refdesc=\"SKU Number\">3213A</OtherRefNmbr>" + "<OtherRefNmbr refcode=\"UPC\" refdesc=\"UPC number\">789283</OtherRefNmbr>" + "</CustRefNmbrs>" + "<Shipper>" + "<ShipperName>Alan Shipley</ShipperName>" + "<ShipperAddr>1234 NE Main</ShipperAddr>" + "<ShipperCity>Portland</ShipperCity>" + "<ShipperState>OR</ShipperState>" + "<ShipperZip country=\"US\">97202</ShipperZip>" + "<ShipperPhone extension=\"6055\">503.450.6055</ShipperPhone>" + "<ShipperEmail>web.support@Con-way.com</ShipperEmail>" + "</Shipper>" + "<Consignee>" + "<ConsigneeCustNmbr>883885</ConsigneeCustNmbr>" + "<ConsigneePhone extension=\"6666\">503.450.6436</ConsigneePhone>" + "<ConsigneeEmail>web.support@Con-way.com</ConsigneeEmail>" + "</Consignee>" + "<Item>" + "<Quantity pkgtype=\"PLT\">44</Quantity>" + "<Weight unit=\"lbs\">667</Weight>" + "<Description>widget-arms</Description>" + "<CmdtyClass>775</CmdtyClass>" + "<NMFClass></NMFClass>" + "<HazMat>N</HazMat>" + "</Item>" + "<Accessorial chargecode=\"C\">DID</Accessorial>" + "<Accessorial chargecode=\"C\">DST</Accessorial>" + "<ShippingRemarks>TEST TEST TEST</ShippingRemarks>" + "<EmergencyContact></EmergencyContact>" + "<PickupRequest>" + "<PickupDate>" + today + "</PickupDate>" + "<PickupReadyTime>4:00 pm</PickupReadyTime>" + "<DockCloseTime>7:00 pm</DockCloseTime>" + "<ContactName>Frank</ContactName>" + "<ContactCompany>Franklin Arms</ContactCompany>" + "<ContactPhone>(333)444-4321</ContactPhone>" + "</PickupRequest>" + "<SendBOLemail/>" + "</BOLrequest>"; // Instantiate a ConwayXml object with the String argument XmlBol myConwayXml = new XmlBol(xmlInString); // Report success System.out.println("XML Request success = " + myConwayXml.isSuccess()); // Use object method getElementValue() // to display text values of response elements for this request for (int i=0; i<respElements.length; i++) { System.out.println("Value of <" + respElements[i] + ">: " + myConwayXml.getElementValue(respElements[i])); } // Display the entire XML response for this request System.out.print(myConwayXml.getXmlResponse()); // For any questions, contact ConWay XML Support at web.support@Con-way.com } /** * Default no-argument constructor */ public XmlBol() { super(); } /** * Use this constructor if you pass in the entire XML input string * @param xmlInput java.lang.String */ public XmlBol(String xmlInput) { processXmlInput(xmlInput); } /** * Use this constructor if you pass in an array of Strings * for the XML elements and attributes * * Arguments: the array of Strings is to hold * the XML elements and their attributes using this form: * For Elements: "name=value" * For Attributes: "@name=value" ('@'prefixed to Attribute name) * Submit content in order, with any attributes following their parent element. * hence if root element has any attributes, * submit them as the first items in the String array * * @param xmlContentArray java.lang.String[] */ public XmlBol(String[] xmlContentArray) { processXmlInput(buildXmlInput(xmlContentArray)); } /** * Take the XML input String, encode it, submit to the Con-way servlet, * then read the result into a JDOM Document * @param xmlInput java.lang.String */ public void processXmlInput(String xmlInput) { inRootEl.removeContent(); // Clear Request JDOM document setXmlInput(xmlInput); success = false; outRootEl.removeContent(); // Clear Reponse JDOM document try { // Encode the input for a POST xmlInput = URLEncoder.encode(xmlInput,"UTF-8"); } catch (UnsupportedEncodingException use) { // If error, add error element outRootEl.addContent(new Element("Error").setText(use.getMessage())); error = true; return; } HttpURLConnection conwayConn = getUrlConnection(postUrl); DataOutputStream myOutStream = null; try { myOutStream = new DataOutputStream(conwayConn.getOutputStream()); myOutStream.writeBytes(requestType + "=" + xmlInput); myOutStream.flush(); myOutStream.close(); // Test the URL Connection for success if (! conwayConn.getResponseMessage().equals("OK")) { outRootEl.addContent(new Element("Error") .setText("URL " + conwayConn.getURL().toExternalForm() + ": " +conwayConn.getResponseMessage())); error = true; return; } // Create the output JDOM document using the connection's InputStream outJdomDoc = saxb.build(conwayConn.getInputStream()); outRootEl = outJdomDoc.getRootElement(); if (outRootEl.getChild("Error")==null) success = true; error = false; } catch (IOException ioe) { outRootEl.addContent(new Element("Error").setText(ioe.getMessage())); error = true; } catch (JDOMException jde) { outRootEl.addContent(new Element("Error").setText(jde.getMessage())); error = true; } } /** * Override <code>processXmlInput(String)</code> * in order to process with String array arguments from main() * @param xmlContentArray java.lang.String[] */ public void processXmlInput(String[] xmlContentArray) { processXmlInput(buildXmlInput(xmlContentArray)); } /** * @return java.lang.String - the XML input */ public String getXmlRequest () { return xmlOut.outputString(inJdomDoc); } /** * @return java.lang.String - the XML output */ public String getXmlResponse () { return xmlOut.outputString(outJdomDoc); } /** * Get the value of an XML element in the response, given its name * If more than one element of that name exists, returns value of the first * @param elementName java.lang.String - the name of the JDOM element * @return java.lang.String - the value of the JDOM element */ public String getElementValue (String elementName) { Element myEl = null; try { xpath = XPath.newInstance("//"+ elementName); myEl = (Element) xpath.selectSingleNode(outJdomDoc); } catch (JDOMException e) { // TODO Catch JDOM Exceptions e.printStackTrace(); } if (myEl != null) { return myEl.getText(); } else { return ":: ELEMENT <" + elementName + "> NOT FOUND ::"; } } /** * @return boolean - processing errors or not */ public boolean isError() { return error; } /** * @return boolean - success processing or not */ public boolean isSuccess() { return success; } /** * Using the String array of arguments containing the input XML * elements and attributes, build the XML document to submit in * the HTTP POST to the Con-way servlet. * * @param parms java.lang.String[] - the array of XML elements and attributes * @return java.lang.String - the XML input to the POST */ private String buildXmlInput(String[] parms) { String[] argNameVal = null; String argName = null; String argVal = null; Element myEl = null; Attribute myAtt = null; for (int i=0; i < parms.length; i++) { argNameVal = parms[i].split("="); argName = argNameVal[0]; argVal = argNameVal[1]; //Determine if this content is an attribute if (argName.startsWith("@")) { myAtt = new Attribute(argName.substring(1), argVal); // if this attribute is the first argument, add it to the root element if (i==0) { inRootEl.setAttribute(myAtt); } else { myEl.setAttribute(myAtt); } } else { // If it's not an attribute, assume it's an element myEl = new Element(argName).setText(argVal); inRootEl.addContent(myEl); } } return xmlOut.outputString(inJdomDoc); } /** * Establish and set up the URL connection * * @param theUrl java.lang.String = the POST URL * @return HttpURLConnection */ private HttpURLConnection getUrlConnection(String theUrl) { //Create a URL connection java.net.HttpURLConnection conn = null; java.net.URL conwayUrl; try { conwayUrl = new URL(theUrl); conn = (HttpURLConnection) conwayUrl.openConnection(); // Setup connection parameters conn.setRequestMethod("POST"); conn.setDoOutput(true); conn.setDoInput(true); conn.setUseCaches(false); } catch (MalformedURLException mfe) { outRootEl.addContent(new Element("Error").setText(mfe.getMessage())); error = true; } catch (IOException ioe) { outRootEl.addContent(new Element("Error").setText(ioe.getMessage())); error = true; } // Set the headers correctly (URL encoding, authentication) conn.setRequestProperty("Content-type", "application/x-www-form-urlencoded"); String authString = username + ":" + password; String auth = "Basic " + new sun.misc.BASE64Encoder().encode(authString.getBytes()); conn.setRequestProperty("Authorization", auth); return conn; } /** * Set the xmlInput instance variable, and normalize the String. * @param xmlInput java.lang.String */ private void setXmlInput(String xmlInput) { // remove tabs, CR, LF, extra spaces this.xmlInput = Text.normalizeString(xmlInput); } } -------------------------------------------------------------------------------------