简体   繁体   中英

HTTURLConnection Upload not 100% working

I am trying to upload a file to a server with following code, the upload works, but the payload is added to the file, you can see it for example uploading a text file:

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);
    }
}

Uploading a text file with only 12345 inside with this code results in following:

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

12345
--*****--

What am I doing wrong?

You copy code is wrong. This is how to copy between streams in Java:

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

Notes:

  1. You must check all reads for end of stream.
  2. You must use the read count in the write() method.
  3. You don't need a new buffer per read, and you don't need a buffer the size of the file. This will work with any buffer size greater than zero. I usually use 8192.

I suspect that your server is not designed / configured to handle "multi-part" uploads.

It certainly looks like it is treating this as a plain upload ... and I cannot see anything wring with the multi-part encapsulation.

(EJP is correct, but that is not what is causing your problem here. Your example shows that all of the characters were sent ...)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM