<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 33,comments - 21,trackbacks - 0

    一、“NetConnection”簡介:
    轉述Matrix上zhengyun_ustc所述:“你的HttpConnection是否封裝的足夠健壯呢?遇到各種情況,你是否有信心應對呢?譬如說,你要請求的Response包實在太大,以至于運營商給你掐了告訴你說超時;譬如說你是不是總要自己寫一個線程來專門作http連接?譬如說有一些移動運營商設置了caching proxy servers,妨礙了你的測試。”
    為了解決這個問題,一位日本程序員“JAY-F”針對MIDP1.0提供了一種robust的“NetConnection”封裝。這個HttpConnnection類負責管理連接并易于使用。
    二、“NetConnection”特性:
    1. 跨過Proxy-server阻礙:
    一些移動網絡放置了代理服務器用來提高訪問速度,但是它的cache也成為了開發人員測試/調試程序的一大障礙。“NetConnection”類使用一個簡單的http request屬性將server上的代理功能關閉掉。
    2. 使用線程分離的連接模式:
    本類可以使用單線程、多線程兩種模式運行,只要設置一個簡單的標志即可。
    3. 支持Http request range:
    由于服務商在其網絡上可能存在一些針對回應數據最大長度的限制,所以“NetConnection”類提供了構造request URL的功能使回應數據分為多個數據包。從而去除了前面的限制。
    三、netConnection是如何實現的?
    1。netConnection類結構分析:
    此類實現了Runnable接口,其運行模式支持多線程模式:當前只能由一個線程使用資源,其它線程wait。
    此類使用了一些靜態成員變量:

    				
    ????????//當前只能由一個線程使用singleton。
    ????????private static NetConnection singleton = new NetConnection();

    ????????private static HttpConnection httpConn;

    ????????private static String url;

    ????????private static String method;

    ????????private static byte[] data;
    ????????????????

    ????????private static String contentType;
    ????????

    ????????private static long lowRange;
    ????????

    ????????private static long highRange;
    ????????

    ????????private static boolean disableProxy;
    ????????

    ????????private static boolean detached;
    ????????
    ????????private static byte[] response;

    類方法:

    //線程run方法
    public void run()

    //當前運行的線程執行完畢后,通報給其它的由于等待資源而wait狀態的線程
    private synchronized void forceNotify()

    //當資源正在被其它線程使用時,當前線程進入wait狀態
    private synchronized void forceWait()

    //關閉http連接
    private static void severConnection()

    由于使用了這些static成員變量,所以一些操作方法需要同步(synchronized)。
    2。netConnection核心代碼解析:
    netConnection類的實現思想很簡單,就是設置一些request屬性和對于GET方法構造一個特殊的URL。更重要的是其作者對http協議的深入理解、嚴謹的代碼風格值得吾輩學習、研究。這也是本人分析其核心代碼的一大原因。

    /**
    * 實現了連接邏輯。
    * 調用者可以在分離的線程中使用netConnection類的靜態連接。
    * @throws IllegalStateException 如果此方法直接其它類調用則拋出該異常
    */
    public void run() {
    ????????
    ????????if (url == null) {
    ????????????????throw new IllegalStateException("Cannot invoke this method!");
    ????????}

    ????????
    ????????DataOutputStream dos = null;
    ????????DataInputStream dis = null;
    ????????StringBuffer buffer = null;

    ????????try {

    ????????????????int permissions = 0;
    ????????????????
    ????????????????//根據method值,設置Connector的權限(READ/READ_WRITE)
    ????????????????if (HttpConnection.GET.equals(method)) {
    ????????????????????????permissions = Connector.READ;
    ????????????????} else if (HttpConnection.POST.equals(method)) {
    ????????????????????????permissions = Connector.READ_WRITE;
    ????????????????}
    ????????????????
    ????????????????//如果關閉server代理功能,則構造noProxyUrl。
    ????????????????//原理:使用timestamp作為該URL中no-proxy參數值,
    ????????????????//????????致使server視其為client發來的新請求。
    ????????????????if (disableProxy) {
    ????????????????????????
    ????????????????????????boolean hasQueryParams = false;
    ????????????????????????
    ????????????????????????char[] ca = url.toCharArray();
    ????????????????????????//判斷原URL中是否含有參數
    ????????????????????????for (int loop = 0; loop < url.length(); loop++) {
    ????????????????????????????????
    ????????????????????????????????if (ca[loop] == '?') {
    ????????????????????????????????????????hasQueryParams = true;
    ????????????????????????????????????????break;
    ????????????????????????????????}
    ????????????????????????}
    ????????????????????????
    ????????????????????????//由于需要多次字符串拼接,所以使用可提供效率的StringBuffer類
    ????????????????????????StringBuffer noProxyUrl = new StringBuffer();

    ????????????????????????//將原URL內容復制到noProxyUrl
    ????????????????????????noProxyUrl.append(url);

    ????????????????????????//如果原URL中含有參數,
    ????????????????????????//??則需要在noProxyUrl中增加"&",
    ????????????????????????//??否則直接在noProxyUrl中增加"?",
    ????????????????????????//??這樣做為了后面增加no-proxy參數做準備。
    ????????????????????????if (hasQueryParams) {
    ????????????????????????????????noProxyUrl.append("&");
    ????????????????????????} else {
    ????????????????????????????????noProxyUrl.append("?");
    ????????????????????????}

    ????????????????????????//增加no-proxy參數
    ????????????????????????noProxyUrl.append("no-proxy=");
    ????????????????????????noProxyUrl.append(System.currentTimeMillis()); // timestamp
    ????????????????????????
    ????????????????????????//將構造好的noProxyUrl復制到原URL
    ????????????????????????url = noProxyUrl.toString();
    ????????????????}
    ????????????????
    ????????????????

    ????????????????// 打開Http 連接
    ????????????????httpConn = (HttpConnection) Connector.open(url, permissions, true);
    ????????????????//設置request方法
    ????????????????httpConn.setRequestMethod(method);

    ????????????????//如果request權限為READ(即request方法為GET),
    ????????????????//則需要設置http request屬性的Range。
    ????????????????//原理:設置http request屬性的Range后的,
    ????????????????//????????server接收到該request后將把response數據分成小部分發回。
    ????????????????//????????從而避免了部分運營商對http response size的限制。
    ????????????????if (permissions == Connector.READ) {????????
    ????????????????????????if (lowRange > -1 && lowRange < highRange) {
    ????????????????????????????????StringBuffer range = new StringBuffer();
    ????????????????????????????????
    ????????????????????????????????range.append("bytes=");
    ????????????????????????????????range.append(lowRange);
    ????????????????????????????????range.append("-");
    ????????????????????????????????range.append(highRange);
    ????????????????????????????????
    ????????????????????????????????httpConn.setRequestProperty("Range", range.toString());
    ????????????????????????}
    ????????????????//否則,request權限為READ_WRITE(即request方法為POST),
    ????????????????//那么設置request的Content-Type屬性。
    ????????????????} else if (permissions == Connector.READ_WRITE) {
    ????????????????????????// POST request
    ????????????????????????httpConn.setRequestProperty("Content-Type", contentType);
    ????????????????????????dos = httpConn.openDataOutputStream();
    ????????????????????????dos.write(data);
    ????????????????}
    ????????
    ????????} catch (Exception e) {
    ????????
    ????????????????exceptionPipe = e;
    ????????????????//如果程序運行在多線程模式,則在異常發生后需要喚醒其它睡眠的線程繼續run
    ????????????????if (detached) {
    ????????????????????????forceNotify();
    ????????????????}
    ????????????????
    ????????????????return;
    ????????????????
    ????????} finally {

    ????????????????try {
    ????????????????????????try {
    ????????????????????????????????if (dos != null) {
    ????????????????????????????????????????// 關閉dos
    ????????????????????????????????????????dos.close();
    ????????????????????????????????}
    ????????????????????????} catch (Exception e) {
    ????????????????????????????????// 如果程序運行在多線程模式,則在異常發生后需要喚醒其它睡眠的線程繼續run
    ????????????????????????????????if (exceptionPipe == null) {
    ????????????????????????????????????????exceptionPipe = e;
    ????????????????????????????????????????
    ????????????????????????????????????????if (detached) {
    ????????????????????????????????????????????????forceNotify();
    ????????????????????????????????????????}
    ????????????????????????????????????????return;
    ????????????????????????????????}
    ????????????????????????} finally {
    ????????????????????????????????dos = null;
    ????????????????????????}
    ????????????????????????
    ????????????????????????// 讀取http連接的回應代碼
    ????????????????????????int responseCode = httpConn.getResponseCode();
    ????????????????????????
    ????????????????????????//當request方法為GET,并設置了request range時,接收到的回應代碼為HTTP_PARTIAL
    ????????????????????????//當request方法為POST,接收到的回應代碼為HTTP_OK
    ????????????????????????//如果上述兩種回應代碼均沒有收到,則表明連接失敗或者出問題
    ????????????????????????if (responseCode != HttpConnection.HTTP_OK
    ????????????????????????????????????????&& responseCode != HttpConnection.HTTP_PARTIAL) {

    ????????????????????????????????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;
    ????????????????????????????????}
    ????????????????????????}

    ????????????????????????//如果收到了上述的兩種回應代碼之一,則可以繼續讀取server的response數據
    ????????????????????????dis = httpConn.openDataInputStream();

    ????????????????????????//循環讀取repsonse數據
    ????????????????????????int ch;
    ????????????????????????buffer = new StringBuffer();
    ????????????????while ((ch = dis.read()) != -1) {
    ????????????????????????buffer.append((char) ch);
    ????????????????}

    ????????????????//將response數據進行必要的編碼轉換????????????????
    ????????????????????????response = buffer.toString().getBytes("ISO8859_1");
    ????????????????????????//接收到回應后,表明整個http會話過程結束,線程將結束。
    ????????????????????????//如果程序運行在多線程模式,則此時需要喚醒其它睡眠的線程繼續run
    ????????????????????????if (detached) {
    ????????????????????????????????forceNotify();
    ????????????????????????}
    ????????????????????????
    ????????????????????????return;

    ????????????????} catch (Exception e) {
    ????????????????????????
    ????????????????????????if (exceptionPipe == null) {
    ????????????????????????????????exceptionPipe = e;
    ????????????????????????????????
    ????????????????????????????????if (detached) {
    ????????????????????????????????????????forceNotify();
    ????????????????????????????????}
    ????????????????????????????????
    ????????????????????????????????return;
    ????????????????????????}
    ????????????????} finally {
    ????????????????????
    ????????????????????????try {
    ????????????????????????????????if (dis != null) {
    ????????????????????????????????????????// 關閉dis
    ????????????????????????????????????????dis.close();
    ????????????????????????????????}
    ????????????????????????} catch (Exception e) {
    ????????????????????????????????// 若關閉dis時發生異常,則進行異常處理
    ????????????????????????????????if (exceptionPipe == null) {
    ????????????????????????????????????????exceptionPipe = e;
    ????????????????????????????????????????
    ????????????????????????????????????????if (detached) {
    ????????????????????????????????????????????????forceNotify();
    ????????????????????????????????????????}
    ????????????????????????????????????????return;
    ????????????????????????????????}
    ????????????????????????} finally {
    ????????????????????????????????dis = null;
    ????????????????????????}
    ????????????????????????
    ????????????????????????try {
    ????????????????????????????????if (httpConn != null) {
    ????????????????????????????????????????//關閉http連接
    ????????????????????????????????????????httpConn.close();

    ????????????????????????????????????????httpConn = null;
    ????????????????????????????????}
    ????????????????????????} catch (Exception e) {

    ????????????????????????????????if (exceptionPipe == null) {
    ????????????????????????????????????????exceptionPipe = e;
    ????????????????????????????????????????
    ????????????????????????????????????????if (detached) {
    ????????????????????????????????????????????????forceNotify();
    ????????????????????????????????????????}
    ????????????????????????????????????????return;
    ????????????????????????????????}
    ????????????????????????}
    ????????????????}
    ????????}
    }

    五、參考資料:
    聯系netConnection作者:JAY-F
    源代碼下載
    HTTP/1.1定義
    posted on 2007-03-17 18:00 英明 閱讀(1246) 評論(0)  編輯  收藏 所屬分類: J2ME
    主站蜘蛛池模板: 99久久成人国产精品免费| 特a级免费高清黄色片 | mm1313亚洲国产精品无码试看| 在线视频免费国产成人| 国产日韩AV免费无码一区二区三区 | 中文字幕在亚洲第一在线 | 亚洲第一黄片大全| 无码日韩精品一区二区免费暖暖| 亚洲娇小性xxxx色| 国产亚洲精品不卡在线| 国产人成免费视频网站| 黄色网页免费观看| 亚洲天堂一区在线| 亚洲视频人成在线播放| 一个人看的www在线观看免费 | 大陆一级毛片免费视频观看i| 久久久久久噜噜精品免费直播| 国产AV旡码专区亚洲AV苍井空 | 污视频网站在线观看免费| 亚洲精品乱码久久久久久下载| 亚洲av无码专区在线观看素人| 日本h在线精品免费观看| 成人免费一区二区三区| 亚洲熟女www一区二区三区| 久久精品国产亚洲AV网站| 免费国产成人高清视频网站| 18禁网站免费无遮挡无码中文| 两个人www免费高清视频| 风间由美在线亚洲一区| 亚洲国产福利精品一区二区| 精品久久久久久亚洲| 国产乱子伦片免费观看中字| 在线看片v免费观看视频777| 你懂的在线免费观看| 又硬又粗又长又爽免费看| 亚洲综合在线一区二区三区| 在线免费观看亚洲| 久久亚洲精品视频| 亚洲中文字幕在线乱码| 亚洲精品无码成人片在线观看 | 免费人成毛片动漫在线播放|