赞
踩
使用HTTP协议或TCP/UDP协议都可以实现应用和服务器之间的通信,这两种方式各有优缺点。使用HTTP协议的好处是:服务器端有成熟的Web服务器来处理通信中的很多问题,开发者只需关注业务逻辑;缺点是HTTP协议只支持一问一答的通信方式,不能像聊天一样随意地互相发送消息。
Android使用HTTP协议主要是作为客户端,用HTTP GET方法从服务器获取数据,用HTTP POST方法向服务器传送数据。在Android上发送HTTP请求的方式不止一个,分别借助不同的工具类。HttpURLConnection是Java自带的HTTP访问接口,它是一个轻量极的HTTP客户端,轻便,灵活,易于扩展,但使用起来相对复杂一点。
本文介绍的是用HttpURLConnection类来发送HTTP请求。用HttpURLConnection发送HTTP请求的流程是:创建对象、设置参数、建立连接、传输数据、处理返回的数据。
使用HttpURLConnection或其它类实现网络功能时,还需注意:
我们通过一个的例子来介绍如何实现HTTP GET和POST。这个例子是一个最简化的BBS系统原型。有一个Android客户端和Web服务器端。
Android端通过HTTP Get从Web服务器获取所有帖子内容,通过HTTP Post将发表的新帖发送到Web服务器。服务器端用JavaEE开发,用一个Servlet来响应HTTP请求,用一个List来保存所有帖子。服务器端还设计了一个网页,用于测试和演示多客户端系统。
下面我们首先看Android端是如何实现的。首先看如何发送一个GET请求。我们把实现Get请求的代码封装到了一个方法中,叫做httpGet,参数是请求的URL,是一个字符串;返回值是服务器返回的消息内容,也保存到了一个字符串中。方法的主要代码就是按照使用HttpURLConnection发送HTTP请求的流程。
- String httpGet(String urlStr){
- String result = null;
- HttpURLConnection connection = null;
- try{
- URL url = new URL(urlStr);
- connection = (HttpURLConnection) url.openConnection();
- connection.setRequestMethod("GET");
- connection.setConnectTimeout(8000);
- connection.setReadTimeout(5000);
- //connection.connect(); // 会自动进行
- int statusCode = connection.getResponseCode();
- if(statusCode==200) {
- InputStream in = connection.getInputStream();
- result = readInputStream(in);
- in.close();
- }
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- if(connection!=null) connection.disconnect();
- }
- return result;
- }
首先创建HttpURLConnection对象,对应的代码是创建一个URL对象,再调用它的openConnection方法创建出HttpURLConnection对象。
然后是设置HTTP方法,对应的代码是调用connection对象的setRequestMethod方法,参数是字符串”GET”。
接着是设置参数,对应的代码中,设置了连接超时和读超时,单位是毫秒。
再接着是建立连接并传输数据,对应的代码是connection.connect()。这个方法如果不显式调用,也会自动调用。所以,即使不写这一句代码,也会自动建立连接并传输数据。
最后是处理返回的数据。先获取返回码,判断服务器对GET请求是否成功响应。返回码等于200表示成功,此时就可以打开一个输入流读取服务器返回的消息内容。这里我们把这些内容读到了一个字符串中,最后作为返回值返回。
这些代码涉及网络操作,可能会产生异常,所以要用try-catch语句进行处理。为了保证连接建立后就一定会断开,需要把断开连接的disconnect方法写到finally块中。
发送GET请求的代码,也就是上面我们写的httpGet方法,需异步执行。所谓异步执行,简单的说就是把代码在另一个单独的线程中执行,即使很耗时也不影响当前线程的继续执行。
如果在发送请求按钮的事件响应方法里面直接调用httpGet方法,那么发送GET请求的代码就会在主线程中执行,而网络操作可能比较耗时,会影响主线程对用户操作的响应,造成应用在此段时间内假死。所以,不能在事件响应方法中直接调用httpGet方法。
那么,如何实现代码的异步执行呢?可以用Android提供的AsyncTask类。具体步骤是创建一个AsyncTask对象,再执行它的execute方法。创建AsyncTask对象时要覆盖它的doInBackground方法和onPostExecute方法。doInBackground方法中的代码会在一个新的线程中执行;onPostExecute方法会在doInBackground方法结束后回调,并在主线程中执行,这样不影响其中的代码对界面控件的操作。所以在onPostExecute方法中,我们可以直接将结果字符串设置到界面最下方的TextView控件中显示。通过这个AsyncTask类,可以很方便地将网络传输放到子线程执行,同时又不违反子线程不能操作界面控件的规则,因为中间的参数传递和同步操作都已经封装在AsyncTask类中。这种方式用于网络传输等任务非常适合。
当然,这里为了代码清晰,我们用了一个字符串常量将URL传给了子线程,没有用execute方法的参数来传递。
完成了GET请求后,我们接着来看如何发送POST请求。与发送GET请求一样,发送POST请求的代码也是按照这个流程,写到了一个方法中,叫做httpPost。
- String httpPost(String urlStr, String content){
- String result = null;
- HttpURLConnection connection = null;
- try{
- URL url = new URL(urlStr);
- connection = (HttpURLConnection) url.openConnection();
- connection.setRequestMethod("POST");
- connection.setRequestProperty("Charset", "UTF-8");
- connection.setDoInput(true);
- connection.setDoOutput(true);
- connection.setUseCaches(false);
- String params = "owner=Android&content=" + URLEncoder.encode(content, "UTF-8");
- OutputStream os = connection.getOutputStream();
- os.write(params.getBytes());
- os.flush();
- os.close();
-
- int statusCode = connection.getResponseCode();
- if(statusCode==200) {
- InputStream in = connection.getInputStream();
- result = readInputStream(in);
- in.close();
- }
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- if(connection!=null) connection.disconnect();
- }
- return result;
- }
主要的区别是:
同样,发送POST请求的代码也需要通过AsyncTask异步执行,和GET请求的执行类似,这里不多解释。
到此为止,Android端发送GET和POST请求的代码就都完成了。
接下来,我们看服务器端如何实现。服务器端是用JavaEE开发的,开发工具用的Eclipse for JavaEE,Web服务器用的Tomcat。
服务器端的主要功能由一个Servlet实现。这个Servlet将所有发帖保存在posts中,这是一个Post对象的列表。一个Post对象保存发帖者和发帖内容。
这个Servlet负责响应客户端的请求。对于Get请求,将posts中所有内容返回,缺省是以纯文本格式返回。这里我们也预留了XML格式和JSON格式的接口,如果URL中有fmt参数并且fmt的值是2的时候,以XML格式返回posts中所有内容;fmt的值是3时,以JSON格式返回posts中所有内容。
对于Post请求,会把发帖者和内容保存到一个Post对象中,然后添加到posts列表中,最后返回一个Post OK的字符串,告诉客户端发帖成功。
除了这个Servlet以外,我们在服务器上再添加一个页面,叫content.html,负责对BBS Servlet进行测试,也可以演示多客户端系统。
BBS-content.png
这个页面上部是三个链接,都是以GET请求返回所有帖子内容,第一个链接对应于纯文本格式,第二个链接对应于XML格式,第三个链接对应于JSON格式。通过这三个链接,我们就可以测试BBS返回的帖子内容,也能看到数据的格式。页面下部是一个表单,对应于POST请求发表新帖。页面的代码也非常简单,就是三个超级链接和一个表单。
完整代码下载:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。