Android http 请求

来源:互联网 发布:券商研究员 知乎 编辑:程序博客网 时间:2024/05/29 17:18

转载来自:Alex Zhou,本文链接:http://codingnow.cn/android/723.html

这篇文章主要实现了在Android中使用JDK的HttpURLConnection和Apache的HttpClient访问网络资源,服务端采用python+flask编写,使用Servlet太麻烦了。关于Http协议的相关知识,可以在网上查看相关资料。代码比较简单,就不详细解释了。

1. 使用JDK中HttpURLConnection访问网络资源

(1)get请求

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
public String executeHttpGet() {
        String result =null;
        URL url =null;
        HttpURLConnection connection =null;
        InputStreamReader in =null;
        try{
            url =newURL("http://10.0.2.2:8888/data/get/?token=alexzhou");
            connection = (HttpURLConnection) url.openConnection();
            in =newInputStreamReader(connection.getInputStream());
            BufferedReader bufferedReader =newBufferedReader(in);
            StringBuffer strBuffer =newStringBuffer();
            String line =null;
            while((line = bufferedReader.readLine()) !=null) {
                strBuffer.append(line);
            }
            result = strBuffer.toString();
        }catch(Exception e) {
            e.printStackTrace();
        }finally{
            if(connection !=null) {
                connection.disconnect();
            }
            if(in !=null) {
                try{
                    in.close();
                }catch(IOException e) {
                    e.printStackTrace();
                }
            }
 
        }
        returnresult;
    }

注意:因为是通过android模拟器访问本地pc服务端,所以不能使用localhost和127.0.0.1,使用127.0.0.1会访问模拟器自身。Android系统为实现通信将PC的IP设置为10.0.2.2

(2)post请求

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
public String executeHttpPost() {
        String result =null;
        URL url =null;
        HttpURLConnection connection =null;
        InputStreamReader in =null;
        try{
            url =newURL("http://10.0.2.2:8888/data/post/");
            connection = (HttpURLConnection) url.openConnection();
            connection.setDoInput(true);
            connection.setDoOutput(true);
            connection.setRequestMethod("POST");
            connection.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
            connection.setRequestProperty("Charset","utf-8");
            DataOutputStream dop =newDataOutputStream(
                    connection.getOutputStream());
            dop.writeBytes("token=alexzhou");
            dop.flush();
            dop.close();
 
            in =newInputStreamReader(connection.getInputStream());
            BufferedReader bufferedReader =newBufferedReader(in);
            StringBuffer strBuffer =newStringBuffer();
            String line =null;
            while((line = bufferedReader.readLine()) !=null) {
                strBuffer.append(line);
            }
            result = strBuffer.toString();
        }catch(Exception e) {
            e.printStackTrace();
        }finally{
            if(connection !=null) {
                connection.disconnect();
            }
            if(in !=null) {
                try{
                    in.close();
                }catch(IOException e) {
                    e.printStackTrace();
                }
            }
 
        }
        returnresult;
    }

如果参数中有中文的话,可以使用下面的方式进行编码解码:

?
1
2
URLEncoder.encode("测试","utf-8")
URLDecoder.decode("测试","utf-8");

2.使用Apache的HttpClient访问网络资源
(1)get请求

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
public String executeGet() {
        String result =null;
        BufferedReader reader =null;
        try{
            HttpClient client =newDefaultHttpClient();
            HttpGet request =newHttpGet();
            request.setURI(newURI(
                    "http://10.0.2.2:8888/data/get/?token=alexzhou"));
            HttpResponse response = client.execute(request);
            reader =newBufferedReader(newInputStreamReader(response
                    .getEntity().getContent()));
 
            StringBuffer strBuffer =newStringBuffer("");
            String line =null;
            while((line = reader.readLine()) !=null) {
                strBuffer.append(line);
            }
            result = strBuffer.toString();
 
        }catch(Exception e) {
            e.printStackTrace();
        }finally{
            if(reader !=null) {
                try{
                    reader.close();
                    reader =null;
                }catch(IOException e) {
                    e.printStackTrace();
                }
            }
        }
 
        returnresult;
    }

(2)post请求

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
public String executePost() {
        String result =null;
        BufferedReader reader =null;
        try{
            HttpClient client =newDefaultHttpClient();
            HttpPost request =newHttpPost();
            request.setURI(newURI("http://10.0.2.2:8888/data/post/"));
            List<NameValuePair> postParameters =newArrayList<NameValuePair>();
            postParameters.add(newBasicNameValuePair("token","alexzhou"));
            UrlEncodedFormEntity formEntity =newUrlEncodedFormEntity(
                    postParameters);
            request.setEntity(formEntity);
 
            HttpResponse response = client.execute(request);
            reader =newBufferedReader(newInputStreamReader(response
                    .getEntity().getContent()));
 
            StringBuffer strBuffer =newStringBuffer("");
            String line =null;
            while((line = reader.readLine()) !=null) {
                strBuffer.append(line);
            }
            result = strBuffer.toString();
 
        }catch(Exception e) {
            e.printStackTrace();
        }finally{
            if(reader !=null) {
                try{
                    reader.close();
                    reader =null;
                }catch(IOException e) {
                    e.printStackTrace();
                }
            }
        }
 
        returnresult;
    }

