1. /*该类演示了四种方法提交数据到服务器,并将服务器解析后的数据以字符串的形式返回*/
2. public class LoginService {
3. /**
4. *
5. * @param username
6. * @param password
7. * @return
8. */
9. public static String loginByGet(String username,String password){
10. try {
11. //提交数据到服务器
12. //拼装路径
13. "http://192.168.1.100/Web/servlet/LoginServlet?username="
14. "UTF-8") + "&password=" + URLEncoder.encode(password,"UTF-8");
15. new URL(path);
16.
17. //打开连接
18.
19. "GET");//设置请求方式为get
20.
21. 5000);//设置连接超时时间为5秒
22.
23. int code = conn.getResponseCode();//获得请求码
24. if(code == 200){
25. InputStream is = conn.getInputStream();
26. String text = StreamTools.readInputStream(is);
27. return text;
28. else{
29. return null;
30. }
31. catch (Exception e) {
32. e.printStackTrace();
33. }
34. return null;
35. }
36.
37. /**
38. *
39. * @param username
40. * @param password
41. * @return
42. */
43. public static String loginByPost(String username,String password){
44. try {
45. //提交数据到服务器
46. //拼装路径
47. "http://192.168.1.100/Web/servlet/LoginServlet";
48. new URL(path);
49.
50. //打开连接
51.
52. "POST");//设置请求方式为get
53.
54. 5000);//设置连接超时时间为5秒
55. //准备数据
56. "username="+ URLEncoder.encode(username,"UTF-8") + "&password=" + URLEncoder.encode(password,"UTF-8");
57. "Content-Type", "application/x-www-form-urlencoded");
58. "Content-Length", data.length()+"");
59.
60. //post的方式实际上是浏览器把数据写给了服务器
61. true);
62. OutputStream os = conn.getOutputStream();
63. os.write(data.getBytes());
64.
65. int code = conn.getResponseCode();//获得请求码
66. if(code == 200){
67. InputStream is = conn.getInputStream();
68. String text = StreamTools.readInputStream(is);
69. return text;
70. else{
71. return null;
72. }
73. catch (Exception e) {
74. e.printStackTrace();
75. }
76. return null;
77. }
78.
79. /**
80. * 采用httpclient get提交数据
81. * @param username
82. * @param password
83. * @return
84. */
85. public static String loginByClientGet(String username,String password){
86. try {
87. //1.打开一个浏览器
88. new DefaultHttpClient();
89. //2.输入地址
90. "http://192.168.1.100/Web/servlet/LoginServlet?username="
91. + URLEncoder.encode(username)
92. "&password="
93. + URLEncoder.encode(password);
94. new HttpGet(path);
95. //3.敲回车
96. HttpResponse response = client.execute(httpGet);
97. int code = response.getStatusLine().getStatusCode();
98. if (code == 200) {
99. InputStream is = response.getEntity().getContent();
100. String text = StreamTools.readInputStream(is);
101. return text;
102. else {
103. return null;
104. }
105. catch (Exception e) {
106. e.printStackTrace();
107. return null;
108. }
109. }
110.
111. /**
112. * 采用httpclient post提交数据
113. * @param username
114. * @param password
115. * @return
116. */
117. public static String loginByClientPost(String username,String password){
118. try {
119. //1.打开一个浏览器
120. new DefaultHttpClient();
121. //2.输入地址
122. "http://192.168.1.100/Web/servlet/LoginServlet";
123. new HttpPost(path);
124. //指定要提交的数据实体
125. new ArrayList<NameValuePair>();
126. new BasicNameValuePair("username", username));
127. new BasicNameValuePair("password", password));
128. new UrlEncodedFormEntity(parameters,"UTF-8"));
129. //3.敲回车
130. HttpResponse response = client.execute(httpPost);
131. int code = response.getStatusLine().getStatusCode();
132. if (code == 200) {
133. InputStream is = response.getEntity().getContent();
134. String text = StreamTools.readInputStream(is);
135. return text;
136. else {
137. return null;
138. }
139. catch (Exception e) {
140. e.printStackTrace();
141. return null;
142. }
143.
144. }
145. }
将输入流转换为字符串的工具类StreamTools代码如下:
1. public class StreamTools {
2. /**
3. * 把输入流的内容转化成字符串
4. * @param is
5. * @return
6. * @throws IOException
7. */
8. public static String readInputStream(InputStream is){
9. try {
10. new ByteArrayOutputStream();
11. int len = 0;
12. byte[] buffer = new byte[1024];
13. while((len=is.read(buffer))!=-1){
14. 0, len);
15. }
16. is.close();
17. stream.close();
18. byte[] result = stream.toByteArray();
19. //试着解析 result 里面的字符串
20. new String(result);
21. return temp;
22. catch (Exception e) {
23. e.printStackTrace();
24. return "获取失败";
25. }
26.
27. }
28. }
在主界面测试是否成功提交的代码如下:
1. public class MainActivity extends Activity {
2. private EditText et_username;
3. private EditText et_password;
4. @Override
5. protected void onCreate(Bundle savedInstanceState) {
6. super.onCreate(savedInstanceState);
7. setContentView(R.layout.activity_main);
8. et_username = (EditText) findViewById(R.id.et_username);
9. et_password = (EditText) findViewById(R.id.et_password);
10. }
11. public void click1(View view){
12. final String username = et_username.getText().toString().trim();
13. final String password = et_password.getText().toString().trim();
14.
15. new Thread(){
16. public void run() {
17. final String result = LoginService.loginByGet(username, password);
18. if(result!=null){
19. new Runnable() {
20. @Override
21. public void run() {
22. this, result, Toast.LENGTH_SHORT).show();
23. }
24. });
25. else{
26. new Runnable() {
27. @Override
28. public void run() {
29. this, "请求失败...", Toast.LENGTH_SHORT).show();
30. }
31. });
32. }
33. };
34. }.start();
35. }
36.
37. public void click2(View view){
38. final String username = et_username.getText().toString().trim();
39. final String password = et_password.getText().toString().trim();
40.
41. new Thread(){
42. public void run() {
43. final String result = LoginService.loginByGet(username, password);
44. if(result!=null){
45. new Runnable() {
46. @Override
47. public void run() {
48. this, result, Toast.LENGTH_SHORT).show();
49. }
50. });
51. else{
52. new Runnable() {
53. @Override
54. public void run() {
55. this, "请求失败...", Toast.LENGTH_SHORT).show();
56. }
57. });
58. }
59. };
60. }.start();
61. }
62.
63. public void click3(View view){
64. final String username = et_username.getText().toString().trim();
65. final String password = et_password.getText().toString().trim();
66.
67. new Thread(){
68. public void run() {
69. final String result = LoginService.loginByClientGet(username, password);
70. if(result!=null){
71. new Runnable() {
72. @Override
73. public void run() {
74. this, result, Toast.LENGTH_SHORT).show();
75. }
76. });
77. else{
78. new Runnable() {
79. @Override
80. public void run() {
81. this, "请求失败...", Toast.LENGTH_SHORT).show();
82. }
83. });
84. }
85. };
86. }.start();
87. }
88.
89. public void click4(View view){
90. final String username = et_username.getText().toString().trim();
91. final String password = et_password.getText().toString().trim();
92.
93. new Thread(){
94. public void run() {
95. final String result = LoginService.loginByClientPost(username, password);
96. if(result!=null){
97. new Runnable() {
98. @Override
99. public void run() {
100. this, result, Toast.LENGTH_SHORT).show();
101. }
102. });
103. else{
104. new Runnable() {
105. @Override
106. public void run() {
107. this, "请求失败...", Toast.LENGTH_SHORT).show();
108. }
109. });
110. }
111. };
112. }.start();
113. }
114.
115. public void click5(View view){
116. final String username = et_username.getText().toString().trim();
117. final String password = et_password.getText().toString().trim();
118. new AsyncHttpClient();
119. "http://127.0.0.1:80/Web/servlet/LoginServlet";
120. new RequestParams();
121. "username", username);
122. "password", password);
123. new AsyncHttpResponseHandler() {
124.
125. @Override
126. public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {
127. this, "请求失败..."+new String(responseBody), 0).show();
128. }
129.
130. @Override
131. public void onFailure(int statusCode, Header[] headers,
132. byte[] responseBody, Throwable error) {
133. this, "请求失败..."+new String(responseBody), 0).show();
134. }
135. });
136. }
137. }
使用开源项目AsnycHttpclient提交数据
项目的官方网站:
http://loopj.com/android-async-http/,对应的github地址:https://github.com/loopj/android-async-http
我这里简要介绍下:它是专门针对Android在Apache的HttpClient基础上构建的异步的callback-based http client。所有的请求
全在UI线程之外发生,而callback发生在创建它的线程中,应用了Android的Handler发送消息机制。你也可以把AsyncHttpClient应用在
Service中或者后台线程中,库代码会自动识别出它所运行的context。它的feature包括:
1. 发送异步http请求,在匿名callback对象中处理response;
2. http请求发生在UI线程之外;
3. 内部采用线程池来处理并发请求;
4. GET/POST 参数构造,通过RequestParams类。
5. 内置多部分文件上传,不需要第三方库支持;
6. 流式Json上传,不需要额外的库;
7. 能处理环行和相对重定向;
8. 和你的app大小相比来说,库的size很小,所有的一切只有90kb;
9. 自动智能的请求重试机制在各种各样的移动连接环境中;
10. 自动的gzip响应解码;
11. 内置多种形式的响应解析,有原生的字节流,string,json对象,甚至可以将response写到文件中;
12. 永久的cookie保存,内部实现用的是Android的SharedPreferences;
BaseJsonHttpResponseHandler和
各种json库集成;
14. 支持SAX解析器;
15. 支持各种语言和content编码,不仅仅是UTF-8。
大概翻译了下,这些只是大体的概览,具体的细节还得在使用过程中慢慢感受、学习。
接下来,带领大家看看应用android-async-http来写代码是个啥样子。简单来说你只需要3步,
1. 创建一个AsyncHttpClient;
2. (可选的)通过RequestParams对象设置请求参数;
3. 调用AsyncHttpClient的某个get方法,传递你需要的(成功和失败时)callback接口实现,一般都是匿名内部类
,实现了AsyncHttpResponseHandler,类库自己也提供了好些现成的response handler,你一般不需要自己创建一个。
来看看代码如何写:
AsyncHttpClient client = new AsyncHttpClient();
client.get("http://www.google.com", new AsyncHttpResponseHandler() {
@Override
public void onStart() {
// called before request is started
}
@Override
public void onSuccess(int statusCode, Header[] headers, byte[] response) {
// called when response HTTP status is "200 OK"
}
@Override
public void onFailure(int statusCode, Header[] headers, byte[] errorResponse, Throwable e) {
// called when response HTTP status is "4XX" (eg. 401, 403, 404)
}
@Override
public void onRetry(int retryNo) {
// called when request is retried
}
});
是不是很简洁,有没有被震撼到?反正我自己第一次看到的时候有种相见恨晚的感觉,这简直就是我日思夜想的方式啊!这里你只需要通过
匿名内部类的方式实现AsyncHttpResponseHandler,而且更棒的是你只需要override感兴趣的方法,比如一般都是onSuccess和onFailure。
这个版本的get方法没有为请求传递任何参数,当然你也可以通过RequestParams来传递各种参数,如下:
AsyncHttpClient client = new AsyncHttpClient();
RequestParams params = new RequestParams();
params.put("key", "value");
params.put("more", "data");
client.get("http://www.google.com", params, new
AsyncHttpResponseHandler() {
@Override
public void onSuccess(int statusCode, Header[] headers, byte[] response) {
System.out.println(response);
}
@Override
public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) {
Log.d("ERROR", error);
}
}
);
以上的例子是返回的response直接是原生字节流的情况,如果你需要把返回的结果当一个String对待,这时只需要匿名实现一个
TextHttpResponseHandler就行,其继承自AsyncHttpResponse,并将原生的字节流根据指定的encoding转化成了string对象,
代码如下:
AsyncHttpClient client = new AsyncHttpClient();
RequestParams params = new RequestParams();
params.put("key", "value");
params.put("more", "data");
client.get("http://www.google.com", params, new
TextHttpResponseHandler() {
@Override
public void onSuccess(int statusCode, Header[] headers, String response) {
System.out.println(response);
}
@Override
public void onFailure(int statusCode, Header[] headers, String responseBody, Throwable error) {
Log.d("ERROR", error);
}
}
);
同样的方式,你可以发送json请求,代码如下:
String url = "https://ajax.googleapis.com/ajax/services/search/images";
AsyncHttpClient client = new AsyncHttpClient();
RequestParams params = new RequestParams();
params.put("q", "android");
params.put("rsz", "8");
client.get(url, params, new JsonHttpResponseHandler() {
@Override
public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
// Handle resulting parsed JSON response here
}
@Override
public void onSuccess(int statusCode, Header[] headers, JSONArray response) {
// Handle resulting parsed JSON response here
}
});
看到了没,返回的response已经自动转化成JSONObject了,当然也支持JSONArray类型,override你需要的那个版本就行。
有了AsyncHttpClient,要实现这些功能是不是很简单呢?当然这里只是很初级的介绍和使用,剩下的还需要开发者自己参考官方文档、源码(官方甚至提供了一个Sample使用的集合),在实际项目中实践。最后,强烈建议大家使用,是时候和冗长乏味的代码说再见了。我一直是分析源码的,这次也不例外,实现上的关键代码我会在接下来的博客中专门介绍