Android中實現OkHttp上傳檔案到伺服器並帶進度

來源:互聯網
上載者:User

標籤:length   注意   cas   指定   title   build   serve   char   伺服器   

在上一講中 OkHttp下載檔案並帶進度條 中,我們知道怎樣去下載檔案了。那上傳檔案呢

一、編寫伺服器端

在上一講伺服器下建立UploadFileServlet,代碼如下:然後重啟伺服器!

  1. @WebServlet("/UploadFileServlet")
  2. @MultipartConfig
  3. public class UploadFileServlet extends HttpServlet {
  4. private static final long serialVersionUID = 1L;
  5. public UploadFileServlet() {
  6. super();
  7. // TODO Auto-generated constructor stub
  8. }
  9. /**
  10. * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
  11. * response)
  12. */
  13. protected void doGet(HttpServletRequest request, HttpServletResponse response)
  14. throws ServletException, IOException {
  15. this.doPost(request, response);
  16. }
  17. /**
  18. * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
  19. * response)
  20. */
  21. protected void doPost(HttpServletRequest request, HttpServletResponse response)
  22. throws ServletException, IOException {
  23. System.out.println("doPost==");
  24. request.setCharacterEncoding("utf-8");
  25. //擷取file命名的part,注意要與Android端一樣
  26. Part part = request.getPart("file");
  27. // 擷取要求標頭,要求標頭的格式:form-data; name="file"; filename="snmp4j--api.zip"
  28. String header = part.getHeader("content-disposition");
  29. System.out.println(header);
  30. String fileName = getFileName(header);
  31. // 儲存路徑
  32. String savePath = "D:/huang/upload";
  33. // 把檔案寫到指定路徑
  34. part.write(savePath + File.separator + fileName);
  35. response.setCharacterEncoding("UTF-8");
  36. PrintWriter writer = response.getWriter();
  37. writer.print("上傳成功");
  38. }
  39. public String getFileName(String header) {
  40. /**
  41. * header 為 form-data; name="file"; filename="dial.png"
  42. * String[] tempArr1 =
  43. * header.split(";");代碼執行完之後,在不同的瀏覽器下,tempArr1數組裡面的內容稍有區別
  44. * Firefox或者google瀏覽器下:tempArr1={form-data,name="file",filename=
  45. * "snmp4j--api.zip"}
  46. * IE瀏覽器下:tempArr1={form-data,name="file",filename="E:\snmp4j--api.zip"}
  47. */
  48. String[] tempArr1 = header.split(";");
  49. /**
  50. * Firefox或者google瀏覽器下:tempArr2={filename,"snmp4j--api.zip"}
  51. * IE瀏覽器下:tempArr2={filename,"E:\snmp4j--api.zip"}
  52. */
  53. String[] tempArr2 = tempArr1[2].split("=");
  54. // 擷取檔案名稱,相容各種瀏覽器的寫法
  55. String fileName = tempArr2[1].substring(tempArr2[1].lastIndexOf("\\") + 1).replaceAll("\"", "");
  56. return fileName;
  57. }
  58. }
複製代碼

二、Android端

1.布局,上一講activity_main代碼中添加 :

 

  1. <Button
  2. android:id="@+id/ok_post_file"
  3. android:layout_width="match_parent"
  4. android:layout_height="wrap_content"
  5. android:text="上傳檔案" />
  6. <TextView
  7. android:id="@+id/post_text"
  8. android:layout_width="match_parent"
  9. android:layout_height="wrap_content"
  10. android:gravity="center"
  11. android:text="0" />
  12. <ProgressBar
  13. android:id="@+id/post_progress"
  14. style="?android:attr/progressBarStyleHorizontal"
  15. android:layout_width="match_parent"
  16. android:layout_height="wrap_content"
  17. android:max="100" />
複製代碼

