您的位置:首页 > 理论基础 > 计算机网络

J2ME连接HTTP,获取网页信息的联网类

2010-11-05 15:19 344 查看
import java.io.DataInputStream;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;
import javax.microedition.io.Connector;
import javax.microedition.io.HttpConnection;
import javax.microedition.io.HttpsConnection;
import javax.microedition.lcdui.Display;
import com.ucweb.east.ui.DisplayScreen;
import com.ucweb.log.Logger;

public class HttpConnect extends Thread {
//http请求常量
//浏览器可接受的MIME类型
public static final String REQUSET_HEADER_ACCEPT = "Accept";
public static final String REQUEST_HEADER_USER_AGENT = "User-Agent";
//浏览器所希望的语言种类
public static final String REQUSET_HEADER_CONTENT_LANGUAGE = "Content-Language";
public static final String REQUSET_HEADER_CONTENT_TYPE = "Content-Type";
//表示是否需要持久连接
public static final String REQUSET_HEADER_CONNECTION_OPTION = "Connection";
//http回应常量
public static final String RESPONSE_HEADER_DATE = "Date";
public static final String RESPONSE_HEADER_SERVER = "Server";
public static final String RESPONSE_HEADER_MODIFIEDDATE = "Last-Modified";
public static final String RESPONSE_HEADER_CONTENT_ENCODING = "Content-Encoding";
//表示回应消息正文的长度
public static final String RESPONSE_HEADER_CONTENT_LENGTH = "Content-Length";
public static final String RESPONSE_HEADER_CONTENT_TYPE = "Content-Type";
//重定向的最大次数
private static final int MAX_REDIRECTS = 7;
//计算重定向的次数
private int iRedirectCount = 0;
private String iURL;
private Display iDisplay = null;
private DisplayScreen iDisplayScreen = null;

public HttpConnect(String aURL, Display aDis) {
this.iURL = aURL;
iDisplay = aDis;
}

public void run() {
String sTempResult;
try {
sTempResult = getConnect();
if (sTempResult == null) {
sTempResult = "获取不到网页内容";
Logger.logWarn("获取的网页为空");
}
iDisplayScreen = DisplayScreen.getInstance();
iDisplayScreen.init(sTempResult);
iDisplay.setCurrent(iDisplayScreen);
} catch (IOException ex) {
Logger.logError("线程运行出现异常", ex);
}
}

/**
* 连接URL地址,并返回网页的源代码
* @param
* @return String
*/
public String getConnect() throws IOException {
HttpConnection sConn = null;
DataInputStream sIs = null;
String sReponseData = null;
int sStatus = 0;
int sIdx = 0;
sIdx = iURL.indexOf("://");
if (sIdx == -1) {
throw new IllegalArgumentException("URL must start with the protocol.");
}
try {
sConn = (HttpConnection) Connector.open(iURL);
this.setRequestMethod(sConn, HttpConnection.GET);
Hashtable requestHeaderPair = new Hashtable();
requestHeaderPair.put(REQUSET_HEADER_CONTENT_TYPE, "application/octet-stream");
//传入MIDP和自身版本号,以便服务器能识别此请求来自MIDP应用程序,并且根据版本号发送相应的相应
requestHeaderPair.put(REQUEST_HEADER_USER_AGENT, "Profile/MIDP-2.1 Configuration/CLDC-1.0");
requestHeaderPair.put(REQUSET_HEADER_CONTENT_LANGUAGE, "en-US");
requestHeaderPair.put(REQUSET_HEADER_ACCEPT, "application/octet-stream");
requestHeaderPair.put(REQUSET_HEADER_CONNECTION_OPTION, "Keep-Alive");
this.putRequestHeader(sConn, requestHeaderPair);
sStatus = sConn.getResponseCode();
String sRedirection = sConn.getHeaderField("Location");
//处理返回码301
if (sStatus == HttpConnection.HTTP_MOVED_PERM || sStatus == HttpsConnection.HTTP_SEE_OTHER) {
if (sRedirection != null) {
iURL = sRedirection;
iRedirectCount++;
if (iRedirectCount < MAX_REDIRECTS) {
try {
sConn.close();
} catch (IOException ex) {
Logger.logWarn("HttpConnect: 在重定向时关闭连接失败.", ex);
}
return getConnect();
}
}
//处理返回码302
} else if (sStatus == HttpConnection.HTTP_MOVED_TEMP) {
if (sRedirection != null) {
iURL = sRedirection;
iRedirectCount++;
if (iRedirectCount < MAX_REDIRECTS) {
try {
sConn.close();
} catch (IOException ex) {
Logger.logWarn("HttpConnect: 在重定向时关闭连接失败.", ex);
}
closeConnection(sConn, sIs);
return getConnect(); //必须加上return,否则会返回空值
}
//等待10-1000ms,直到状态码从302转变为200。马上处理响应,当作没有错误发生
} else {
long sBeginWait = System.currentTimeMillis();
while (System.currentTimeMillis() - sBeginWait < 1000 || sStatus != HttpConnection.HTTP_OK) {
sleep(100);
sStatus = sConn.getResponseCode();
}
}
} else if (sStatus != HttpConnection.HTTP_OK) {
Logger.logInfo("HttpConnect response code: " + sConn.getResponseCode());
}
if (sStatus == HttpConnection.HTTP_OK) {
sIs = sConn.openDataInputStream();
sReponseData = (String) this.getResponseData(sConn, sIs);
}
} catch (Exception ex) {
Logger.logDebug("Exception: " + ex.getClass() + ": " + ex.getMessage());
} finally {
closeConnection(sConn, sIs);
iRedirectCount = 0;
}
return sReponseData;
}

/**
* 关闭流
* @param aConn HttpConnection,aIs DataInputStream
* @return boolean
*/
public void closeConnection(HttpConnection aConn,DataInputStream aIs) {
try{
if (aIs != null) {
aIs.close();
}
if (aConn != null) {
aConn.close();
}
}catch (Exception ex) {
Logger.logWarn("关闭连接失败.",ex);
}
}

/**
* 设置请求Header信息
* @param aConn HttpConnection,aKey String,aKeyValue String
* @return boolean
*/
public boolean putRequestHeaderProperty(HttpConnection aConn, String aKey, String aKeyValue) {
try {
aConn.setRequestProperty(aKey, aKeyValue);
return true;
} catch (Exception ex) {
Logger.logWarn("设置HTTP请求Header的信息异常.",ex);
}
return false;
}

/**
* 获取响应Header信息
* @param aConn HttpConnection,aKey String
* @return void
*/
public String getResponseHeaderProperty(HttpConnection aConn, String aKey) {
return aConn.getRequestProperty(aKey);
}

/**
* 设置请求的Header信息
* @param aConn HttpConnection,aPropertiesPair Hashtable
* @return void
*/
public boolean putRequestHeader(HttpConnection aConn, Hashtable aPropertiesPair) {
Enumeration sKeyEnumer = aPropertiesPair.keys();
boolean isResult = true;
while (sKeyEnumer.hasMoreElements()) {
String sKeyName = (String) sKeyEnumer.nextElement();
String sKeyValue = (String) aPropertiesPair.get(sKeyName);
if (putRequestHeaderProperty(aConn, sKeyName, sKeyValue) == false) {
isResult = false;
}
}
return isResult;
}

/**
* 设置网络连接的方式
* @param aConn HttpConnection,aMethodName String
* @return boolean
*/
public boolean setRequestMethod(HttpConnection aConn, String aMethodName) {
try {
aConn.setRequestMethod(aMethodName);
return true;
} catch (Exception ex) {
Logger.logWarn("设置网络连接方式出现异常",ex);
return false;
}
}

/**
* 获取网页返回的数据,用byte[]流来原封不动读取网页的源代码
* @param aConn HttpConnection,aIs InputStream
* @return void
*/
public Object getResponseData(HttpConnection aConn, DataInputStream sIs) {
boolean isWap = true;
byte[] sData = null;
String sType = null;
int sLen = 0;
try {
sType = aConn.getHeaderField(RESPONSE_HEADER_CONTENT_TYPE);
sLen = Integer.parseInt(getResponseHeaderProperty(aConn, RESPONSE_HEADER_CONTENT_LENGTH));
} catch (IOException ex) {
Logger.logWarn("出现IO异常 " + ex);
} catch (Exception ex) {
Logger.logWarn("出现异常", ex);
sLen = 0;
}
if (sLen > 0) {
int sActual = 0; //每一次实际读取的字节数
int sBytesread = 0; //总读取的字节数
sData = new byte[sLen];
while ((sBytesread != sLen) && (sActual != -1)) {
try {
sActual = sIs.read(sData, sBytesread, sLen - sBytesread);
sBytesread += sActual;
} catch (Exception ex) {
Logger.logDebug("读取网页源代码出现异常: " + ex.getMessage());
return null;
}
}
} else {
int sCh = 0;
Vector sVbuffer = new Vector();
try {
while ((sCh = sIs.read()) != -1) {
sVbuffer.addElement(new Integer(sCh));
}
} catch (Exception ex) {
Logger.logDebug("读取网页源代码出现异常: " + ex.getMessage());
return null;
}
sLen = sVbuffer.size();
sData = new byte[sLen];
for (int i = 0; i < sLen; i++) {
sData[i] = ((Integer) sVbuffer.elementAt(i)).byteValue();
}
}
String sResult = new String(sData);
isWap = judgeContentType(sType);
return setEncode(sResult, sData, sType, isWap);
}

/**
* 根据网页的编码进行自动编码转换
* @param aConn HttpConnection,aIs InputStream
* @return void
*/
public String setEncode(String aResult, byte[] aData, String aType, boolean isWap) {
if (aData.length == 0) {
Logger.logInfo("要转化编码的数据为空");
return null;
}
if (aType.length() == 0) {
Logger.logInfo("没有要转化的编码类型");
return null;
}
String sTempType = null;
if (isWap) {
int sWapFlagBeginPosition = aResult.indexOf("encoding=");
if (sWapFlagBeginPosition > 0) {
//获取双引号之前的字符位置 ,/042表示双引号
sWapFlagBeginPosition = aResult.indexOf("/042", sWapFlagBeginPosition);
int sWapFlagEndPosition = aResult.indexOf("/042", sWapFlagBeginPosition + "/042".length());
if (sWapFlagEndPosition > sWapFlagBeginPosition) {
//获取网页的编码格式
sTempType = aResult.substring(sWapFlagBeginPosition + "/042".length(), sWapFlagEndPosition);
}
} else {
int sWapTypeBeginPosition = aType.indexOf("charset=");
sTempType = aType.substring(sWapTypeBeginPosition + "charset=".length());
sTempType = sTempType.trim();
}
} else {
int sFlagBeginPosition = aResult.indexOf("charset=");
//获取双引号之前的字符位置 ,/042表示双引号
int sFlagEndPosition = aResult.indexOf("/042", sFlagBeginPosition);
if (sFlagEndPosition > sFlagBeginPosition) {
//获取网页的编码格式
sTempType = aResult.substring(sFlagBeginPosition + "charset=".length(), sFlagEndPosition);
}
}
System.out.println("编码类型: "+sTempType);
if (sTempType != null) {
try {
//根据编码格式对获取网页的源代码进行编码转换
aResult = new String(aData, sTempType);
} catch (Exception ex) {
Logger.logWarn("出现编码转换异常", ex);
}
}
return aResult;
}

/**
* 判断返回的网页是html还是wml
* @param String aType
* @return boolean
*/
public boolean judgeContentType(String aType){
int sContentTypePosition = 0;
if(iURL.indexOf("wap") > 0){
return true;
}
if(iURL.indexOf("www")> 0 ){
return false;
}
if(aType != null){
sContentTypePosition = aType.indexOf("wml");
}
if(sContentTypePosition > 0){
return true;
}else{
return false;
}
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: