转载来自: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 =
new
URL(
"http://10.0.2.2:8888/data/get/?token=alexzhou"
);
connection = (HttpURLConnection) url.openConnection();
in =
new
InputStreamReader(connection.getInputStream());
BufferedReader bufferedReader =
new
BufferedReader(in);
StringBuffer strBuffer =
new
StringBuffer();
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();
}
}
}
return
result;
}
|
注意:因为是通过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 =
new
URL(
"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 =
new
DataOutputStream(
connection.getOutputStream());
dop.writeBytes(
"token=alexzhou"
);
dop.flush();
dop.close();
in =
new
InputStreamReader(connection.getInputStream());
BufferedReader bufferedReader =
new
BufferedReader(in);
StringBuffer strBuffer =
new
StringBuffer();
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();
}
}
}
return
result;
}
|
如果参数中有中文的话,可以使用下面的方式进行编码解码:
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 =
new
DefaultHttpClient();
HttpGet request =
new
HttpGet();
request.setURI(
new
URI(
"http://10.0.2.2:8888/data/get/?token=alexzhou"
));
HttpResponse response = client.execute(request);
reader =
new
BufferedReader(
new
InputStreamReader(response
.getEntity().getContent()));
StringBuffer strBuffer =
new
StringBuffer(
""
);
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();
}
}
}
return
result;
}
|
(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 =
new
DefaultHttpClient();
HttpPost request =
new
HttpPost();
request.setURI(
new
URI(
"http://10.0.2.2:8888/data/post/"
));
List<NameValuePair> postParameters =
new
ArrayList<NameValuePair>();
postParameters.add(
new
BasicNameValuePair(
"token"
,
"alexzhou"
));
UrlEncodedFormEntity formEntity =
new
UrlEncodedFormEntity(
postParameters);
request.setEntity(formEntity);
HttpResponse response = client.execute(request);
reader =
new
BufferedReader(
new
InputStreamReader(response
.getEntity().getContent()));
StringBuffer strBuffer =
new
StringBuffer(
""
);
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();
}
}
}
return
result;
}
|
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
):
if
not
data:
data
=
{}
ok_json
=
{
'ok'
:
True
,
'reason'
:'
','
data':data}
return
json.dumps(ok_json)
@app
.route(
'/data/get/'
,methods
=
[
'GET'
])
def
data_get():
token
=
request.args.get(
'token'
)
ret
=
'%s**%s'
%
(token,
'get'
)
return
send_ok_json(ret)
@app
.route(
'/data/post/'
,methods
=
[
'POST'
])
def
data_post():
token
=
request.form.get(
'token'
)
ret
=
'%s**%s'
%
(token,
'post'
)
return
send_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
extends
AndroidTestCase {
@Override
protected
void
setUp()
throws
Exception {
Log.e(
"HttpTest"
,
"setUp"
);
}
@Override
protected
void
tearDown()
throws
Exception {
Log.e(
"HttpTest"
,
"tearDown"
);
}
public
void
testExecuteGet() {
Log.e(
"HttpTest"
,
"testExecuteGet"
);
HttpClientTest client = HttpClientTest.getInstance();
String result = client.executeGet();
Log.e(
"HttpTest"
, result);
}
public
void
testExecutePost() {
Log.e(
"HttpTest"
,
"testExecutePost"
);
HttpClientTest client = HttpClientTest.getInstance();
String result = client.executePost();
Log.e(
"HttpTest"
, result);
}
public
void
testExecuteHttpGet() {
Log.e(
"HttpTest"
,
"testExecuteHttpGet"
);
HttpClientTest client = HttpClientTest.getInstance();
String result = client.executeHttpGet();
Log.e(
"HttpTest"
, result);
}
public
void
testExecuteHttpPost() {
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 {
private
static
final
Object mSyncObject =
new
Object();
private
static
HttpClientTest mInstance;
private
HttpClientTest() {
}
public
static
HttpClientTest getInstance() {
synchronized
(mSyncObject) {
if
(mInstance !=
null
) {
return
mInstance;
}
mInstance =
new
HttpClientTest();
}
return
mInstance;
}
/**...上面的四个方法...*/
}
|
现在还需要修改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
|
<
manifest
xmlns:android
=
"http://schemas.android.com/apk/res/android"
package
=
"com.alexzhou.androidhttp"
android:versionCode
=
"1"
android:versionName
=
"1.0"
>
<
uses-permission
android: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-library
android:name
=
"android.test.runner"
/>
<
activity
android:name
=
".MainActivity"
android:label
=
"@string/title_activity_main"
>
<
intent-filter
>
<
action
android:name
=
"android.intent.action.MAIN"
/>
<
category
android: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,结果如图: