【Android每周专题】网络编程
2013-12-08 15:11
281 查看
本系列文章均为A2BGeek原创,转载务必在明显处注明:
转载自A2BGeek的【Android每周专题】系列,原文链接:http://blog.csdn.net/a2bgeek/article/details/11580395
本期专题将讲解网络编程。
很多APP或多或少会有一些访问网络的功能,比如用户的登录,文件的上传和下载,更新等功能,本期专题将注重实践,会有大量的代码,读者可以直接拷贝使用。
在一般情况下,如果只是需要Web站点的某个简单页面提交请求并获取服务器响应,HttpURLConnection完全可以胜任。但在绝大部分情况下,Web站点的网页可能没这么简单,这些页面并不是通过一个简单的URL就可访问的,可能需要用户登录而且具有相应的权限才可访问该页面。在这种情况下,就需要涉及Session、Cookie的处理了,如果打算使用HttpURLConnection来处理这些细节,当然也是可能实现的,只是处理起来难度就大了。
为了更好地处理向Web站点请求,包括处理Session、Cookie等细节问题,Apache开源组织提供了一个HttpClient项目,看它的名称就知道,它是一个简单的HTTP客户端(并不是浏览器),可以用于发送HTTP请求,接收HTTP响应。但不会缓存服务器的响应,不能执行HTML页面中嵌入的Javascript代码,也不会对页面内容进行任何解析、处理。
简单来说,HttpClient就是一个增强版的HttpURLConnection,HttpURLConnection可以做的事情HttpClient全部可以做;HttpURLConnection没有提供的有些功能,HttpClient也提供了,但它只是关注于如何发送请求、接收响应,以及管理HTTP连接。
server.py
好了今天就到这里了,代码的大部分已经放在博客里面了,由于个人时间紧张,上传代码又要等很长时间,代码就不贴了,需要的同学可以留言。
转载自A2BGeek的【Android每周专题】系列,原文链接:http://blog.csdn.net/a2bgeek/article/details/11580395
本期专题将讲解网络编程。
很多APP或多或少会有一些访问网络的功能,比如用户的登录,文件的上传和下载,更新等功能,本期专题将注重实践,会有大量的代码,读者可以直接拷贝使用。
概述
HTTP 协议可能是现在 Internet 上使用得最多、最重要的协议了,在 JDK 的 java.net 包中已经提供了访问 HTTP 协议的基本功能:HttpURLConnection。HttpURLConnection是java的标准类,HttpURLConnection继承自URLConnection,可用于向指定网站发送GET请求、POST请求。在一般情况下,如果只是需要Web站点的某个简单页面提交请求并获取服务器响应,HttpURLConnection完全可以胜任。但在绝大部分情况下,Web站点的网页可能没这么简单,这些页面并不是通过一个简单的URL就可访问的,可能需要用户登录而且具有相应的权限才可访问该页面。在这种情况下,就需要涉及Session、Cookie的处理了,如果打算使用HttpURLConnection来处理这些细节,当然也是可能实现的,只是处理起来难度就大了。
为了更好地处理向Web站点请求,包括处理Session、Cookie等细节问题,Apache开源组织提供了一个HttpClient项目,看它的名称就知道,它是一个简单的HTTP客户端(并不是浏览器),可以用于发送HTTP请求,接收HTTP响应。但不会缓存服务器的响应,不能执行HTML页面中嵌入的Javascript代码,也不会对页面内容进行任何解析、处理。
简单来说,HttpClient就是一个增强版的HttpURLConnection,HttpURLConnection可以做的事情HttpClient全部可以做;HttpURLConnection没有提供的有些功能,HttpClient也提供了,但它只是关注于如何发送请求、接收响应,以及管理HTTP连接。
简单登录功能
这里说的用户登录仅仅是向服务器发送用户名和密码,服务器验证一下,返回一个标志(比如1代表用户名和密码正确登录成功),真正的登录功能是没有这么简单的,还需要维护Session。在本小节我将通过四种方式编写登录代码,分别是HttpURLConnection的GET方式和POST方式以及HttpClient的GET方式和POST方式,目的是熟悉Android的网络编程。服务器端我选用了Facebook的开源框架Tornado,服务器端大家可以根据自己的喜好选择,比如LAMP的经典组合。接下来就直接上代码了。HttpURLConnection GET
public static String HttpURLConnectionGet(String username, String passwd) { String response = "HttpURLConnectionGet "; try { String urlStr = "http://XXX.XXX.XXX.XXX:8888/normalrequest?username=" + username + "&password=" + passwd; URL url = new URL(urlStr); HttpURLConnection urlConnection = (HttpURLConnection) url .openConnection(); InputStream is = urlConnection.getInputStream(); BufferedReader br = new BufferedReader(new InputStreamReader(is)); String readLine = null; while ((readLine = br.readLine()) != null) { response += readLine; } is.close(); br.close(); urlConnection.disconnect(); } catch (MalformedURLException e) { // TODO Auto-generated catch block Log.v("a2bgeek", "MalformedURLException--->" + e.getMessage()); } catch (IOException e) { // TODO Auto-generated catch block Log.v("a2bgeek", "IOException--->" + e.getMessage()); } return response; }我电脑的IP地址就不写啦,用XXX代替了。
HttpURLConnection POST
public static String HttpURLConnectionPost(String username, String passwd) { String response = "HttpURLConnectionPost "; try { String urlStr = "http://XXX.XXX.XXX.XXX:8888/normalrequest"; URL url = new URL(urlStr); HttpURLConnection urlConnection = (HttpURLConnection) url .openConnection(); urlConnection.setDoInput(true); urlConnection.setDoOutput(true); urlConnection.setRequestMethod("POST"); urlConnection.setUseCaches(false); urlConnection.connect(); DataOutputStream out = new DataOutputStream( urlConnection.getOutputStream()); String content = "username=" + username + "&password=" + passwd; out.writeBytes(content); out.flush(); out.close(); InputStream is = urlConnection.getInputStream(); BufferedReader br = new BufferedReader(new InputStreamReader(is)); String readLine = null; while ((readLine = br.readLine()) != null) { response += readLine; } is.close(); br.close(); urlConnection.disconnect(); } catch (MalformedURLException e) { // TODO Auto-generated catch block Log.v("a2bgeek", "MalformedURLException--->" + e.getMessage()); } catch (IOException e) { // TODO Auto-generated catch block Log.v("a2bgeek", "IOException--->" + e.getMessage()); } return response; }
HttpGet
public static String HttpClientGet(String username, String passwd) { String response = "HttpClientGet "; try { String urlStr = "http://XXX.XXX.XXX.XXX:8888/normalrequest?username=" + username + "&password=" + passwd; HttpGet httpGet = new HttpGet(urlStr); HttpClient httpClient = new DefaultHttpClient(); HttpResponse httpResponse = httpClient.execute(httpGet); if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { response += EntityUtils.toString(httpResponse.getEntity()); } } catch (ClientProtocolException e) { // TODO Auto-generated catch block Log.v("a2bgeek", "ClientProtocolException--->" + e.getMessage()); } catch (IOException e) { // TODO Auto-generated catch block Log.v("a2bgeek", "IOException--->" + e.getMessage()); } return response; }
HttpPost
public static String HttpClientPost(String username, String passwd) { String response = "HttpClientPost "; try { String urlStr = "http://XXX.XXX.XXX.XXX:8888/normalrequest"; HttpPost httpPost = new HttpPost(urlStr); List<NameValuePair> params = new ArrayList<NameValuePair>(); params.add(new BasicNameValuePair("username", username)); params.add(new BasicNameValuePair("password", passwd)); HttpEntity httpEntity = new UrlEncodedFormEntity(params); httpPost.setEntity(httpEntity); HttpClient httpClient = new DefaultHttpClient(); HttpResponse httpResponse = httpClient.execute(httpPost); if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { response += EntityUtils.toString(httpResponse.getEntity()); } } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block Log.v("a2bgeek", "UnsupportedEncodingException--->" + e.getMessage()); } catch (ClientProtocolException e) { // TODO Auto-generated catch block Log.v("a2bgeek", "ClientProtocolException--->" + e.getMessage()); } catch (IOException e) { // TODO Auto-generated catch block Log.v("a2bgeek", "IOException--->" + e.getMessage()); } return response; }
服务器端代码
服务器端是使用tornado框架编写的,不了解的读者请谷歌一下。server.py
import tornado.ioloop import tornado.web from request import NormalRequestHandler application = tornado.web.Application([ (r"/normalrequest", NormalRequestHandler), ]) if __name__ == "__main__": application.listen(8888) tornado.ioloop.IOLoop.instance().start()request.py
import tornado.web class NormalRequestHandler(tornado.web.RequestHandler): def get(self): username = self.get_argument('username') password = self.get_argument('password') if username=='a2bgeek' and password=='123456': self.write('login success') else: self.write('login fail') def post(self): username = self.get_argument('username') password = self.get_argument('password') if username=='a2bgeek' and password=='123456': self.write('login success') else: self.write('login fail')在这里有一点必须要提醒读者,Android4.0以后涉及网络的操作不能放在主线程里面做了,所以需要开一个线程来做。
文件的上传
一般文件的上传使用POST方式,因为GET对字节数有限制只能传很少的数据,而POST理论上是没有限制的。HttpURLConnection POST
public static String HttpURLConnectionFileUpload(File file) { String response = "HttpURLConnectionFileUpload "; String boundary = "a2bgeek"; try { String urlStr = "http://XXX.XXX.XXX.XXX:8888/fileupload"; URL url = new URL(urlStr); HttpURLConnection urlConnection = (HttpURLConnection) url .openConnection(); urlConnection.setDoInput(true); urlConnection.setDoOutput(true); urlConnection.setRequestMethod("POST"); urlConnection.setUseCaches(false); urlConnection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary); urlConnection.connect(); DataOutputStream dos = new DataOutputStream( urlConnection.getOutputStream()); dos.writeBytes("--" + boundary); dos.writeBytes("\r\n"); dos.writeBytes("Content-Disposition: form-data; name=\"file\"; filename=\"" + file.getName() + "\"" + "\r\n"); dos.writeBytes("\r\n"); FileInputStream fis = new FileInputStream(file.getPath()); byte[] buffer = new byte[1024 * 1024]; int count = 0; while ((count = fis.read(buffer)) != -1) { dos.write(buffer, 0, count); } fis.close(); dos.writeBytes("\r\n"); dos.writeBytes("--" + boundary + "--"); dos.flush(); dos.close(); InputStream is = urlConnection.getInputStream(); BufferedReader br = new BufferedReader(new InputStreamReader(is)); String readLine = null; while ((readLine = br.readLine()) != null) { response += readLine; } is.close(); br.close(); urlConnection.disconnect(); } catch (MalformedURLException e) { // TODO Auto-generated catch block Log.v("a2bgeek", "MalformedURLException--->" + e.getMessage()); } catch (IOException e) { // TODO Auto-generated catch block Log.v("a2bgeek", "IOException--->" + e.getMessage()); } return response; }
HttpPost
public static String HttpClientFileUpload(File file) { String response = "HttpClientFileUpload "; try { String urlStr = "http://XXX.XXX.XXX.XXX:8888/fileupload"; HttpPost httpPost = new HttpPost(urlStr); MultipartEntity multipartEntity = new MultipartEntity(); multipartEntity.addPart("file", new FileBody(file)); httpPost.setEntity(multipartEntity); HttpClient httpClient = new DefaultHttpClient(); HttpResponse httpResponse = httpClient.execute(httpPost); if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { response += EntityUtils.toString(httpResponse.getEntity()); } } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block Log.v("a2bgeek", "UnsupportedEncodingException--->" + e.getMessage()); } catch (ClientProtocolException e) { // TODO Auto-generated catch block Log.v("a2bgeek", "ClientProtocolException--->" + e.getMessage()); } catch (IOException e) { // TODO Auto-generated catch block Log.v("a2bgeek", "IOException--->" + e.getMessage()); } return response; }
服务器端代码
import tornado.web import os class UploadFileHandler(tornado.web.RequestHandler): def get(self): self.write(''' <html> <head><title>Upload File</title></head> <body> <form action='fileupload' enctype="multipart/form-data" method='post'> <input type='file' name='file'/><br/> <input type='submit' value='submit'/> </form> </body> </html> ''') def post(self): upload_path=os.path.join(os.path.dirname(__file__),'files') if not os.path.exists(upload_path): os.makedirs(upload_path) file_metas=self.request.files['file'] for meta in file_metas: filename=meta['filename'] filepath=os.path.join(upload_path,filename) with open(filepath,'w') as up: up.write(meta['body']) self.write('upload success')
文件的下载
一般文件的下载使用的是GET方式,其实也可以使用POST方式,这两种是没有本质区别的。只是GET比较方便,POST的话需要在服务器端编写返回文件的代码。HttpURLConnection GET
public static void HttpURLConnectionFileDownload() { try { int BUFFER_SIZE = 1024 * 1024; String urlStr = "http://XXX.XXX.XXX.XXX:8888/pic/one.png"; URL url = new URL(urlStr); HttpURLConnection urlConnection = (HttpURLConnection) url .openConnection(); InputStream is = urlConnection.getInputStream(); FileOutputStream fos = new FileOutputStream(new File(Environment .getExternalStorageDirectory().getPath() + "/NetConn/downone.png")); byte[] buffer = new byte[BUFFER_SIZE]; int count = 0; while ((count = is.read(buffer)) > 0) { fos.write(buffer, 0, count); } is.close(); fos.close(); Log.v("a2bgeek", "HttpURLConnectionFileDownload success"); } catch (MalformedURLException e) { // TODO Auto-generated catch block Log.v("a2bgeek", "MalformedURLException--->" + e.getMessage()); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }
HttpGet
public static void HttpClientFileDownload() { try { int BUFFER_SIZE = 1024 * 1024; String urlStr = "http://XXX.XXX.XXX.XXX:8888/pic/two.png"; HttpGet httpGet = new HttpGet(urlStr); HttpClient httpClient = new DefaultHttpClient(); HttpResponse httpResponse = httpClient.execute(httpGet); HttpEntity httpEntity = httpResponse.getEntity(); InputStream is = httpEntity.getContent(); FileOutputStream fos = new FileOutputStream(new File(Environment .getExternalStorageDirectory().getPath() + "/NetConn/downtwo.png")); byte[] buffer = new byte[BUFFER_SIZE]; int count = 0; while ((count = is.read(buffer)) > 0) { fos.write(buffer, 0, count); } is.close(); fos.close(); Log.v("a2bgeek", "HttpClientFileDownload success"); } catch (ClientProtocolException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }
好了今天就到这里了,代码的大部分已经放在博客里面了,由于个人时间紧张,上传代码又要等很长时间,代码就不贴了,需要的同学可以留言。
相关文章推荐
- linux网络编程用到的网络函数详解用和使用示例
- 谈谈新手如何学习PHP网络编程第1/2页
- Python 网络编程起步(Socket发送消息)
- c# socket网络编程接收发送数据示例代码
- Python 网络编程说明第1/2页
- python socket网络编程步骤详解(socket套接字使用)
- IOCP浅析[二]——IOCP出现的意义和函数接口
- [源码分享]Windows下的半自动线程锁
- 揭开网络编程常见API的面纱【上】
- 揭开网络编程常见API的面纱【下】
- 深入浅出Cocoa之Bonjour网络编程(服务器端)
- Java网络编程之实现HTTP断点续传下载工具(附源代码)
- 网络编程 同步,阻塞,异步,非阻塞
- Java网络编程从入门到精通(25):创建ServerSocket对象
- android 网络编程 HttpGet类和HttpPost类使用详解
- 网络编程
- android网络编程之json传输数据以及解析方式
- 网络套接字基础
- android网络编程关于Socket和http协议
- API及可伸缩性-AcceptEx