------------------------------------------------------------------------------------- package com.conway; import java.io.*; import java.net.*; import java.util.List; import java.util.ListIterator; import java.util.Random; import org.apache.xerces.impl.dv.util.Base64; /* Here we use the Apache Xerces Base64 Encoder (Xerces 2.6 +) Old versions of Xerces use this: import org.apache.xerces.utils.Base64; You can use any other Base64 encoder you want */ //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 Image Retrieval * @author Andrew vonderLuft * * REQUIRES: JDOM, XERCES * JDOM 1.0 which can be downloaded from http://jdom.org * JDOM provides a helpful abstraction layer for working with with XML within Java * XERCES is the Open Source Apache XML processor * available at http://xml.apache.org - to use the Base64 encoder * This was tested with both XERCES 2.6.2 and 2.7.1 * * TESTED: * In Eclipse 3.1 using JRE 1.3.1 (no SSL), 1.4.2_08 and 1.5.0_04 * In WebSphere Application Developer 5.1.2 * * TODO: replace the USERNAME and PASSWORD String values in variables below * with your Con-way username and password * replace the "C:\\imgs\\" directory location with your preferred location for * retrieved PDF files. * replace "PRONUMBER" with your own 9-digit PRO Numbers * * Send any questions to Con-way XML Support at xmlsupport@Con-way.com */ public class XmlImage { // 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"; // TODO: replace the "C:\\imgs\\" directory location with your preferred location private final static String imageDir = "C:\\imgs\\"; public final static String requestType = "ImageRequest"; public final static String responseType = "ImageResponse"; public final static String servletUri = "webapp/imaging_app/XmlImageRetrieverServlet"; // JRE 1.3 doesn't handle SSL well by itself, so if you are using 1.3 // use this standard HTTP URL instead: // public final static String conwayUrl = "http://www.Con-way.com/"; public final static String conwayUrl = "https://www.Con-way.com/"; public final static String postUrl = conwayUrl + servletUri; // 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, proNum, imgType, imgFormat = null; List imgList = null; byte[] imgBytes = null; XPath xpath = null; boolean 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. * * 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 * * NOTE: For the XML Image interface you will simply pass in 2 elements for each * Image Request: PRONumber and ImageType * * @param args java.lang.String[] */ public static void main(String[] args) { String[] xmlArgs = null; // TODO: replace "PRONUMBER" below with your own 9-digit PRO Number // if arguments are not passed in to main, we can use these to test: if (args.length == 0) { xmlArgs = new String[] { "PRONumber=PRONUMBER" ,"ImageType=BL" ,"ImageFormat=pdf" // may be 'pdf', 'png', 'tiff', 'jpeg' }; // otherwise use arguments which are passed in. } else { xmlArgs = new String[args.length]; for (int i=0; i<args.length; i++) { xmlArgs[i] = args[i]; } } // Instantiate a ConwayXml object with the String array argments XmlImage myConwayXml = new XmlImage(xmlArgs); // Report success System.out.println("XML Request success = " + myConwayXml.isSuccessful()); // If successful, save the image file(s) on your filesystem if (myConwayXml.isSuccessful()) { String fileName = null; String uniqueString = Integer.toString(new Random(System.currentTimeMillis()) .nextInt(),Character.MAX_RADIX).toUpperCase(); Element imgEl = null; ListIterator imgListItor = (ListIterator) myConwayXml.imgList.iterator(); int pages = myConwayXml.imgList.size(); while (imgListItor.hasNext()) { int page = imgListItor.nextIndex() + 1; String pageString = ""; if (pages > 1) { pageString = new Integer(page).toString(); if (pageString.length() < 2) pageString = "0" + pageString; pageString = "_" + pageString; } // Create a unique file name fileName = imageDir + myConwayXml.imgType + "-" + myConwayXml.proNum + "-" + uniqueString + pageString + "." + myConwayXml.imgFormat; imgEl = (Element) imgListItor.next(); myConwayXml.imgBytes = Base64.decode(imgEl.getText()); try { BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(fileName)); out.write(myConwayXml.imgBytes); out.close(); System.out.println("Image File written to: " + fileName); } catch (IOException e) { //TODO catch file write error System.out.println("Image File failed writing to: " + fileName + ": " + e); } } } // You can also display the entire XML response with this method: System.out.print(myConwayXml.getXmlResponse()); // For any questions, contact ConWay XML Support at xmlsupport@Con-way.com } /** * Default no-argument constructor */ public XmlImage() { super(); } /** * Use this constructor if you pass in the entire XML input string * @param xmlInput java.lang.String */ public XmlImage(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 XmlImage(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 // remove tabs, CR, LF, extra spaces xmlInput = Text.normalizeString(xmlInput); success = false; outRootEl.removeContent(); // Clear Response JDOM document xmlInput = URLEncoder.encode(xmlInput); /* If using JRE 1.5, the encode method above is deprecated. * You may wish to use the following instead. 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())); success = false; 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())); success = false; return; } // Create the output JDOM document using the connection's InputStream outJdomDoc = saxb.build(conwayConn.getInputStream()); outRootEl = outJdomDoc.getRootElement(); // Check for success if (outRootEl.getChild("Error")==null) { success = true; // Set instance variables this.proNum = outRootEl.getChild("Image").getChildText("PRONumber"); this.imgType = outRootEl.getChild("Image").getChildText("ImageType"); this.imgFormat = outRootEl.getChild("Image").getChildText("ImageFormat").toLowerCase(); this.imgList = outRootEl.getChild("Image").getChildren("ImageData"); } else { success = false; } } catch (IOException ioe) { outRootEl.addContent(new Element("Error").setText(ioe.getMessage())); success = false; } catch (JDOMException jde) { outRootEl.addContent(new Element("Error").setText(jde.getMessage())); success = false; } catch (Exception e) { outRootEl.addContent(new Element("Error").setText(e.getMessage())); success = false; } } /** * 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 - success processing or not */ public boolean isSuccessful() { 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; Element imgKeyEl = new Element("ImageKey"); inRootEl.addContent(imgKeyEl); for (int i=0; i < parms.length; i++) { argName = parms[i].substring(0,parms[i].indexOf("=")); argVal = parms[i].substring(parms[i].indexOf("=")+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); imgKeyEl.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); // 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); } catch (MalformedURLException mfe) { outRootEl.addContent(new Element("Error").setText(mfe.getMessage())); success = false; } catch (IOException ioe) { outRootEl.addContent(new Element("Error").setText(ioe.getMessage())); success = false; } return conn; } } -------------------------------------------------------------------------------------