一个基于http协议的访问网络的封装类

    技术2022-05-11  135

    转一个基于http协议的访问网络的封装类,使用时只需调用

    public static synchronized byte[] connect(String url, byte[] data,String method, String contentType, long lowRange, long highRange,  boolean disableProxy, boolean detached)

     这个函数就可以了.

     

    ------------------------------------------/** * NetConnection.java *  * This code is protected under the Apache 2.0 license as mentioned in * the accompanying license.txt file.  The license.txt file MUST be located * within the same folder as this NetConnection.java source file. *  * The license file may also be viewed online by * visiting http://www.apache.org/licenses/ */

    import java.io.DataInputStream;import java.io.DataOutputStream;import java.io.IOException;

    import javax.microedition.io.Connector;import javax.microedition.io.HttpConnection;

     

    /** * This class provides robust network connectivity and exception handling * over an unreliable MIDP HttpConnection. *  * In addition the caller may perform a combination of any of the below * functions. *  * - Proxy-server thwarting * - HTTP range requests * - Thread-separated connections *  * @author Jason Fuerstenberg (http://www.jay-f.jp) * @version 2004/03/15 */public final class NetConnection implements Runnable {  /*  * This class is implemented as a singleton since only  * a single active connection is allowed.  */ private static NetConnection singleton = new NetConnection();   /*  * The underlying HttpConnection which is managed by this class.  */ private static HttpConnection httpConn;   /*  * To support multi-threaded network connections a series of  * pass-through members are used/shared across the class' threads.  */   /*  * The requested URL.  *   * This member serves a second purpose which is to prevent a caller  * from directly calling the run() method which is public to adhere to  * the Runnable interface.  */ private static String url;   // The HTTP method used to make the connection. private static String method;  // The posted data if any. private static byte[] data;   // The content type (if the method is POST) private static String contentType;  // The lower bound of the requested range. private static long lowRange;  // The higher bound of the requested range. private static long highRange;  /*  * The flag to indicate that the request should attempt to thwart  * any proxy servers by appending a timestamp to the request.  */  private static boolean disableProxy;  /*  * The flag to indicate that the connection should occur in a separate  * thread.  */ private static boolean detached;  // The response's byte array. private static byte[] response;    /*  * In the event of an exception occuring in the run() method during  * synchronous or asynchronous execution the exception needs to be  * communicated up the main application thread's call stack.  This static  * member will be a reference for any exception that may have occured  * and will be thrown after run() returns.  *   */ private static Exception exceptionPipe;

     /*  * The private constructor to enforce the singleton pattern  * which this class implements.  */ private NetConnection() {  // singleton }

     /**  * Connects to a target URL.  *   * @param url The target URL  * @param data The data to post (if any)  * @param method HttpConnection.GET or HttpConnection.POST  * @param contentType The content-type of the posted data (if any)  * @param lowRange The byte offset within the requested resource from  *      which the response will begin.  * @param highRange The last byte the response will return or 0  *    if requesting the entire resource.  * @param disableProxy Attempts to prevent a given server from   *       offering a cached proxy version of the  *       requested resource.  * @param detached Causes the connection to occur in a thread separate  *    from the calling thread.  This call will block until  *    the connection has ended.  * @return A byte array containing the response from the server.  * @throws IOException If a network error occured.  */ public static synchronized byte[] connect(String url, byte[] data,   String method, String contentType, long lowRange, long highRange,   boolean disableProxy, boolean detached) throws Exception {  

      /*   * Set all the pass-through members here.   */  exceptionPipe = null;  NetConnection.url = url;  NetConnection.data = data;  NetConnection.method = method;  NetConnection.contentType = contentType;  NetConnection.lowRange = lowRange;  NetConnection.highRange = highRange;  NetConnection.disableProxy = disableProxy;  NetConnection.detached = detached;  

      // Preemptively try to disconnect from a previous connection!  NetConnection.severConnection();

        if (detached) {   /*    * The caller has specified that the connection should occur    * in a separate, detached thread.    */   Thread t = new Thread(singleton);   t.start();      /*    * Enforce a wait here to provide the illusion of synchronous    * execution despite having the connection in another thread.    */   singleton.forceWait();

      } else {   /*    * Call run() directly without creating a thread to launch it.    */   singleton.run();  }    /*   * Reset the URL to null to prevent direct   * calling of the run() method.   */  NetConnection.url = null;    if (exceptionPipe != null) {   /*    * During the course of the connection an exception occured    * and was communicated here by the exceptionPipe member.    * Throw it from this location.    */   throw exceptionPipe;  }     // successful connection, return response!  return response; } 

     /**  * Performs the actual connection logic.  * The connection may occur in a separate thread from that of the caller.  *   * @throws IllegalStateException if called directly by any class  *    other than this one.  */ public void run() {    if (url == null) {   /*    * The URL is used as a means to ascertain whether or not the    * caller of this method was the connect() method.  Since it is    * null the caller is directly calling run() so throw an exception.    */   throw new IllegalStateException("Cannot invoke this method!");  }

        DataOutputStream dos = null;  DataInputStream dis = null;  StringBuffer buffer = null;      /*   * IMPLEMENTATION NOTE:   *    * From this section on, a series of try/catch/finally statements   * is used to ensure the proper flow of the connection under a   * wide variety of circumstances.  This seemingly verbose logic   * is important for the proper exception handling and object   * reclamation required to make subsequent connections   * possible in the future.   *    * In addition, the catching of exception is not too particular   * regarding the type of exception being thrown for a few reasons...   *    * 1. The handling of each exception type is identical   * 2. Implementations may vary in which exceptions they throw   *    * In the interest of stability it is highly recommended to   * leave this as is, even if it goes against orthodox practices.   */

      try {

       int permissions = 0;      // Setup the permissions   if (HttpConnection.GET.equals(method)) {    permissions = Connector.READ;   } else if (HttpConnection.POST.equals(method)) {    permissions = Connector.READ_WRITE;   }         if (disableProxy) {    /*     * To thwart the a given server's proxy cache     * the logic will attach a query parameter to the     * end of the URL with a millisecond timestamp which     * will hopefully force the server to see this request as one     * which has never previously occured for this client     * and therefore entitled to a fresh copy of the requested     * resource.      */    boolean hasQueryParams = false;        char[] ca = url.toCharArray();

        for (int loop = 0; loop < url.length(); loop++) {          if (ca[loop] == '?') {      hasQueryParams = true;      break;     }    }        StringBuffer noProxyUrl = new StringBuffer();    noProxyUrl.append(url);

        if (hasQueryParams) {     noProxyUrl.append("&");    } else {     noProxyUrl.append("?");    }    noProxyUrl.append("no-proxy=");    noProxyUrl.append(System.currentTimeMillis()); // timestamp        /*     * Reset the URL to include the "no-proxy" query     * parameter.     */    url = noProxyUrl.toString();   }      

       // Open the connection and set the request method.   httpConn = (HttpConnection) Connector.open(url, permissions, true);   httpConn.setRequestMethod(method);

       //if (HttpConnection.GET.equals(method)) {   if (permissions == Connector.READ) {    // GET request        if (lowRange > -1 && lowRange < highRange) {     /*      * The caller is requesting a specific range within      * the resource.      *       * The logic will insert the appropriate HTTP header to      * implement the request.      */     StringBuffer range = new StringBuffer();          range.append("bytes=");     range.append(lowRange);     range.append("-");     range.append(highRange);          httpConn.setRequestProperty("Range", range.toString());    }   } else if (permissions == Connector.READ_WRITE) {    // POST request    httpConn.setRequestProperty("Content-Type", contentType);    dos = httpConn.openDataOutputStream();    dos.write(data);   }     } catch (Exception e) {   /*    * An exception occured either during the opening of the connection    * or during the POSTing of data.  In either case the logic cannot    * continue and will quit here.    */   exceptionPipe = e;

       if (detached) {    forceNotify();   }      return;     } finally {

       try {    try {     if (dos != null) {      // Close the DataOutputStream.      dos.close();     }    } catch (Exception e) {     // Failure to close the DataOutputStream!     if (exceptionPipe == null) {      exceptionPipe = e;            if (detached) {       forceNotify();      }      return;     }    } finally {     // Force the dereferencing of the DataOutputStream.     dos = null;    }        // Get the response code.    int responseCode = httpConn.getResponseCode();        if (responseCode != HttpConnection.HTTP_OK      && responseCode != HttpConnection.HTTP_PARTIAL) {

         /*      * The response code does not match HTTP_OK (200)      * or HTTP_PARTIAL (206).  The logic cannot proceed to      * treat the response as one holding the requested      * resource and therefore will report the response code      * via an exception to the caller.      */     if (exceptionPipe == null) {      StringBuffer errorCode = new StringBuffer();      errorCode.append("Response code from server: ");      errorCode.append(responseCode);      errorCode.append("/nMessage: [");      errorCode.append(httpConn.getResponseMessage());      errorCode.append("]");            exceptionPipe = new IOException(errorCode.toString());            if (detached) {       forceNotify();      }      return;     }    }

        dis = httpConn.openDataInputStream();

        /*     * Cycle through all the bytes provided     * in the response and append them to a     * StringBuffer for later use.     */    int ch;    buffer = new StringBuffer();          while ((ch = dis.read()) != -1) {           buffer.append((char) ch);          }

              /*           * Convert the StringBuffer to an array using           * the ISO-8859-1 encoding to preserve the byte           * encoding of the characters.           */    response = buffer.toString().getBytes("ISO8859_1");        if (detached) {     forceNotify();    }        /*     * All OK, now returning.     */    return;

       } catch (Exception e) {    /*     * An exception occured either during the usage of the     * connection object (such as a NullPointerException) or during     * the reading of the data.  In either case the logic cannot     * continue.     */    if (exceptionPipe == null) {     exceptionPipe = e;          if (detached) {      forceNotify();     }          return;    }   } finally {           try {     if (dis != null) {      // Close the DataInputStream.      dis.close();     }    } catch (Exception e) {     // Failure to close the DataInputStream!     if (exceptionPipe == null) {      exceptionPipe = e;            if (detached) {       forceNotify();      }      return;     }    } finally {     // force the dereferencing of the DataInputStream.     dis = null;    }        try {     if (httpConn != null) {      // Close the HttpConnection.      httpConn.close();            /*       * Only dereference the HttpConnection if the       * closing actually succeeded!       */       httpConn = null;     }    } catch (Exception e) {     // Failure in closing the HttpConnection!     if (exceptionPipe == null) {      exceptionPipe = e;            if (detached) {       forceNotify();      }      return;     }    }   }  } }  /*  * Provides the synchronized context against the singleton's instance  * for the wait() method call to properly execute.  Not all implementations  * of the JVM support the concept of synchronized contexts other than  * that of an entire method.  As such the inner call to wait must be  * embedded in this synchronized method.  */ private synchronized void forceWait() {    try {   wait();  } catch (InterruptedException ie) {   // Ignore this exception   ie = null;  } }   /*  * Provides the synchronized context against the singleton's instance  * for the notify() method call to properly execute.  Not all  * implementations of the JVM support the concept of synchronized  * contexts other than that of an entire method.  As such the inner  * call to notify must be embedded in this synchronized method.  */ private synchronized void forceNotify() {  notify(); }  /*  * Severs an ongoing connection.  */ private static void severConnection() {       try {   if (httpConn == null) {    /*     * No connection is in progress so simply return     * to the caller.     */    return;   }      // Close the connection.      httpConn.close();

      } catch (Exception e) {   /*    * If the handset's implementation of the HttpConnection    * interface is solid it will not be possible for    * an exception to occur.    */   e = null;  } finally {   // Force the dereferencing of the connection.   httpConn = null;  } }}


    最新回复(0)