📄 simplexmlrpcclient.java
字号:
/* * Copyright 1999,2005 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package org.apache.xmlrpc.applet;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.io.UnsupportedEncodingException;import java.net.MalformedURLException;import java.net.URL;import java.net.URLConnection;import java.text.DateFormat;import java.text.ParseException;import java.text.SimpleDateFormat;import java.util.Date;import java.util.Enumeration;import java.util.Hashtable;import java.util.Stack;import java.util.Vector;import org.apache.commons.codec.binary.Base64;import org.apache.commons.codec.DecoderException;import org.apache.commons.codec.EncoderException;import org.xml.sax.AttributeList;import org.xml.sax.HandlerBase;import org.xml.sax.InputSource;import org.xml.sax.SAXException;import org.xml.sax.SAXParseException;import uk.co.wilson.xml.MinML;/** * A simple XML-RPC client. * * FIXME: This code is VERY out of date with the rest of the package. * * @version $Id: SimpleXmlRpcClient.java,v 1.10 2005/04/22 10:25:58 hgomez Exp $ */public class SimpleXmlRpcClient{ URL url; /** * Construct a XML-RPC client with this URL. */ public SimpleXmlRpcClient(URL url) { this.url = url; } /** * Construct a XML-RPC client for the URL represented by this String. */ public SimpleXmlRpcClient(String url) throws MalformedURLException { this.url = new URL(url); } /** * Construct a XML-RPC client for the specified hostname and port. */ public SimpleXmlRpcClient(String hostname, int port) throws MalformedURLException { this.url = new URL("http://" + hostname + ":" + port + "/RPC2"); } /** * * @param method * @param params * @return * @throws XmlRpcException * @throws IOException */ public Object execute(String method, Vector params) throws XmlRpcException, IOException { return new XmlRpcSupport (url).execute (method, params); }}/** * FIXME: Leverage the XmlRpc class. */class XmlRpcSupport extends HandlerBase{ URL url; String methodName; boolean fault = false; Object result = null; Base64 base64 = new Base64(); // the stack we're parsing our values into. Stack values; Value currentValue; boolean readCdata; // formats for parsing and generating dateTime values static final DateFormat format = new SimpleDateFormat("yyyyMMdd'T'HH:mm:ss"); // used to collect character data of parameter values StringBuffer cdata = new StringBuffer (); // XML RPC parameter types used for dataMode static final int STRING = 0; static final int INTEGER = 1; static final int BOOLEAN = 2; static final int DOUBLE = 3; static final int DATE = 4; static final int BASE64 = 5; static final int STRUCT = 6; static final int ARRAY = 7; // for debugging output public static boolean debug = false; final static String types[] = {"String", "Integer", "Boolean", "Double", "Date", "Base64", "Struct", "Array"}; /** * * @param url */ public XmlRpcSupport(URL url) { this.url = url; } /** * Switch debugging output on/off. */ public static void setDebug(boolean val) { debug = val; } /** * Parse the input stream. For each root level object, method * <code>objectParsed</code> is called. */ synchronized void parse(InputStream is) throws Exception { values = new Stack(); long now = System.currentTimeMillis(); MinML parser = new MinML(); parser.setDocumentHandler(this); parser.setErrorHandler(this); parser.parse(new InputSource(is)); if (debug) { System.out.println("Spent " + (System.currentTimeMillis() - now) + " parsing"); } } /** * Writes the XML representation of a supported Java object to the XML writer. */ void writeObject (Object what, XmlWriter writer) throws IOException { writer.startElement("value"); if (what instanceof String) { writer.write(what.toString()); } else if (what instanceof Integer) { writer.startElement("int"); writer.write (what.toString()); writer.endElement("int"); } else if (what instanceof Boolean) { writer.startElement("boolean"); writer.write(((Boolean) what).booleanValue() ? "1" : "0"); writer.endElement("boolean"); } else if (what instanceof Double) { writer.startElement("double"); writer.write (what.toString()); writer.endElement("double"); } else if (what instanceof Date) { writer.startElement("dateTime.iso8601"); Date d = (Date) what; writer.write(format.format(d)); writer.endElement("dateTime.iso8601"); } else if (what instanceof byte[]) { writer.startElement("base64"); try { writer.write((byte[]) base64.encode(what)); } catch (EncoderException e) { throw new RuntimeException("Possibly incompatible version " + "of '" + Base64.class.getName() + "' used: " + e); } writer.endElement("base64"); } else if (what instanceof Vector) { writer.startElement("array"); writer.startElement("data"); Vector v = (Vector) what; int l2 = v.size(); for (int i2 = 0; i2 < l2; i2++) { writeObject(v.elementAt(i2), writer); } writer.endElement("data"); writer.endElement("array"); } else if (what instanceof Hashtable) { writer.startElement("struct"); Hashtable h = (Hashtable) what; for (Enumeration e = h.keys (); e.hasMoreElements (); ) { String nextkey = (String) e.nextElement (); Object nextval = h.get(nextkey); writer.startElement("member"); writer.startElement("name"); writer.write(nextkey); writer.endElement("name"); writeObject(nextval, writer); writer.endElement("member"); } writer.endElement("struct"); } else { String unsupportedType = what == null ? "null" : what.getClass().toString(); throw new IOException("unsupported Java type: " + unsupportedType); } writer.endElement("value"); } /** * Generate an XML-RPC request and send it to the server. Parse the result * and return the corresponding Java object. * * @exception XmlRpcException If the remote host returned a fault message. * @exception IOException If the call could not be made for lower level * problems. */ public Object execute(String method, Vector arguments) throws XmlRpcException, IOException { fault = false; long now = System.currentTimeMillis(); try { StringBuffer strbuf = new StringBuffer(); XmlWriter writer = new XmlWriter(strbuf); writeRequest(writer, method, arguments); byte[] request = strbuf.toString().getBytes(); URLConnection con = url.openConnection(); con.setDoOutput(true); con.setDoInput(true); con.setUseCaches(false); con.setAllowUserInteraction(false); con.setRequestProperty("Content-Length", Integer.toString(request.length)); con.setRequestProperty("Content-Type", "text/xml"); // con.connect (); OutputStream out = con.getOutputStream(); out.write(request); out.flush(); InputStream in = con.getInputStream(); parse(in); System.out.println("result = " + result); } catch (Exception x) { x.printStackTrace(); throw new IOException(x.getMessage()); } if (fault) { // generate an XmlRpcException XmlRpcException exception = null; try { Hashtable f = (Hashtable) result; String faultString = (String) f.get("faultString"); int faultCode = Integer.parseInt(f.get("faultCode").toString()); exception = new XmlRpcException(faultCode, faultString.trim()); } catch (Exception x) { throw new XmlRpcException(0, "Invalid fault response"); } throw exception; } System.out.println("Spent " + (System.currentTimeMillis() - now) + " in request"); return result; } /** * Called when the return value has been parsed. */ void objectParsed(Object what) { result = what; } /** * Generate an XML-RPC request from a method name and a parameter vector. */ void writeRequest (XmlWriter writer, String method, Vector params) throws IOException { writer.startElement("methodCall"); writer.startElement("methodName"); writer.write(method); writer.endElement("methodName"); writer.startElement("params"); int l = params.size(); for (int i = 0; i < l; i++) { writer.startElement("param"); writeObject(params.elementAt (i), writer); writer.endElement("param"); } writer.endElement("params"); writer.endElement("methodCall"); } //////////////////////////////////////////////////////////////// // methods called by XML parser /** * Method called by SAX driver. */ public void characters(char ch[], int start, int length) throws SAXException { if (! readCdata) { return; } cdata.append (ch, start, length); } /** * Method called by SAX driver. */ public void endElement(String name) throws SAXException { if (debug) { System.err.println("endElement: " + name); } // finalize character data, if appropriate if (currentValue != null && readCdata) { currentValue.characterData(cdata.toString()); cdata.setLength(0); readCdata = false; } if ("value".equals(name)) { int depth = values.size(); // Only handle top level objects or objects contained in arrays here. // For objects contained in structs, wait for </member> (see code below). if (depth < 2 || values.elementAt (depth - 2).hashCode () != STRUCT) { Value v = currentValue;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -