美文网首页
Android Http文件上传方法和实践

Android Http文件上传方法和实践

作者: NiceDream | 来源:发表于2021-02-08 17:34 被阅读0次

文件上传在应用中是比较常用的的一种功能,比如用户的意见反馈功能。用户可以上传图片,音视频等文件,方便用户反馈问题的情况。

下来我将和大家一起梳理下需要掌握的知识,少走弯路一步到位,实现文件上传功能。

第一步:了解请求头

需要先大致了解一下上传信息需要的请求结构。当我们掌握了请求头的结构,就可以根据自己项目情况选择sdk或者自己实现HTTP请求。

使用HTTP进行文件上传需要用到POST请求。POST请求包含请求Head 和请求Body。

上传文件需要使用 Content-type为multipart/form-data 的格式,发送请求信息。这种格式的数据会有一个边界线用于分割不同的字段。如下文中的:boundary=86489a0c-3d1f-4351-8f49-58315690babe

请求Head: 一般会携带客户端的一些信息包括签名,token等。服务端用这些信息来校验是否合法。

请求Body: 会携带文件的信息和相关的参数便于服务端进行区分。

消息头可以携带签名信息等字段,用于服务端校验。请求头中的 head1 和head2,代表token,uuid,key等信息用于校验。


POST https://*****/upload
Content-Type: multipart/form-data; boundary=86489a0c-3d1f-4351-8f49-58315690babe
Content-Length: 83014
head1: param
head2: param

消息主体以分界线开始,紧接着就是内容描述信息,可以携带多个字段进行资源数据的描述。最后是字段具体的内容(文本或二进制)。

请求体中的param1 和param2 代表携带文件的相关参数信息,比如文件扩展名等,方便服务端进行区分

--86489a0c-3d1f-4351-8f49-58315690babe
Content-Disposition: form-data; name="param1"
Content-Length: 8
param1

--86489a0c-3d1f-4351-8f49-58315690babe
Content-Disposition: form-data; name="param2"
Content-Length: 3
param2

--86489a0c-3d1f-4351-8f49-58315690babe
Content-Disposition: form-data; name="file"; filename="pic.png"
Content-Type: application/otcet-stream
Content-Length: 82560
*****

--86489a0c-3d1f-4351-8f49-58315690babe

消息主体以boundary结束。

第二步:实践

我们将用目前比较流行的框架实现上面的结构。为了方便了解,我会一一对应的结构,实现上面的Post接口,实际应用中可以充分利用框架的进行接口优化。

方案1:直接使用OKHttp 上传文件

        File file= new File(file);

        // 构建okhttpclient,使用HttpLoggingInterceptor 打印调试日志
        OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder();
        clientBuilder.connectTimeout(Config.DEFAULT_TIMEOUT, TimeUnit.SECONDS);
        HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();
        loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
        clientBuilder.addInterceptor(loggingInterceptor);
        OkHttpClient client = clientBuilder.build();


        // 构造请求头
        Headers.Builder headerBuilder =  new Headers.Builder();
        headerBuilder.add("head1","***");
        headerBuilder.add("head2","***");
        

        // 构造请求体
        MultipartBody.Builder builder = new MultipartBody.Builder();
        builder.setType(MultipartBody.FORM);
        
        
        builder.addPart(
                        Headers.of("Content-Disposition", "form-data; name=\"param1\""),
                        RequestBody.create(null, "param1"));
                        

        builder.addPart(
                        Headers.of("Content-Disposition", "form-data; name=\"param2\""),
                        RequestBody.create(null, "param2"));

        MediaType MEDIA_TYPE_PNG = MediaType.parse("image/png");
        RequestBody filebody = MultipartBody.create(MEDIA_TYPE_PNG, file);
        builder.addFormDataPart("file",file.getName(),filebody);

        MultipartBody body = builder.build();

        // 构造请求
        Request request = new Request.Builder()
                .headers(headerBuilder.build())
                .url("***********")
                .post(body)
                .build();

        // 发起请求
        Call call = client.newCall(request);
        call.enqueue(new Callback() {


            @Override
            public void onFailure(Call call, IOException e) {
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {

            }
        });

方案2:利用Retrofit 上传文件

实例化Retroift 对象

        // 构造okhttp
        OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder();
        clientBuilder.connectTimeout(Config.DEFAULT_TIMEOUT, TimeUnit.SECONDS);

        // 打印网络请求日志
        HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();
        loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
        clientBuilder.addInterceptor(loggingInterceptor);

        mOkHttpClient = httpClientBuilder.build();
        
        // 构造Retrofit
        mRetrofit = new Retrofit.Builder()
                .client(mOkHttpClient)
                .baseUrl(BASE_URL)
                // 增加 Gson转换
                .addConverterFactory(GsonConverterFactory.create())
                .build();

定义Retrofit接口

        @Multipart
        @POST("***")
        Call<ResponseBody> uploadFile(@Header("head1") String head1,
                                  @Header("head2") String head2,
                                  @Part MultipartBody.Part param1,
                                  @Part MultipartBody.Part param2,
                                  @Part MultipartBody.Part multipartBody);
                                  
                                  
    

调用Retrofit接口

        mApiService = NetworkService.getInstance().getService(Api.class);

        //请求体
        MultipartBody.Part param1 = MultipartBody.Part.createFormData("param1", "param1");
        MultipartBody.Part param2 = MultipartBody.Part.createFormData("param2", "param2");

        File file = new File("path");
        RequestBody body = RequestBody.create(MediaType.parse("application/otcet-stream"), file);
        MultipartBody.Part filebody = MultipartBody.Part.createFormData("file",file.getName(),body);

        call = mApiService.uploadFile("head1","head2",param1,param2,filebody);
        call.enqueue(new Callback<ResponseBody>() {
            @Override
            public void onResponse(Call<ResponseBody> call, 

            }

            @Override
            public void onFailure(Call<ResponseBody> call, Throwable t) {

            }
        });

调试工具

对于在家没有后端支持的同学,可以使用 Http File Server 在局域网类部署服务端,然后进行接口测试。
Http File Server 工具可以在百度上搜到,使用的中可以关闭用户校验功能。

相关文章

  • Android Http文件上传方法和实践

    文件上传在应用中是比较常用的的一种功能,比如用户的意见反馈功能。用户可以上传图片,音视频等文件,方便用户反馈问题的...

  • 文件上传和下载

    一.项目用到的图片上传的关键方法:直接使用android-async-http.jar 二、文件下载 1.普通单线...

  • 71. 请求 文件资源

    获取上传文件 你可以使用 Illuminate\Http\Request 实例中的 file 方法获取上传的文件。...

  • Web安全之文件上传漏洞

    文件上传# 1.原因: 2.文件上传过程 3.文件上传详细信息及绕过方法 3.1文件以http协议上传,将以 PO...

  • 手动Mark

    android实现文件的断点上传 http://blog.csdn.net/ZACH_ZHOU/article/d...

  • ubuntu20.04配置ftp服务器-java通过ftpCli

    前言 上传文件有多种方法,比较常用的就是http网页上传或者httpClient后台接口上传,这两种方法之前写过以...

  • JAVA实现文件上传下载

    用户使用方法:文件上传:(1)登录 http://localhost:8080/FileUpload/upload...

  • laravel 上传文件

    1. 获取上传文件 Laravel 使用 Illuminate\Http\Request 的 file() 方法来...

  • HTTP上传文件

    重点:1.修改请求头Content-Type字段 e.g. Content-Type: multipart/for...

  • HTTP上传文件

    http协议之前是没有在提交表单的时候上传文件的功能,然后之后在rfc1867的提议中制订了出来 MIME类型为多...

网友评论

      本文标题:Android Http文件上传方法和实践

      本文链接:https://www.haomeiwen.com/subject/ilbhtltx.html