国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

MIDP 1.0 HttpConnection類的robust封裝

2019-11-18 16:17:45
字體:
供稿:網(wǎng)友

  一、“NetConnection”簡介:

轉(zhuǎn)述Matrix上zhengyun_ustc所述:“你的HttpConnection是否封裝的足夠健壯呢?遇到各種情況,你是否有信心應(yīng)對呢?譬如說,你要請求的Response包實(shí)在太大,以至于運(yùn)營商給你掐了告訴你說超時;譬如說你是不是總要自己寫一個線程來專門作http連接?譬如說有一些移動運(yùn)營商設(shè)置了caching PRoxy servers,妨礙了你的測試。”

為了解決這個問題,一位日本程序員“JAY-F”針對MIDP1.0提供了一種robust的“NetConnection”封裝。這個HttpConnnection類負(fù)責(zé)管理連接并易于使用。

二、“NetConnection”特性:

1. 跨過Proxy-server阻礙:

一些移動網(wǎng)絡(luò)放置了代理服務(wù)器用來提高訪問速度,但是它的cache也成為了開發(fā)人員測試/調(diào)試程序的一大障礙。“NetConnection”類使用一個簡單的http request屬性將server上的代理功能關(guān)閉掉。

2. 使用線程分離的連接模式:

本類可以使用單線程、多線程兩種模式運(yùn)行,只要設(shè)置一個簡單的標(biāo)志即可。

3. 支持Http request range:

由于服務(wù)商在其網(wǎng)絡(luò)上可能存在一些針對回應(yīng)數(shù)據(jù)最大長度的限制,所以“NetConnection”類提供了構(gòu)造request URL的功能使回應(yīng)數(shù)據(jù)分為多個數(shù)據(jù)包。從而去除了前面的限制。

三、netConnection是如何實(shí)現(xiàn)的?

1。netConnection類結(jié)構(gòu)分析:

此類實(shí)現(xiàn)了Runnable接口,其運(yùn)行模式支持多線程模式:當(dāng)前只能由一個線程使用資源,其它線程wait。

此類使用了一些靜態(tài)成員變量:

        //當(dāng)前只能由一個線程使用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()

//當(dāng)前運(yùn)行的線程執(zhí)行完畢后,通報(bào)給其它的由于等待資源而wait狀態(tài)的線程
private synchronized void forceNotify()

//當(dāng)資源正在被其它線程使用時,當(dāng)前線程進(jìn)入wait狀態(tài)
private synchronized void forceWait()

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


由于使用了這些static成員變量,所以一些操作方法需要同步(synchronized)。

2。netConnection核心代碼解析:

netConnection類的實(shí)現(xiàn)思想很簡單,就是設(shè)置一些request屬性和對于GET方法構(gòu)造一個特殊的URL。更重要的是其作者對http協(xié)議的深入理解、嚴(yán)謹(jǐn)?shù)拇a風(fēng)格值得吾輩學(xué)習(xí)、研究。這也是本人分析其核心代碼的一大原因。

/**
* 實(shí)現(xiàn)了連接邏輯。
* 調(diào)用者可以在分離的線程中使用netConnection類的靜態(tài)連接。
* @throws IllegalStateException 如果此方法直接其它類調(diào)用則拋出該異常
*/
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;
                
                //根據(jù)method值,設(shè)置Connector的權(quán)限(READ/READ_WRITE)
                if (HttpConnection.GET.equals(method)) {
                        permissions = Connector.READ;
                } else if (HttpConnection.POST.equals(method)) {
                        permissions = Connector.READ_WRITE;
                }
                
                //如果關(guān)閉server代理功能,則構(gòu)造noProxyUrl。
                //原理:使用timestamp作為該URL中no-proxy參數(shù)值,
                //        致使server視其為client發(fā)來的新請求。
                if (disableProxy) {
                        
                        boolean hasQueryParams = false;
                        
                        char[] ca = url.toCharArray();
                        //判斷原URL中是否含有參數(shù)
                        for (int loop = 0; loop < url.length(); loop++) {
                                
                                if (ca[loop] == '?') {
                                        hasQueryParams = true;
                                        break;
                                }
                        }
                        
                        //由于需要多次字符串拼接,所以使用可提供效率的StringBuffer類
                        StringBuffer noProxyUrl = new StringBuffer();

                        //將原URL內(nèi)容復(fù)制到noProxyUrl
                        noProxyUrl.append(url);

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

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

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

                //如果request權(quán)限為READ(即request方法為GET),
                //則需要設(shè)置http request屬性的Range。
                //原理:設(shè)置http request屬性的Range后的,
                //        server接收到該request后將把response數(shù)據(jù)分成小部分發(fā)回。
                //        從而避免了部分運(yùn)營商對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權(quán)限為READ_WRITE(即request方法為POST),
                //那么設(shè)置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;
                //如果程序運(yùn)行在多線程模式,則在異常發(fā)生后需要喚醒其它睡眠的線程繼續(xù)run
                if (detached) {
                        forceNotify();
                }
                
                return;
                
        } finally {

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

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

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

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

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

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

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


五、參考資料:

聯(lián)系netConnection作者:JAY-F
源代碼下載
HTTP/1.1定義

(出處:http://m.survivalescaperooms.com)



發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 衡阳县| 镇宁| 云龙县| 肥西县| 安顺市| 任丘市| 井陉县| 施秉县| 遂溪县| 赤城县| 文水县| 威海市| 铜梁县| 武胜县| 稻城县| 茌平县| 阳山县| 靖安县| 禹州市| 肇源县| 新和县| 崇义县| 西藏| 咸丰县| 巫山县| 澄城县| 建宁县| 双柏县| 馆陶县| 宁武县| 龙南县| 韩城市| 黄骅市| 昭苏县| 临江市| 康定县| 平阳县| 白河县| 盘锦市| 锦屏县| 禄丰县|