2.OkHttpUtil新增上傳檔案方法:

  1. public static void postFile(String url, final ProgressListener listener, Callback callback, File...files){
  2. MultipartBody.Builder builder = new MultipartBody.Builder();
  3. builder.setType(MultipartBody.FORM);
  4. Log.i("huang","files[0].getName()=="+files[0].getName());
  5. //第一個參數要與Servlet中的一致
  6. builder.addFormDataPart("file",files[0].getName(), RequestBody.create(MediaType.parse("application/octet-stream"),files[0]));
  7. MultipartBody multipartBody = builder.build();
  8. Request request = new Request.Builder().url(url).post(new ProgressRequestBody(multipartBody,listener)).build();
  9. okHttpClient.newCall(request).enqueue(callback);
  10. }
複製代碼

3.ProgressRequestBody是自訂RequestBody類,用來監聽進度:

  1. public class ProgressRequestBody extends RequestBody {
  2. public static final int UPDATE = 0x01;
  3. private RequestBody requestBody;
  4. private ProgressListener mListener;
  5. private BufferedSink bufferedSink;
  6. private MyHandler myHandler;
  7. public ProgressRequestBody(RequestBody body, ProgressListener listener) {
  8. requestBody = body;
  9. mListener = listener;
  10. if (myHandler==null){
  11. myHandler = new MyHandler();
  12. }
  13. }
  14. class MyHandler extends Handler {
  15. //放在主線程中顯示
  16. public MyHandler() {
  17. super(Looper.getMainLooper());
  18. }
  19. @Override
  20. public void handleMessage(Message msg) {
  21. switch (msg.what){
  22. case UPDATE:
  23. ProgressModel progressModel = (ProgressModel) msg.obj;
  24. if (mListener!=null)mListener.onProgress(progressModel.getCurrentBytes(),progressModel.getContentLength(),progressModel.isDone());
  25. break;
  26. }
  27. }
  28. }
  29. @Override
  30. public MediaType contentType() {
  31. return requestBody.contentType();
  32. }
  33. @Override
  34. public long contentLength() throws IOException {
  35. return requestBody.contentLength();
  36. }
  37. @Override
  38. public void writeTo(BufferedSink sink) throws IOException {
  39. if (bufferedSink==null){
  40. bufferedSink = Okio.buffer(sink(sink));
  41. }
  42. //寫入
  43. requestBody.writeTo(bufferedSink);
  44. //重新整理
  45. bufferedSink.flush();
  46. }
  47. private Sink sink(BufferedSink sink) {
  48. return new ForwardingSink(sink) {
  49. long bytesWritten = 0L;
  50. long contentLength = 0L;
  51. @Override
  52. public void write(Buffer source, long byteCount) throws IOException {
  53. super.write(source, byteCount);
  54. if (contentLength==0){
  55. contentLength = contentLength();
  56. }
  57. bytesWritten += byteCount;
  58. //回調
  59. Message msg = Message.obtain();
  60. msg.what = UPDATE;
  61. msg.obj = new ProgressModel(bytesWritten,contentLength,bytesWritten==contentLength);
  62. myHandler.sendMessage(msg);
  63. }
  64. };
  65. }
  66. }
複製代碼

4.在MainActivity添加上傳按鈕點擊事件,代碼如下:

  1. File file = new File(basePath + "/1.mp4");
  2. String postUrl = "http://192.168.0.104:8080/OkHttpServer/UploadFileServlet";
  3. OkHttpUtil.postFile(postUrl, new ProgressListener() {
  4. @Override
  5. public void onProgress(long currentBytes, long contentLength, boolean done) {
  6. Log.i(TAG, "currentBytes==" + currentBytes + "==contentLength==" + contentLength + "==done==" + done);
  7. int progress = (int) (currentBytes * 100 / contentLength);
  8. post_progress.setProgress(progress);
  9. post_text.setText(progress + "%");
  10. }
  11. }, new Callback() {
  12. @Override
  13. public void onFailure(Call call, IOException e) {
  14. }
  15. @Override
  16. public void onResponse(Call call, Response response) throws IOException {
  17. if (response != null) {
  18. String result = response.body().string();
  19. Log.i(TAG, "result===" + result);
  20. }
  21. }
  22. }, file);
複製代碼

相關: 

上傳完成後,在電腦D:\huang\upload下可以看到:

Android中實現OkHttp上傳檔案到伺服器並帶進度

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.