File Upload to Rest Web Service via Android

1

I have a Webservice Rest using the Jersey libraries that are working properly. It turns out that I need to add the functionality of uploading the photos of the items that the user photographs in the field. I added the following code to the WebService:

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

import com.sun.jersey.core.header.FormDataContentDisposition;
import com.sun.jersey.multipart.FormDataParam;

@Path("/fileupload")
public class UploadFileService {

    @POST
    @Path("/upload")
    @Consumes(MediaType.MULTIPART_FORM_DATA)
    public Response upload(
            @FormDataParam("file") InputStream uploadedInputStream,
            @FormDataParam("file") FormDataContentDisposition fileDetail) {

        String uploadedFileLocation = "c://pastadestino/" + fileDetail.getFileName();

        // save it
        writeToFile(uploadedInputStream, uploadedFileLocation);

        String output = "File uploaded to : " + uploadedFileLocation;

        return Response.status(200).entity(output).build();

    }

    private void writeToFile(InputStream uploadedInputStream,
            String uploadedFileLocation) {

        try {
            OutputStream out = new FileOutputStream(new File( uploadedFileLocation ));
            int read = 0;
            byte[] bytes = new byte[1024];

            out = new FileOutputStream(new File( uploadedFileLocation ));
            while ((read = uploadedInputStream.read(bytes)) != -1) {
                out.write(bytes, 0, read);
            }
            out.flush();
            out.close();
        } catch (IOException e) {

            e.printStackTrace();
        }

    }

}

When uploading with the HTML file below:

<html>
<body>
    <h1>Upload File with RESTFul WebService</h1>
    <form action="http://ipservidor:porta/servico/fileupload/upload" method="post" enctype="multipart/form-data">
       <p>
        Choose a file : <input type="file" name="file" />
       </p>
       <input type="submit" value="Upload" />
    </form>
</body>
</html>

works correctly .

But I need it to work on Android.

For this I have the following code:

private class UpLoadFoto extends AsyncTask<String, Void, String> {

        @Override
        protected String doInBackground(String... params) {
            String fileName = params[0];

            HttpURLConnection conn = null;
            DataOutputStream dos = null;
            String lineEnd = "\r\n";
            String twoHyphens = "--";
            String boundary = "*****";
            int bytesRead, bytesAvailable, bufferSize;
            byte[] buffer;
            int maxBufferSize = 1 * 1024 * 1024;
            File sourceFile = new File(params[0]);
            try {

                FileInputStream fileInputStream = new FileInputStream(sourceFile);
                URL url = new URL(servidorremoto + "fileupload/upload/");

                conn = (HttpURLConnection) url.openConnection();
                conn.setDoInput(true);
                conn.setDoOutput(true);
                conn.setUseCaches(false);
                conn.setRequestMethod("POST");
                conn.setRequestProperty("Connection", "Keep-Alive");
                conn.setRequestProperty("ENCTYPE", "multipart/form-data");
                conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
                conn.setRequestProperty("upload_file", fileName);

                dos = new DataOutputStream(conn.getOutputStream());

                dos.writeBytes(twoHyphens + boundary + lineEnd);
                dos.writeBytes("Content-Disposition: form-data; uploadedInputStream=\"uploaded_file\";fileDetail=\"" + fileName + "\"" + lineEnd);

                dos.writeBytes(lineEnd);

                bytesAvailable = fileInputStream.available();

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

                bytesRead = fileInputStream.read(buffer, 0, bufferSize);

                while (bytesRead > 0) {

                    dos.write(buffer, 0, bufferSize);
                    bytesAvailable = fileInputStream.available();
                    bufferSize = Math.min(bytesAvailable, maxBufferSize);
                    bytesRead = fileInputStream.read(buffer, 0, bufferSize);

                }

                dos.writeBytes(lineEnd);
                dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);

                serverResponseCode = conn.getResponseCode();
                String serverResponseMessage = conn.getResponseMessage();

                fileInputStream.close();
                dos.flush();
                dos.close();

            } catch (MalformedURLException ex) {
                ex.printStackTrace();

            } catch (Exception e) {
                e.printStackTrace();
            }
            return "";
        }
    }

When I run this code on Android I get the message: Bad Request

Someone could tell me where I'm going wrong.

Thank you.

    
asked by anonymous 14.06.2016 / 19:57

1 answer

1

Resolved.

Replace line:

 conn.setRequestProperty("upload_file", fileName);

by this:

  conn.setRequestProperty("file", uploadFileName);

The file parameter here must match the WebService parameter there - obvious .

WebService line:

@FormDataParam("file") FormDataContentDisposition fileDetail) 

As written here file . There on Android has to be the same. uploadFileName contains the name of the BLBLABLA.JPG file

And replaces the line:

 dos.writeBytes("Content-Disposition: form-data; uploadedInputStream=\"uploaded_file\";fileDetail=\"" + fileName + "\"" + lineEnd);

For this:

  dos.writeBytes("Content-Disposition: form-data; name=\"file\";filename=\"" + uploadFileName + "\"" + lineEnd);

Must have the name tag and the filename tag for the same reasons as above.

For those who need to use the method UpLoadFoto is called like this:

  new UpLoadFoto().execute( NomeCompletoFoto );

FullNameFoto is equal to /storage/emulated/0/20160615160909.JPG, for example.

Ready. A code in WebService and Android fully functional.

    
15.06.2016 / 21:11