[关闭]
@liter 2015-10-04T16:01:01.000000Z 字数 5072 阅读 6894

Android网络通信框架LiteHttp 第五节:文件、位图的上传和下载

litehttp2.x版本系列教程


官网: http://litesuits.com
QQ群: 大群 47357508,二群 42960650

本系列文章面向android开发者,展示开源网络通信框架LiteHttp的主要用法,并讲解其关键功能的运作原理,同时传达了一些框架作者在日常开发中的一些最佳实践和经验。

本系列文章目录总览: https://zybuluo.com/liter/note/186513


第五节:LiteHttp之文件、位图的上传和下载

1. 文件下载

先准备一张网络图片,比如:

  1. public static final String picUrl = "http://pic.33.la/20140403sj/1638.jpg";

然后下载之

第一步:
liteHttp.executeAsync(new FileRequest(picUrl, "sdcard/aaa.jpg"));

第二步:
不好意思,已经下载好了。

下载位图并监听进度

  1. liteHttp.executeAsync(
  2. new BitmapRequest(picUrl).setHttpListener(
  3. new HttpListener<Bitmap>(true, true, false) {
  4. @Override
  5. public void onLoading(AbstractRequest<Bitmap> request, long total, long len) {
  6. HttpLog.i(TAG, total + " total " + len + " len");
  7. }
  8. @Override
  9. public void onSuccess(Bitmap bitmap, Response<Bitmap> response) {
  10. downProgress.dismiss();
  11. AlertDialog.Builder b = HttpUtil.dialogBuilder(activity, "LiteHttp2.0", "");
  12. ImageView iv = new ImageView(activity);
  13. iv.setImageBitmap(bitmap);
  14. b.setView(iv);
  15. b.show();
  16. }
  17. @Override
  18. public void onFailure(HttpException e, Response<Bitmap> response) {
  19. HttpUtil.showTips(activity, "LiteHttp2.0", e.toString());
  20. }
  21. }));

迅雷不及掩耳之势,别停,继续...

2. 单文件上传(application/octet-stream)

为方便测试,我在SD卡上放置一张名为aaa.jpg的图片,然后开撸:

  1. // 替换自己的服务器地址
  2. public static final String uploadUrl = "http://192.168.0.0:8080/upload";
  3. HttpListener uploadListener = new HttpListener<String>(true, false, true) {
  4. @Override
  5. public void onSuccess(String s, Response<String> response) {
  6. response.printInfo();
  7. }
  8. @Override
  9. public void onFailure(HttpException e, Response<String> response) {
  10. response.printInfo();
  11. }
  12. @Override
  13. public void onUploading(AbstractRequest<String> request, long total, long len) {
  14. }
  15. };
  16. final StringRequest upload = new StringRequest(uploadUrl)
  17. .setMethod(HttpMethods.Post)
  18. .setHttpListener(uploadListener)
  19. .setHttpBody(new FileBody(new File("/sdcard/aaa.jpg")));
  20. liteHttp.executeAsync(upload);

通过流上传:

  1. // uploadListener上面已经定义,不在重复写
  2. FileInputStream fis = null;
  3. try {
  4. fis = new FileInputStream(new File("/sdcard/aaa.jpg"));
  5. } catch (Exception e) {
  6. e.printStackTrace();
  7. }
  8. final StringRequest upload = new StringRequest(uploadUrl)
  9. .setMethod(HttpMethods.Post)
  10. .setHttpListener(uploadListener)
  11. .setHttpBody(new InputStreamBody(fis));
  12. liteHttp.executeAsync(upload);

服务器端 可以这样接收 单个文件 的上传:

  1. private void processEntity(String dir, HttpServletRequest request) {
  2. try {
  3. File uploadFile = new File(dir + "a-upload");
  4. InputStream input = request.getInputStream();
  5. OutputStream output = new FileOutputStream(uploadFile);
  6. byte[] buffer = new byte[4096];
  7. int n = -1;
  8. while ((n = input.read(buffer)) != -1) {
  9. if (n > 0) {
  10. output.write(buffer, 0, n);
  11. }
  12. }
  13. output.close();
  14. } catch (IOException e) {
  15. e.printStackTrace();
  16. }
  17. }

如果是 Servlet ,那么在 doPost 中合适时机调用此方法即可,文件夹位置根据实际情况设置,比如测试时windows系统设置dir = "D:\Downloads", Mac系统设置dir = "/Users/.../Downloads"。由于MD文件的格式化可能导致斜杠不显示,注意斜杠方向和数量要正确。

另外,服务器需要apache提供的jar包支持接收文件,比如:commons-fileupload-1.3.1.jar 等。

上面就是单文件上传的两种方式,mimetype为application/octet-stream,还有一种文件、表单混合,并且可以传多文件的上传方式,mimetype为multipart/form-data,即:表单上传。

2. 表单(多文件)上传(multipart/form-data)

多文件上传,我又在SD卡下面又放了一个文本文件 litehttp.txt:

  1. // litehttp.txt使用流上传;aaa.jpg使用文件式上传。
  2. fis = null;
  3. try {
  4. fis = new FileInputStream(new File("/sdcard/litehttp.txt"));
  5. } catch (Exception e) {
  6. e.printStackTrace();
  7. }
  8. MultipartBody body = new MultipartBody();
  9. body.addPart(new StringPart("key1", "hello"))
  10. .addPart(new StringPart("key2", "很高兴见到你", "utf-8", null))
  11. .addPart(new BytesPart("key3", new byte[]{1, 2, 3}))
  12. .addPart(new FilePart("pic", new File("/sdcard/aaa.jpg"), "image/jpeg"))
  13. .addPart(new InputStreamPart("litehttp", fis, "litehttp.txt", "text/plain"));
  14. // uploadListener上面已经定义,不在重复写
  15. final StringRequest upload = new StringRequest(uploadUrl)
  16. .setMethod(HttpMethods.Post)
  17. .setHttpListener(uploadListener)
  18. .setHttpBody(body);
  19. liteHttp.executeAsync(upload);

服务器端 可以这样接收 多个文件 的上传:

  1. // String fileDir = "D:\\Downloads";
  2. // 这是我的Mac笔记本上的位置,开发者设置为合适自己的文件夹,尤其windows系统。
  3. String fileDir = "/Users/.../Downloads";
  4. String contentType = request.getContentType();
  5. if (contentType.startsWith("multipart")) {
  6. //向客户端发送响应正文
  7. try {
  8. //创建一个基于硬盘的FileItem工厂
  9. DiskFileItemFactory factory = new DiskFileItemFactory();
  10. //设置向硬盘写数据时所用的缓冲区的大小,此处为4K
  11. factory.setSizeThreshold(4 * 1024);
  12. //设置临时目录
  13. factory.setRepository(new File(fileDir));
  14. //创建一个文件上传处理器
  15. ServletFileUpload upload = new ServletFileUpload(factory);
  16. //设置允许上传的文件的最大尺寸,此处为100M
  17. upload.setSizeMax(100 * 1024 * 1024);
  18. Map<String, List<FileItem>> itemMap = upload.parseParameterMap(request);
  19. for (List<FileItem> items : itemMap.values()) {
  20. Iterator iter = items.iterator();
  21. while (iter.hasNext()) {
  22. FileItem item = (FileItem) iter.next();
  23. if (item.isFormField()) {
  24. processFormField(item, writer); //处理普通的表单域
  25. } else {
  26. processUploadedFile(fileDir, item, writer); //处理上传文件
  27. }
  28. }
  29. }
  30. } catch (Exception ex) {
  31. ex.printStackTrace();
  32. }
  33. }
  34. /**
  35. * 处理表单字符数据
  36. */
  37. private void processFormField(FileItem item, PrintWriter writer) {
  38. String name = item.getFieldName();
  39. String value = item.getString();
  40. writer.println("Form Part [" + name + "] value :" + value + "\r\n");
  41. }
  42. /**
  43. * 处理表单文件
  44. */
  45. private void processUploadedFile(String filePath, FileItem item, PrintWriter writer) throws Exception {
  46. String filename = item.getName();
  47. int index = filename.lastIndexOf("\\");
  48. filename = filename.substring(index + 1, filename.length());
  49. long fileSize = item.getSize();
  50. if (filename.equals("") && fileSize == 0)
  51. return;
  52. File uploadFile = new File(filePath + "/" + filename);
  53. item.write(uploadFile);
  54. writer.println(
  55. "File Part [" + filename + "] is saved." + " contentType: " + item
  56. .getContentType() + " , size: " + fileSize + "\r\n");
  57. }

好了,到此为止下载和上传都搞定了,喝杯水休息下...

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注