HTTURLConnection上传不是100%正常工作

时间:2014-02-03 17:57:53

标签: java httpurlconnection http-upload

我正在尝试使用以下代码将文件上传到服务器,上传工作正常,但有效负载已添加到文件中,您可以看到它上传文本文件:

private Integer doFileUpload(final String urlServer) {
    HttpURLConnection connection = null;
    DataOutputStream outputStream = null;
    FileInputStream fileInputStream = null;

    final String pathToOurFile = mFileInfo.getProviderPath();
    final String lineEnd = "\r\n";
    final String twoHyphens = "--";
    final String boundary = "*****";

    int fileLength;
    int bytesToRead, bufferSize;
    final long fileSize;
    byte[] buffer;
    final int maxBufferSize = 1 * 1024 * 1024;

    try {
        final File file = new File(pathToOurFile);

        fileInputStream = new FileInputStream(file);

        final URL url = new URL(urlServer);
        connection = (HttpURLConnection) url.openConnection();

        final String[] payload = { twoHyphens + boundary + lineEnd,
                "Content-Disposition: form-data; name=\"uploadedfile\";filename=\"" + pathToOurFile + "\"" + lineEnd, lineEnd, lineEnd,
                twoHyphens + boundary + twoHyphens + lineEnd };

        int payloadLength = 0;
        for (final String string : payload) {
            payloadLength += string.getBytes("UTF-8").length;
        }
        Logger.d(AsyncEgnyteUploadFile.LOGGING_TAG, "payload length: " + payloadLength);
        fileLength = (int) file.length();
        Logger.d(AsyncEgnyteUploadFile.LOGGING_TAG, "bytes: " + fileLength);
        connection.setFixedLengthStreamingMode(fileLength + payloadLength);
        fileSize = fileLength;

        // Allow Inputs & Outputs
        connection.setDoInput(true);
        connection.setDoOutput(true);
        connection.setUseCaches(false);

        connection.setReadTimeout(5000);
        connection.setConnectTimeout(5000);

        connection.setRequestProperty("Authorization", "Bearer " + mToken);

        // Enable POST method
        connection.setRequestMethod(HttpPost.METHOD_NAME);

        connection.setRequestProperty("Connection", "close");

        // This header doesn't count to the number of bytes being sent.
        connection.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);

        connection.connect();
        outputStream = new DataOutputStream(connection.getOutputStream());

        outputStream.writeBytes(payload[0]);
        outputStream.writeBytes(payload[1]);
        outputStream.writeBytes(payload[2]);

        bufferSize = Math.min(fileLength, maxBufferSize);
        buffer = new byte[bufferSize];

        long totalBytesRead = 0;
        long lastProgressTime = 0;

        // Read file
        bytesToRead = fileInputStream.read(buffer, 0, bufferSize);

        boolean stopUploading = (FileState.UPLOADING != mFileInfo.getState() || isCancelled());
        while (bytesToRead > 0 && !stopUploading)
        {
            outputStream.write(buffer);
            totalBytesRead += bytesToRead;
            Logger.d(AsyncEgnyteUploadFile.LOGGING_TAG, "bytes written: " + totalBytesRead);

            final long now = System.currentTimeMillis();                

            bufferSize = (int) Math.min(fileLength - totalBytesRead, maxBufferSize);
            buffer = new byte[bufferSize];
            bytesToRead = fileInputStream.read(buffer, 0, bufferSize);
        }

        outputStream.writeBytes(payload[3]);
        outputStream.writeBytes(payload[4]);

        // Responses from the server (code and message)
        final int serverResponseCode = connection.getResponseCode();

        if (serverResponseCode == HttpStatus.SC_OK || serverResponseCode == HttpStatus.SC_CREATED) {                
            mAlreadyUploaded = true;
            return JBError.JBERR_SUCCESS;
        } else {
            Log.e(AsyncEgnyteUploadFile.LOGGING_TAG, "error code: " + serverResponseCode);
            return serverResponseCode;
        }

    } catch (final SocketTimeoutException e) {
        ..
    } catch (final UnknownHostException e) {
        ..
    } catch (final SocketException e) {
        ..
    } catch (final IOException e) {
        ..
    } catch (final Exception ex) {
        ..
    } finally {
        closeAll(connection, fileInputStream, outputStream);
    }
}

使用此代码上传仅包含12345的文本文件会产生以下结果:

--*****
Content-Disposition: form-data; name="uploadedfile";filename="/storage/emulated/0/Download/3.txt"

12345
--*****--

我做错了什么?

2 个答案:

答案 0 :(得分:0)

你复制代码是错误的。这是如何在Java中复制流:

while ((count = in.read(buffer)) > 0)
{
    out.write(buffer, 0, count);
}

注意:

  1. 您必须检查所有读取是否为流末尾。
  2. 您必须在write()方法中使用读取计数。
  3. 每次读取不需要新的缓冲区,并且您不需要与文件大小相同的缓冲区。这适用于任何大于零的缓冲区大小。我通常使用8192。

答案 1 :(得分:0)

我怀疑您的服务器没有设计/配置为处理“多部分”上传。

肯定看起来就像把它视为普通上传......我看不到任何与多部分封装相关的东西。

(EJP是正确的,但这不是导致您的问题的原因。您的示例显示所有字符都已发送...)