3.服务端代码实现
上面是采用两种方式的get和post请求的代码,下面来实现服务端的代码编写,使用python+flask真的非常的简单,就一个文件,前提是你得搭建好python+flask的环境,代码如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#coding=utf-8
 
import json
from flask import Flask,request,render_template
 
app =Flask(__name__)
 
def send_ok_json(data=None):
    ifnotdata:
        data={}
    ok_json={'ok':True,'reason':'','data':data}
    returnjson.dumps(ok_json)
 
@app.route('/data/get/',methods=['GET'])
def data_get():
    token=request.args.get('token')
    ret='%s**%s' %(token,'get')
    returnsend_ok_json(ret)
 
@app.route('/data/post/',methods=['POST'])
def data_post():
    token=request.form.get('token')
    ret='%s**%s' %(token,'post')
    returnsend_ok_json(ret)
 
if __name__ =="__main__":
    app.run(host="localhost",port=8888,debug=True)

运行服务器,如图:

4. 编写单元测试代码
右击项目:new–》Source Folder取名tests,包名是:com.alexzhou.androidhttp.test(随便取,没有要求),结构如图:


在该包下创建测试类HttpTest,继承自AndroidTestCase。编写这四种方式的测试方法,代码如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
public class HttpTest extendsAndroidTestCase {
 
    @Override
    protectedvoidsetUp() throwsException {
        Log.e("HttpTest","setUp");
    }
 
    @Override
    protectedvoidtearDown() throwsException {
        Log.e("HttpTest","tearDown");
    }
 
    publicvoidtestExecuteGet() {
        Log.e("HttpTest","testExecuteGet");
        HttpClientTest client = HttpClientTest.getInstance();
        String result = client.executeGet();
        Log.e("HttpTest", result);
    }
 
    publicvoidtestExecutePost() {
        Log.e("HttpTest","testExecutePost");
        HttpClientTest client = HttpClientTest.getInstance();
        String result = client.executePost();
        Log.e("HttpTest", result);
    }
 
    publicvoidtestExecuteHttpGet() {
        Log.e("HttpTest","testExecuteHttpGet");
        HttpClientTest client = HttpClientTest.getInstance();
        String result = client.executeHttpGet();
        Log.e("HttpTest", result);
    }
 
    publicvoidtestExecuteHttpPost() {
        Log.e("HttpTest","testExecuteHttpPost");
        HttpClientTest client = HttpClientTest.getInstance();
        String result = client.executeHttpPost();
        Log.e("HttpTest", result);
    }
}

附上HttpClientTest.java的其他代码:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class HttpClientTest {
 
    privatestaticfinal Object mSyncObject =new Object();
    privatestaticHttpClientTest mInstance;
 
    privateHttpClientTest() {
 
    }
 
    publicstaticHttpClientTest getInstance() {
        synchronized(mSyncObject) {
            if(mInstance !=null) {
                returnmInstance;
            }
            mInstance =newHttpClientTest();
        }
        returnmInstance;
    }
 
  /**...上面的四个方法...*/
}

现在还需要修改Android项目的配置文件AndroidManifest.xml,添加网络访问权限和单元测试的配置,AndroidManifest.xml配置文件的全部代码如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<manifestxmlns:android="http://schemas.android.com/apk/res/android"
    package="com.alexzhou.androidhttp"
    android:versionCode="1"
    android:versionName="1.0">
 
    <uses-permissionandroid:name="android.permission.INTERNET"/>
 
    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="15"/>
 
    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme">
        <uses-libraryandroid:name="android.test.runner"/>
 
        <activity
            android:name=".MainActivity"
            android:label="@string/title_activity_main">
            <intent-filter>
                <actionandroid:name="android.intent.action.MAIN"/>
 
                <categoryandroid:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
    </application>
 
    <instrumentation
        android:name="android.test.InstrumentationTestRunner"
        android:targetPackage="com.alexzhou.androidhttp"/>
 
</manifest>

注意:
android:name=”android.test.InstrumentationTestRunner”这部分不用更改
android:targetPackage=”com.alexzhou.androidhttp”,填写应用程序的包名

5.测试结果
展开测试类HttpTest,依次选中这四个测试方法,右击:Run As–》Android Junit Test。
(1)运行testExecuteHttpGet,结果如图:
(2)运行testExecuteHttpPost,结果如图:
(3)运行testExecuteGet,结果如图:
(4)运行testExecutePost,结果如图:

0 0