N
N
Nikolai2017-07-09 15:36:34
Java
Nikolai, 2017-07-09 15:36:34

How to send a photo using API conditions?

Hello. I was faced with the task of uploading photos to the server. Here is a piece of instructions
All requests to the API must have the Content-Type: application/json header, except for requests where files are uploaded, since we use "multipart/form-data" there.
Adding a photo to a profile
POST 254.254.254.254/accounts/profile/add_photo
Maximum photo size is 4MB.
I upload photos through the AsyncTask class with the following code:

import android.os.AsyncTask;
import android.util.Log;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

public class Task_finder extends AsyncTask<Void, Void, Void> {

    File file;

    String token;


    public Task_finder(File file, String token){
        this.file = file;
        this.token = token;
        Log.d("responseAPI", "sp.token = " + token);
    }

    @Override
    protected Void doInBackground(Void... arg0) {
        if(token.equals("")){
            Log.d("responseAPI", "sp.token = \"\"");
            return null;
        }
        String result = null;
        HttpURLConnection conn = null;
        DataOutputStream dos = null;
        String existingFileName = file.getAbsolutePath();
        String lineEnd = "\r\n";
        String twoHyphens = "--";
        String boundary =  "*****" + System.currentTimeMillis();
        int bytesRead, bytesAvailable, bufferSize;
        byte[] buffer;
        int maxBufferSize = 1*1024*1024;
        String urlString = "http://254.254.254.254/accounts/profile/add_photo/";
        try{
            FileInputStream fileInputStream = new FileInputStream(new File(existingFileName) );
            URL url = new URL(urlString);
            conn = (HttpURLConnection) url.openConnection();
            conn.setDoInput(true);
            conn.setDoOutput(true);
            conn.setUseCaches(false);
            conn.setRequestMethod("POST");
            conn.setRequestProperty("Content-Type", "multipart/form-data;boundary="+boundary);
            conn.setRequestProperty("Authorization", "Token " + token);
            dos = new DataOutputStream( conn.getOutputStream() );
            dos.writeBytes(twoHyphens + boundary + lineEnd);
            String t = "Content-Disposition: form-data; name=\"image\";filename=\"" + file.getName() + "\"" + lineEnd;
            Log.d("responseAPI", "t = " + t);
            dos.writeBytes(t); // uploaded_file_name is the Name of the File to be uploaded
            dos.writeBytes("Content-Type: image upload" + 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);

            int serverResponseCode = conn.getResponseCode();

            fileInputStream.close();
            dos.flush();
            dos.close();
            if(serverResponseCode == 200) {
                result = readStream(conn.getInputStream());
            } else {
                result = readStream(conn.getErrorStream());
            }
            Log.e("responseAPI", "result = " + result);
        } catch (IOException ioe){
            Log.e("Debug", "error: " + ioe.getMessage(), ioe);
        }
        //------------------ read the SERVER RESPONSE
        try {
            int i = conn.getResponseCode();
            Log.e("responseAPI","responseCode = "+i);
        }
        catch (IOException ioex){
            Log.e("Debug", "error: " + ioex.getMessage(), ioex);
        }
        return null;
    }

    public static String readStream(InputStream inputStream) throws IOException {
        StringBuffer buffer = new StringBuffer();
        BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));

        String line;
        while ((line = reader.readLine()) != null) {
            buffer.append(line);
        }

        return buffer.toString();
    }

    @Override
    protected void onPostExecute(Void result) {
    }
}

I call this class like this:
Task_finder task = new Task_finder(new File(filePath), "8asd9d8as9das09af998" /*this is token*/);
                    task.execute();

As a result, I get a response from the server:
responseCode = 400
result = {"image":["The file was not loaded."]}

The request type is incorrect. I've been tinkering for the second day. Tell me, maybe I'm doing something wrong?
Or are there simpler methods to implement this ...
Thank you!

Answer the question

In order to leave comments, you need to log in

1 answer(s)
Z
Zakhar Zolotarev, 2017-07-13
@niklas1987

Think about the meaning of being, stop using asynctax, use retrofit like this,
or leave everything as it is, but still use retrofit but with a synchronous call (the return type of the first method from the link above is like this )
and call it all in the doInBackground
body normally substitute)

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question