作者:
Confach 发表于2006-04-28 21:40 pm
版权信息:可以任意转载, 转载时请务必以超链接形式标明文章
原始出处和作者信息.
http://www.cnblogs.com/confach/articles/387906.html
6
第6章 连接网络
|
HTTP和socket连接
使用HTTP连接
使用HTTPS连接
使用socket连接
使用端口(port)连接
使用蓝牙序列端口连接
|
HTTP和Socket连接
尽管你可以通过socket连接实现HTTP,但是最好使用HTTP连接,因为socket连接不支持BlackBerry MDS服务特性,例如push。也最好使用HTTP连接,因为比起那些使用HTTP连接的应用程序,使用socket连接的应用程序明显需要更多的带宽。
注:如果你使用socket连接,将你的应用程序设计为适应断断续续的无线网络连接。例如,如果你的程序发生错误时,它会重新打开连接。
注:使用BlackBerry Internet Service Browser的java程序不会启动HTTP,HTTPS和TCP连接。
为了打开一个HTTP连接,调用Connector.open(),指定http为协议。将返回的对象转化为一个HTTPConnection或者StreamConnection对象。HttpConnection是一个StreamConnection,它提供访问指定HTTP功能,包括HTTP头和其他HTTP资源。
|
HttpConnection conn = null;
String URL = "http://www.myServer.com/myContent";
conn = (HttpConnection)Connector.open(URL);
|
设置HTTP请求方式
为设置HTTP请求方式(GET或POST),调用HttpConnection.setRequestMethod().
|
conn.setRequestMethod(HttpConnection.POST);
|
为HTTP请求或HTTP响应消息设置或获取头字段,调用HttpConnection 上的getRequestProperty() 或setRequestProperty()。
|
conn.setRequestProperty("User-Agent", "BlackBerry/3.2.1");
String lang = conn.getRequestProperty("Content-Language");
|
为发送和接受数据,调用HTTPConnection的openInputStream()和openOutputStream()获得输入和输出流。
|
InputStream in = conn.openInputStream();
OutputStream out = conn.openOutputStream();
|
HttpFetch.java 实例使用了一个HTTP 连接来获取数据。它遵循下列步骤:
-
创建一个连接线程。
-
定义一个方法获取数据。
-
定义一个方法将数据显示给用户。
-
定义一个方法退出应用程序。
-
定义应用程序构造子。
注:HTTPFetch.java实例需要你在应用程序工程里创建资源文件,并且定义需要的资源键值。参看125页“本地化应用程序”获得更多信息。
例:HTTPFetch.java
/**
* HTTPFetch.java
* Copyright (C) 2001-2005 Research In Motion Limited. All rights reserved.
*/
package com.rim.samples.docs.httpfetch;
import net.rim.device.api.ui.*;
import net.rim.device.api.ui.component.*;
import net.rim.device.api.ui.container.*;
import net.rim.device.api.i18n.*;
import net.rim.device.api.system.*;
import javax.microedition.io.*;
import java.io.*;
import com.rim.samples.docs.baseapp.*;
import com.rim.samples.docs.resource.*;
public class HTTPFetch extends BaseApp implements HTTPFetchResource
{
// Constants.
private static final String SAMPLE_PAGE = "http://localhost/testpage/sample.txt”;
private static final String[] HTTP_PROTOCOL = {"http://", “http:\\”};
private MainScreen _mainScreen;
private RichTextField _content;
/**
* Send and receive data over the network on a
* separate thread from the main thread of your application.
*/
ConnectionThread _connectionThread = new ConnectionThread();
//statics
private static ResourceBundle _resources = ResourceBundle.getBundle(
HTTPFetchResource.BUNDLE_ID, HTTPFetchResource.BUNDLE_NAME);
public static void main(String[] args)
{
HTTPFetch theApp = new HTTPFetch();
theApp.enterEventDispatcher();
}
/**
* The ConnectionThread class manages the HTTP connection.
* Fetch operations are not queued, but if a second fetch request
* is made while a previous request is still active,
* the second request stalls until the previous request completes.
*/
private class ConnectionThread extends Thread
{
private static final int TIMEOUT = 500; //ms
private String _theUrl;
/* The volatile keyword indicates that because the data is shared,
* the value of each variable must always be read and written from memory,
* instead of cached by the VM. This technique is equivalent to wrapping
* the shared data in a synchronized block, but produces less overhead.
*/
private volatile boolean _start = false;
private volatile boolean _stop = false;
/**
* Retrieve the URL. The synchronized keyword makes sure that only one
* thread at a time can call this method on a ConnectionThread object.
*/
public synchronized String getUrl()
{
return _theUrl;
}
/**
* Fetch a page. This method is invoked on the connection thread by
* fetchPage(), which is invoked in the application constructor when
* the user selects the Fetch menu item.
*/
public void fetch(String url)
{
_start = true;
_theUrl = url;
}
/**
* Close the thread. Invoked when the application exits.
*/
public void stop()
{
_stop = true;
}
/**
* Open an input stream and extract data. Invoked when the thread
* is started.
*/
public void run()
{
for(;;)
{
// Thread control.
while( !_start && !_stop)
{
// No connections are open for fetch requests,
// but the thread has not been stopped.
try
{
sleep(TIMEOUT);
}
catch (InterruptedException e)
{
System.err.println(e.toString());
}
}
// Exit condition.
if ( _stop )
{
return;
}
/* Ensure that fetch requests are not missed
* while received data is processed.
*/
synchronized(this)
{
// Open the connection and extract the data.
StreamConnection s = null;
try
{
s = (StreamConnection)Connector.open(getUrl());
InputStream input = s.openInputStream();
// Extract data in 256 byte chunks.
byte[] data = new byte[256];
int len = 0;
StringBuffer raw = new StringBuffer();
while ( -1 != (len = input.read(data)) )
{
raw.append(new String(data, 0, len));
}
String text = raw.toString();
updateContent(text);
input.close();
s.close();
}
catch (IOException e)
{
System.err.println(e.toString());
// Display the text on the screen.
updateContent(e.toString());
}
// Reset the start state.
_start = false;
}
}
}
}
// Constructor.
public HTTPFetch()
{
_mainScreen = new MainScreen();
_mainScreen.setTitle(new LabelField(
_resources.getString(APPLICATION_TITLE), LabelField.ELLIPSIS
| LabelField.USE_ALL_WIDTH));
_mainScreen.add(new SeparatorField());
_content = new RichTextField(
_resources.getString(HTTPDEMO_CONTENT_DEFAULT));
_mainScreen.add(_content);
_mainScreen.addKeyListener(this);
_mainScreen.addTrackwheelListener(this);
// Start the helper thread.
_connectionThread.start();
pushScreen(_mainScreen);
fetchPage(SAMPLE_PAGE);
}
// Retrieve web content.
private void fetchPage(String url)
{
// Perform basic validation (set characters to lowercase and add http:// or https://).
String lcase = url.toLowerCase();
boolean validHeader = false;
int i = 0;
for (i = HTTP_PROTOCOL.length - 1; i >= 0; --i)
{
if ( -1 != lcase.indexOf(HTTP_PROTOCOL[i]) )
{
validHeader = true;
break;
}
}