Android-日常遭遇-文件上传MIME协议

写上传文件的时候,需要产生part才能让文件上传成功,

而android原生并没有提供这样的方法,需要自己写.首先看下mime协议

MIME Multipart Media Encapsulation, Type: multipart/form-data, Boundary: "AF+hwZxkNq38nq6w4liUUA"
    [Type: multipart/form-data]
    First boundary: --AF+hwZxkNq38nq6w4liUUA==\r\n
    Encapsulated multipart part: 
        Data (102 bytes)
            Data: 2d2d41462b68775a786b4e7133386e713677346c69555541...
            [Length: 102]
    Boundary: \r\n--AF+hwZxkNq38nq6w4liUUA==\r\n
    Encapsulated multipart part:  (application/octet-stream)
        Content-Disposition: form-data; name="userfile"; filename="aaa.mp4"\r\n
        Content-Type: application/octet-stream\r\n\r\n
        Data (2003015 bytes)
            Data: 000000206674797069736f6d0000020069736f6d69736f32...
            [Length: 2003015]
    Boundary: \r\n--AF+hwZxkNq38nq6w4liUUA==--\r\n
    Encapsulated multipart part: 

可以看出,是由

--边界码

Content-Disposition-key

value

--边界码

...

--边界码--

结束

由此可以模仿出

 


    private void postFile(PostFormBody body) throws IOException {
        // 说明有文件
        // 边界标识 随机生成
        Random random      = new Random();
        byte[] randomBytes = new byte[16];
        random.nextBytes(randomBytes);
        String boundary = Base64.encodeToString(randomBytes, Base64.NO_WRAP);
        String prefix   = "--";
        String lineEnd  = "\r\n";
        currentCallRequest.getConnection().setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
        OutputStream     outputStream = currentCallRequest.getConnection().getOutputStream();
        DataOutputStream out          = putParams(body, boundary, prefix, lineEnd, outputStream);
        putFile(body, boundary, prefix, lineEnd, out);
        out.flush();
        out.close();
    }

    @NonNull
    private DataOutputStream putParams(PostFormBody body, String boundary, String prefix, String lineEnd, OutputStream outputStream) throws IOException {
        DataOutputStream    out      = new DataOutputStream(outputStream);
        Map<String, String> queryMap = body.params;
        if (queryMap != null && !queryMap.isEmpty()) {
            StringBuilder sb = new StringBuilder();
            for (Map.Entry<String, String> entry : queryMap.entrySet()) {
                String key   = entry.getKey();
                String value = entry.getValue();
                sb.append(prefix).append(boundary).append(lineEnd);
                out.write(sb.toString().getBytes());
                sb.append("Content-Disposition")
                        .append(": ")
                        .append("form-data")
                        .append("; name=\"")
                        .append(key)
                        .append("\"")
                        .append(lineEnd);
                sb.append("Content-Length")
                        .append(": ")
                        .append(value.length())
                        .append(lineEnd)
                        .append(lineEnd);
                sb.append(value).append(lineEnd);

            }
            out.write(sb.toString().getBytes());
            out.flush();
        }
        return out;
    }

    private void putFile(PostFormBody body, String boundary, String prefix, String lineEnd, DataOutputStream out) throws IOException {
        StringBuilder sb = new StringBuilder();
        sb.append(prefix).append(boundary).append(lineEnd);
        sb.append(CONTENT_DISPOSITION)
                .append(": ")
                .append("form-data")
                .append("; name=\"")
                .append(body.keyFile)
                .append("\"; filename=\"")
                .append(body.mFile.getName())
                .append("\"")
                .append(lineEnd);
        sb.append( + "Content-Type: application/octet-stream").append(lineEnd);
        sb.append(lineEnd);
        out.write(sb.toString().getBytes());
        out.flush();
        InputStream input = new FileInputStream(body.mFile);
        byte[]      bytes = new byte[1024];
        int         len   = 0;
        while ((len = input.read(bytes)) != -1) {
            out.write(bytes, 0, len);
        }
        out.write(lineEnd.getBytes());
        out.flush();
        byte[] endData = (prefix + boundary + prefix + lineEnd).getBytes();
        out.write(endData);
        out.flush();
        input.close();
    }

PostFormBody

    public Map<String, String> params;
    public String              keyFile;
    public File                mFile;

    private PostFormBody(Builder builder) {
        params = builder.params;
        keyFile = builder.keyFile;
        mFile = builder.mFile;
    }

这里有一点需要注意

currentCallRequest.getConnection().setRequestProperty(CONTENT_TYPE, TYPE_FORM_DATA_NO_CHARSET + "; boundary=" + boundary);

这边是不能有引号以及其他符号,如果有其他符号会导致文件上传,将数据叠加到一起.导致上传失败

如果是正常,则会让协议成功

详细封装可以看我的github

EHttp

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值