在J2ME中获取HTTP连接

时间:2012-04-02 07:28:39

标签: http java-me connection

我正在尝试从J2ME应用程序获取链接响应 www.google.com 但不能这样,因为我得到一个错误输出

Running with storage root C:\Users\YK0089731\j2mewtk\2.5.2\appdb\QwertyDevice
Running with locale: English_United States.1252
Running in the identified_third_party security domain
No audio device found.
java.io.IOException: Error initializing HTTP tunnel connection: 
HTTP/1.1 502 Proxy Error ( The specified Secure Sockets Layer (SSL) port is not allowed. ISA Server is not configured to allow SSL requests from this port. Most Web browsers use port 443 for SSL requests.  )

Via: 1.1 CVMNODWS002

Connection: close

Proxy-Connection: close

Pragma: no-cache

Cache-Control: no-cache

Content-Type: text/html

Content-Length: 777   



    at com.sun.midp.io.j2me.http.Protocol.doTunnelHandshake(+333)
    at com.sun.midp.io.j2me.http.Protocol.connect(+145)
    at com.sun.midp.io.j2me.http.Protocol.streamConnect(+57)
    at com.sun.midp.io.j2me.http.Protocol.startRequest(+12)
    at com.sun.midp.io.j2me.http.Protocol.sendRequest(+38)
    at com.sun.midp.io.j2me.http.Protocol.sendRequest(+6)
    at com.sun.midp.io.j2me.http.Protocol.getResponseCode(+8)
    at HttpClientConnection.request(+128)
    at AppLoader.startApp(+14)
    at javax.microedition.midlet.MIDletProxy.startApp(+7)
    at com.sun.midp.midlet.Scheduler.schedule(+270)
    at com.sun.midp.main.Main.runLocalClass(+28)
    at com.sun.midp.main.Main.main(+80)
Responsejava.io.IOException: Error initializing HTTP tunnel connection: 
HTTP/1.1 502 Proxy Error ( The specified Secure Sockets Layer (SSL) port is not allowed. ISA Server is not configured to allow SSL requests from this port. Most Web browsers use port 443 for SSL requests.  )

Via: 1.1 CVMNODWS002

Connection: close

Proxy-Connection: close

Pragma: no-cache

Cache-Control: no-cache

Content-Type: text/html

Content-Length: 777   



Execution completed.
3917601 bytecodes executed
21516 thread switches
1670 classes in the system (including system classes)
18265 dynamic objects allocated (575372 bytes)
4 garbage collections (476336 bytes collected)

我在下面写了这样的代码,它从J2ME应用程序创建了一个简单的Http连接,并要求Http连接的响应并打印它并显示为alert。但它反过来给出了如上所示的错误

// Class AppLoader //初始化的类

import javax.microedition.lcdui.Alert;
import javax.microedition.lcdui.Display;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;

import HttpClientConnection.RequestType;


public class AppLoader extends MIDlet {
Display display;
String res;
    public AppLoader() {
        // TODO Auto-generated constructor stub
        display=Display.getDisplay(this);
    }

    protected void destroyApp(boolean arg0) throws MIDletStateChangeException {
        // TODO Auto-generated method stub

    }

    protected void pauseApp() {
        // TODO Auto-generated method stub

    }

    protected void startApp() throws MIDletStateChangeException {
        // TODO Auto-generated method stub
        HttpClientConnection con=HttpClientConnection.getInstance();
        try {
            res=con.request(RequestType.GET, "www.google.com",null, false);

        } catch (Exception e) {
            // TODO Auto-generated catch block
            res = e.toString();
            e.printStackTrace();
        }
        System.out.println("Response"+res);
        Alert alert =new Alert(null,"message : "+ res, null, null);
        alert.setTimeout(Alert.FOREVER);
        display.setCurrent(alert);
    }

}

AppLoader类调用HttpClientConnection类,如下所示,并通过应用程序获取用于建立与www.google.com的连接的相应参数

// HttpClientConnection类

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */



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

import javax.microedition.io.HttpConnection;
import javax.microedition.io.HttpsConnection;
import javax.microedition.io.Connection;
import javax.microedition.io.ConnectionNotFoundException;
import javax.microedition.io.Connector;

public class HttpClientConnection{

    private static HttpClientConnection instance;
    private static final boolean isSecureConnnectionAllowedByDefault = false;

    public static interface RequestType {

        public static final byte GET = 1;
        public static final byte POST = 2;
    }

    HttpClientConnection() {
    }

    public static HttpClientConnection getInstance() {
        if (instance == null) {
            instance = new HttpClientConnection();
        }
        return instance;
    }

    /*
    six input parameters
    byte requestType - tells about the request method
    String url - url to ping
    String userName - userName for Basic Authentication
    String userPass - userPass for Basic Authentication
    String params - request parameter
    boolean isSecureConnnection -  to determine whether to establish a Secure connection or not?

    return
    Response as a string
     */
    public String request(byte requestType, String url, String params, boolean isSecureConnnection) throws Exception {

        String response = null;
        HttpConnection connection = null;
        DataOutputStream outputStream = null;
        DataInputStream inputStream = null;

        try {
            if (isSecureConnnection) {
                connection = this.getHttpsConnection(url);
            } else {
                connection = this.getHttpConnection(url);
            }
            if (requestType == RequestType.POST) {
                connection.setRequestMethod(HttpConnection.POST);
            } else {
                connection.setRequestMethod(HttpConnection.GET);

            }

            if (params != null) //null check for params
            {

                 connection.setRequestProperty("Content-Type", "text/xml");
                connection.setRequestProperty("Content-Length", String.valueOf(params.length()));
                outputStream = new DataOutputStream(connection.openOutputStream());
                outputStream.write(params.getBytes());
                outputStream.close();
            }

            //responseCode = connection.getResponseCode();
            if (connection.getResponseCode() == HttpConnection.HTTP_OK) {
                inputStream = new DataInputStream(connection.openInputStream());
                byte[] data = new byte[256];
                int len = 0;
                StringBuffer raw = new StringBuffer();
                while (-1 != (len = inputStream.read(data))) {
                    raw.append(new String(data, 0, len));
                }
                inputStream.close();
                response = raw.toString();
            } else {
                // response = "" + connection.getResponseCode();

            }

        } catch (ClassCastException cce) //
        {
            throw cce;
        } catch (IllegalArgumentException iae) {
            throw iae;
        }
        //catch (ControlledAccessException cae) {
        //    throw cae;
       // }
    catch (ConnectionNotFoundException cnfe) {
            throw cnfe;
        } catch (IOException ioe) {
            throw ioe;
        } catch (Exception ex) {
            throw ex;
        } finally {
            try {
                if (connection != null) {
                    connection.close();
                }
                if (inputStream != null) {
                    inputStream.close();
                }
                if (outputStream != null) {
                    outputStream.close();
                }
            } catch (IOException ioe) {
            }
        }

        return response;
    }


    private HttpsConnection getHttpsConnection(String url) throws IOException {
        return (HttpsConnection) ConnectionManager.getInstance().getConnection("https://" + url);
    }

    private HttpConnection getHttpConnection(String url) throws IOException {
        return (HttpConnection) ConnectionManager.getInstance().getConnection("http://" + url);

    }
}

然后第3个类是ConnectionManager类

// ConnectionManager class
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */



import java.io.*;
import javax.microedition.io.*;

public class ConnectionManager {

    private static final long ID = 0x1431cf6271d3b1edL; // ConnectionManager.ID //
    private static String IPPP = "IPPP";                // Static instance of the IPPP string so we don't create it every time.
    private static ConnectionManager _manager;      // Static instance of the ConnectionManager.
    private boolean m_parseServiceBooks;
    private boolean _mdsSupport;                    // Boolean representing whether MDS is supported.
    private boolean _bisSupport;                    // Boolean representing whether BIS-B is supported.
    private boolean _wapSupport;                    // Boolean representing whether WAP is supported.
    private boolean _defaultSSLSupport = false;     //Constants.SUPPORT_SSL;

    /**
     * The constructor for this class which simply parses the service books.
     */
    private ConnectionManager() {
    }

    /**
     * Returns an instance of the ConnectionManager.  This currently
     * only leverages providing a static instance (one per process) but could
     * easily be changed to provide a singleton instance for the whole system.
     * @return an instance of the ConnectionManager.
     */
    public static ConnectionManager getInstance() {
        if (_manager == null) {
            _manager = new ConnectionManager();
        }

        return _manager;
    }

    /**
     * Returns the Connection object specified by the name (e.g. HttpConnection) using the
     * appropriate transport mechanism (MDS, BIS-B, TCP) depending on what service books
     * are currently supported on the handheld and using a priority scale in the following order:
     * <code>
     *      MDS
     *      BIS-B
     *      WAP - To be supported in the future
     *      HTTP over Direct TCP
     * </code>
     * This method does NOT check for the name to ensure that HTTP is being requested and as such
     * it may not work if you request a socket connection over the BIS-B transport protocol.
     */
    public Connection getConnection(String name) throws IOException {
        //MyCaptionLogger.debugLog("Enter into getConnection( "+name+ ") in ConnectionManager");
        Connection lConn = null;

        // doing this for the first time when getConnection is called

       // if (!m_parseServiceBooks) {
       //     parseServiceBooks(3);
      //  }

     //   m_parseServiceBooks = true;

      //  if (_bisSupport) {
            // BIS-B Transport
            //if (!DeviceInfo.isSimulator()) {
              // name = name.concat(";deviceside=false;ConnectionType=mds-public");
             //   if (_defaultSSLSupport) {
                    //"EndToEndRequired" specifies that end-to-end TLS/SSL must be used from the handheld
                    //to the host server. If handheld does not support TLS/SSL, the connection is closed.
                    //Please note that with handhelds running 4.0 OS and higher, handheld TLS is installed by default.
                //    name = name.concat(";EndToEndRequired");
              //  }
            //}
       // } else if (_mdsSupport) {
            // MDS Transport
        //    name = name.concat(";deviceside=false");
      //  } else if (_wapSupport) {
            // TODO
      //  }
        /* else
        {
        // HTTP over Direct TCP
        name = name.concat( ";deviceside=true" );
        } */

       //name = name.concat(";deviceside=false");
        try {
            lConn = Connector.open(name);
        } catch (IOException ex) {
            //parseServiceBooks(1);
            throw ex;
        }

        return lConn;
    }

    /**
     * Returns the Connection object specified by the name (e.g. HttpConnection) using the
     * appropriate transport mechanism (MDS, BIS-B, TCP) depending on what service books
     * are currently supported on the handheld and using a priority scale in the following order:
     * <code>
     *      MDS
     *      BIS-B
     *      WAP - To be supported in the future
     *      HTTP over Direct TCP
     * </code>
     * This method does NOT check for the name to ensure that HTTP is being requested and as such
     * it may not work if you request a socket connection over the BIS-B transport protocol.
     */
    public Connection getConnection(String name, int mode, boolean timeouts) throws IOException {
        Connection lConn = null;

       // if (_bisSupport) {
            // BIS-B Transport
           // name = name.concat(";deviceside=false;ConnectionType=mds-public");
            if (_defaultSSLSupport) {
                //"EndToEndRequired" specifies that end-to-end TLS/SSL must be used from the handheld
                //to the host server. If handheld does not support TLS/SSL, the connection is closed.
                //Please note that with handhelds running 4.0 OS and higher, handheld TLS is installed by default.
                name = name.concat(";EndToEndRequired");
           // }
        } else if (_mdsSupport) {
            // MDS Transport
            name = name.concat(";deviceside=false");
        } else if (_wapSupport) {
            // TODO
        }
        /* else {
        // HTTP over Direct TCP
        name = name.concat( ";deviceside=true" );
        } */

        try {
            lConn = Connector.open(name, mode, timeouts);
        } catch (IOException ex) {
            //parseServiceBooks(1);
            throw ex;
        }

        return lConn;
    }

    /**
     * Returns a string representing the type of connection that would be chosen when using getConnection.
     * @return a string representing the type of connection that would be chosen when using getConnection.
     */
    public String getConnectionType() {

        if (_bisSupport) {
            // BIS-B Transport
            return "BIS-B";
        } else if (_mdsSupport) {
            // MDS Transport
            return "MDS";
        } else if (_wapSupport) {
            // WAP Transport
            return "WAP";
        } else {
            // HTTP over Direct TCP
            return "Direct TCP";
        }
    }

    /**
     * This method uses the CoverageInfo API to determine what coverage is available on the device.
     * CoverageInfo is available as of 4.2.0, but until 4.2.2, Coverage_MDS is shown as available
     * when only BIS_B Coverage is actually available on the device.
     */
   /* private void setCoverage() {

        if (CoverageInfo.isCoverageSufficient(CoverageInfo.COVERAGE_MDS)) {
            _mdsSupport = true;
        }

        if (CoverageInfo.isCoverageSufficient(CoverageInfo.COVERAGE_BIS_B)) {
            _bisSupport = true;
        }
    }*/

    /**
     * This method handles changes in Coverage through the CoverageStatusListener interface.
     * CoverageStatusListener works with CoverageInfo and is available with 4.2.0
     */
    /*public void coverageStatusChanged(int newCoverage) {

        if ((newCoverage & CoverageInfo.COVERAGE_MDS) == CoverageInfo.COVERAGE_MDS) {
            _mdsSupport = true;
        }

        if ((newCoverage & CoverageInfo.COVERAGE_BIS_B) == CoverageInfo.COVERAGE_BIS_B) {
            _bisSupport = true;
        }
    }*/

    /**
     * This method provides the functionality of actually parsing
     * through the service books on the handheld and determining
     * which traffic routes are available based on that information.
     */
    /*public void parseServiceBooks(int retryCount) {

        int retry = 0;
        boolean retryFlag = true;
        while (retry < retryCount) {
            retry++;

            // Add in our new items by scrolling through the ServiceBook API.
            ServiceBook sb = ServiceBook.getSB();
            ServiceRecord[] records = sb.findRecordsByCid(IPPP);      // The IPPP service represents the data channel for MDS and BIS-B
            if (records == null) {
                return;
            }

            int numRecords = records.length;
            for (int i = 0; i < numRecords; i++) {
                ServiceRecord myRecord = records[i];
                String name = myRecord.getName();       // Technically, not needed but nice for debugging.
                String uid = myRecord.getUid();         // Technically, not needed but nice for debugging.

                // First of all, the CID itself should be equal to IPPP if this is going to be an IPPP service book.
                if (myRecord.isValid() && !myRecord.isDisabled()) {
                    // Now we need to determine if the service book is Desktop or BIS.  One could check against the
                    // name but that is unreliable.  The best mechanism is to leverage the security of the service
                    // book to determine the security of the channel.
                    int encryptionMode = myRecord.getEncryptionMode();
                    if (encryptionMode == ServiceRecord.ENCRYPT_RIM) {
                        _mdsSupport = true;
                    } else {
                        _bisSupport = true;
                    }

                    retryFlag = false;
                }
            } 

            if (retryFlag == false) {
                break;
            }

            try {
                Thread.sleep(120000); // sleep 2 min to make sure service books are downloaded properly
            } catch (Exception ex) {
            }

        } 
    }*/

    ////////////////////////////////////////////////////////////
    /// GlobalEventListener Interface Implementation         ///
    ////////////////////////////////////////////////////////////
    /**
     * Invoked when the specified global event occured.
     * The eventOccurred method provides two object parameters and two integer parameters for supplying details about the event itself. The developer determines how the parameters will be used.
     *
     *
     *
     * @param guid - The GUID of the event.
     * @param data0 - Integer value specifying information associated with the event.
     * @param data1 - Integer value specifying information associated with the event.
     * @param object0 - Object specifying information associated with the event.
     * @param object1 - Object specifying information associated with the event.
     */
   /* public void eventOccurred(long guid, int data0, int data1, Object object0, Object object1) {
        if (guid == ServiceBook.GUID_SB_ADDED ||
                guid == ServiceBook.GUID_SB_CHANGED ||
                guid == ServiceBook.GUID_SB_OTA_SWITCH ||
                guid == ServiceBook.GUID_SB_OTA_UPDATE ||
                guid == ServiceBook.GUID_SB_POLICY_CHANGED ||
                guid == ServiceBook.GUID_SB_REMOVED) {
            parseServiceBooks(1);
        }
    }*/
}

2 个答案:

答案 0 :(得分:1)

从错误消息中看起来您正尝试在端口80上打开安全连接:
HTTP / 1.1 502代理错误(不允许指定的安全套接字层(SSL)端口.ISA Server未配置为允许来自此端口的SSL请求。大多数Web浏览器使用端口443进行SSL请求。 )

为什么不尝试使用更简单的代码作为跟踪子弹来找出问题的根源?
http://pragprog.com/the-pragmatic-programmer/extracts/tips

答案 1 :(得分:0)

最好你尝试

 outputStream = connection.openDataOutputStream();

而不是

 outputStream = new DataOutputStream(connection.openOutputStream());

在HttpClientConnection类