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使用的集合),在实际项目中实践。最后,强烈建议大家使用,是时候和冗长乏味的代码说再见了。我一直是分析源码的,这次也不例外,实现上的关键代码我会在接下来的博客中专门介绍