转自: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,结果如图: