0

I already referred this link Sending files using POST with HttpURLConnection

Using the following code, I'm trying to POST a file to local PHP server. It always return file size 0 in my PHP file

public class FileUpload2 {
    String CRLF = "\r\n";
    /**
     * @param args
     * @throws Exception
     */
public static void main(String[] args) throws Exception {

    new FileUpload2().put("http://localhost/test/test.php");

}

public void put(String targetURL) throws Exception {

    String BOUNDRY = "==================================";
    HttpURLConnection conn = null;

    try {

        // These strings are sent in the request body. They provide
        // information about the file being uploaded
        String contentDisposition = "Content-Disposition: form-data; name=\"userfile\"; filename=\"test.txt\"";
        String contentType = "Content-Type: application/octet-stream";

        // This is the standard format for a multipart request
        StringBuffer requestBody = new StringBuffer();
        requestBody.append("--");
        requestBody.append(BOUNDRY);
        requestBody.append(CRLF);
        requestBody.append(contentDisposition);
        requestBody.append(CRLF);
        requestBody.append(contentType);
        requestBody.append(CRLF);

        requestBody.append("Content-Transfer-Encoding: binary" + CRLF);
        requestBody.append(CRLF);

        requestBody.append(new String(getFileBytes("test.txt")));
        requestBody.append("--");
        requestBody.append(BOUNDRY);
        requestBody.append("--");
        requestBody.append(CRLF);

        // Make a connect to the server
        URL url = new URL(targetURL);
        conn = (HttpURLConnection) url.openConnection();

        conn.setDoOutput(true);
        conn.setDoInput(true);
        conn.setUseCaches(false);
        conn.setRequestMethod("POST");
        conn.setRequestProperty("Connection", "Keep-Alive");
        conn.setRequestProperty("Content-Type",
                "multipart/form-data; boundary=" + BOUNDRY);
        conn.setRequestProperty("Cache-Control", "no-cache");

        // Send the body
        DataOutputStream dataOS = new DataOutputStream(
                conn.getOutputStream());
        dataOS.writeBytes(requestBody.toString());
        dataOS.flush();
        dataOS.close();

        // Ensure we got the HTTP 200 response code
        int responseCode = conn.getResponseCode();
        if (responseCode != 200) {
            throw new Exception(String.format(
                    "Received the response code %d from the URL %s",
                    responseCode, url));
        }

        // Read the response
        InputStream is = conn.getInputStream();
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        byte[] bytes = new byte[1024];
        int bytesRead;
        while ((bytesRead = is.read(bytes)) != -1) {
            baos.write(bytes, 0, bytesRead);
        }
        byte[] bytesReceived = baos.toByteArray();
        baos.close();

        is.close();
        String response = new String(bytesReceived);
        System.out.println(response);
        // TODO: Do something here to handle the 'response' string

    } finally {
        if (conn != null) {
            conn.disconnect();
        }
    }

}


public byte[] getFileBytes(String file) throws IOException {
    ByteArrayOutputStream ous = null;
    InputStream ios = null;
    try {
        byte[] buffer = new byte[4096];
        ous = new ByteArrayOutputStream();
        ios = this.getClass().getResourceAsStream(file);
        int read = 0;
        while ((read = ios.read(buffer)) != -1)
            ous.write(buffer, 0, read);
    } finally {
        try {
            if (ous != null)
                ous.close();
        } catch (IOException e) {
            // swallow, since not that important
        }
        try {
            if (ios != null)
                ios.close();
        } catch (IOException e) {
            // swallow, since not that important
        }
    }
    return ous.toByteArray();
}

PHP File

<?php 
move_uploaded_file($_FILES['userfile']["tmp_name"], "test.txt");
//file_put_contents("test", "asd".$_FILES['userfile']);
print_r($_FILES);
print_r($_REQUEST);
?>

Result I'm getting is

Array
(
    [userfile] => Array
        (
            [name] => test.txt
            [type] => 
            [tmp_name] => 
            [error] => 3
            [size] => 0
        )

)
Array
(
)

Thanks in advance!

Community
  • 1
  • 1
Jeyasithar
  • 543
  • 4
  • 17
  • Why are you converting a text file to bytes and then back to string? Even if you'd have a binary file you should not just create a string out of those bytes since there might be control characters that could blow up your request but rather encode the bytes using base64 or the like. – Thomas Aug 20 '14 at 10:49
  • Btw, doesn't `[error] => 3` indicate there is at least one error? If so, you might check and post what error that is. – Thomas Aug 20 '14 at 10:50
  • [error] => 3 means Partial file uploaded as per PHP documentation – Jeyasithar Aug 20 '14 at 10:52
  • Should I decode in receiving side if I'm encrypting using Base64 class? Show I writeBytes instead of string append and then writing to bytes? Please advise. – Jeyasithar Aug 20 '14 at 10:56
  • 1
    Of course you'd need to decode on the receiving side (btw that's not _encryption_ just _encoding_). As I said, I'd advise against writing bytes of binary data to a string unencoded, since that could result in unwanted control characters like `\0` (or unicode `\u0000`). And if you only have text files, then I'd read those files as strings and not byte arrays. – Thomas Aug 20 '14 at 11:08
  • 1
    As a side note: the constructor `String(byte[])` would use the JVM's default encoding to convert the bytes to characters. If that encoding doesn't match the encoding used to create the byte array you won't get back the string you expect (it might work in some rare cases where encodings overlap, but don't count on that). So you might want to pass the character encoding as a parameter, e.g. by using `String(byte[],String)` or `String(byte[], Charset)`. – Thomas Aug 20 '14 at 11:11
  • Ok. I just changed this line requestBody.append(new String(getFileBytes("test.txt"))); to requestBody.append("Some String which is the file content"); getting the same result :( – Jeyasithar Aug 20 '14 at 11:33
  • Actually I do not have access to server side. Just for testing sake, I'm using localhost – Jeyasithar Aug 20 '14 at 11:55

1 Answers1

1

Finally I've solved the problem by adding apache http client library instead of HttpUrlConnection.

/*
 * ====================================================================
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 *
 */

import java.io.BufferedReader;
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;

import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

/**
 * Example how to use multipart/form encoded POST request.
 */
public class ClientMultipartFormPost {

    public static void main(String[] args) throws Exception {
        /*if (args.length != 1)  {
            System.out.println("File path not given");
            System.exit(1);
        }*/
        CloseableHttpClient httpclient = HttpClients.createDefault();
        InputStream responseStream = null ;
        String responseString = "" ;
        try {
            HttpPost httppost = new HttpPost("http://localhost/test/test.php");

            FileBody bin = new FileBody(new File("D:/Jeyasithar/Workspace/Java/TestJava/src/test.txt"));
            StringBody comment = new StringBody("A binary file of some kind", ContentType.TEXT_PLAIN);

            HttpEntity reqEntity = MultipartEntityBuilder.create()
                    .addPart("bin", bin)
                    .addPart("comment", comment)
                    .build();


            httppost.setEntity(reqEntity);

            System.out.println("executing request " + httppost.getRequestLine());
            CloseableHttpResponse response = httpclient.execute(httppost);
            try {
                System.out.println("----------------------------------------");
                System.out.println(response.getStatusLine());
                HttpEntity resEntity = response.getEntity();
                if (resEntity != null) {
                    System.out.println("Response content length: " + resEntity.getContentLength());

                    responseStream = resEntity.getContent() ;
                    if (responseStream != null){
                        BufferedReader br = new BufferedReader (new InputStreamReader (responseStream)) ;
                        String responseLine = br.readLine() ;
                        String tempResponseString = "" ;
                        while (responseLine != null){
                            tempResponseString = tempResponseString + responseLine + System.getProperty("line.separator") ;
                            responseLine = br.readLine() ;
                        }
                        br.close() ;
                        if (tempResponseString.length() > 0){
                            responseString = tempResponseString ;
                            System.out.println(responseString);
                        }
                    }

                }
                EntityUtils.consume(resEntity);

            } finally {
                response.close();
            }
        } finally {
            httpclient.close();
        }
    }

}
Jeyasithar
  • 543
  • 4
  • 17