【问题标题】:Getting a HTTP connection in J2ME在 J2ME 中获取 HTTP 连接
【发布时间】:2012-04-02 07:28:38
【问题描述】:

我正在尝试从 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);

    }
}

那么第三类就是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);
        }
    }*/
}

【问题讨论】:

    标签: http java-me connection


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

      你最好试试

       outputStream = connection.openDataOutputStream();
      

      而不是

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

      在 HttpClientConnection 类中

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多