Httpurlconnection multipart / form-data kullanarak arraylist yükleyin


11

ArraylistHerhangi bir kütüphane kullanmadan görüntüleri sunucuya yüklemem gerekiyor . AsynctaskTek bir resim yüklemek için kullanıyorum ve httpurlconnection multipart / form-data yardımıyla mükemmel çalışıyor. Şimdi kullanarak herhangi bir tür birden fazla dosya yüklemek için kodumu değiştirmek gerekiyor Arraylist<String>ama benim sorunum mevcut kodun FileinputStreamarraylist desteklemiyor ve ben Fileinputstreamsunucuya arraylist yüklemek için ne kullanmak için bir fikrim yok ve ben yok bunun için de herhangi bir kütüphane kullanmak istersiniz.

public class multipart_test extends AsyncTask<Void,Void,String> {
    Context context;
    String Images;
    public static final String TAG = "###Image Uploading###";


    public multipart_test(Context context,String Upload_Images) {
        this.context = context;
        this.Images = Upload_Images;

    }

    @Override
    protected String doInBackground(Void... params) {
        BufferedReader reader;
        String WebPath = null;
        try {
            String lineEnd = "\r\n";
            String twoHyphens = "--";
            String boundary = "*****";
            int bytesRead, bytesAvailable, bufferSize;
            byte[] buffer;
            int maxBufferSize = 1024 * 1024;
            //todo change URL as per client ( MOST IMPORTANT )
            URL url = new URL("10.0.0.1/uploadMultipart.php");
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();

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

            // Set HTTP method to POST.
            connection.setRequestMethod("POST");
            connection.setRequestProperty("Connection", "Keep-Alive");
            connection.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
            FileInputStream fileInputStream;
            DataOutputStream outputStream;
            outputStream = new DataOutputStream(connection.getOutputStream());
            outputStream.writeBytes(twoHyphens + boundary + lineEnd);

            outputStream.writeBytes("Content-Disposition: form-data; name=\"reference\""+ lineEnd);
            outputStream.writeBytes(lineEnd);
            //outputStream.writeBytes("my_refrence_text");
            outputStream.writeBytes(lineEnd);
            outputStream.writeBytes(twoHyphens + boundary + lineEnd);

            outputStream.writeBytes("Content-Disposition: form-data; name=\"uploadFile\";filename=\"" + "profileImage" +"\"" + lineEnd);
            outputStream.writeBytes(lineEnd);

            //Dummy ArrayList for upload
            ArrayList<String> uploadFiles = new ArrayList<>();
            uploadFiles.add(Images);
            uploadFiles.add(Images);
            uploadFiles.add(Images);
            uploadFiles.add(Images);


            fileInputStream = new FileInputStream(uploadFiles); // NOT SUPPORTING ARRAYLIST HERE
            bytesAvailable = fileInputStream.available();
            bufferSize = Math.min(bytesAvailable, maxBufferSize);
            buffer = new byte[bufferSize];

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

            while (bytesRead > 0) {
                outputStream.write(buffer, 0, bufferSize);
                bytesAvailable = fileInputStream.available();
                bufferSize = Math.min(bytesAvailable, maxBufferSize);
                bytesRead = fileInputStream.read(buffer, 0, bufferSize);

            outputStream.writeBytes(lineEnd);
            outputStream.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
                fileInputStream.close();
            }
            // Responses from the server (code and message)
            int serverResponseCode = connection.getResponseCode();
            String result = null;
            if (serverResponseCode == 200) {
                StringBuilder s_buffer = new StringBuilder();
                InputStream is = new BufferedInputStream(connection.getInputStream());
                BufferedReader br = new BufferedReader(new InputStreamReader(is));
                String inputLine;
                while ((inputLine = br.readLine()) != null) {
                    s_buffer.append(inputLine);
                }
                result = s_buffer.toString();
            }
            connection.getInputStream().close();
            outputStream.flush();
            outputStream.close();
            if (result != null) {
                Log.d("result_for upload", result);
            }
            return WebPath;
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (ProtocolException e) {
            e.printStackTrace();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }


}

Ben de FileInputStreamdöngü içine koymak için çalıştı ama görüntüleri birden fazla istek içine yüklemek istediğim şey değil. Sunucumun uygulaması, n sayıda resim için tek bir istekte bulunmasını gerektiriyor. Herhangi bir yardım takdir edilecektir, ancak herhangi bir kütüphane kullanmadan


Http sınıfları kullanımdan kaldırıldı, sonradan yükseltme veya başka bir kütüphane kullanın
Jaiprakash Soni

güçlendirme kullanabilir ve tek bir istekte birden fazla görüntü yükleyebilirsiniz
Priyankagb

Yanıtlar:


4

Bu kod yanlışlıkla HttpURLConnection ile çalışır, ancak denemedim unutmayın.

İnternetten okuduğumdan, bahsettiğiniz döngüyü yine de kullanabilirsiniz, ancak bazı değişiklikler ile.

Ben dev.to burada çok parçalı / form-veri öğretici izledi, bu bir öğrenme yazı daha yapmak için size bu yöntem ne olması gerektiğini söyleyeceğim.

Çok parçalı / form verileri bu şekilde gönderilir

--boundary
Content-Disposition: form-data; name="something1"

data1
--boundary
Content-Disposition: form-data; name="something2"

data2
--boundary--

Ne yapacağım yeni bir yöntem oluşturmaktır, ancak sadece mevcut yönteminizdeki kodu yazabilirsiniz.

public byte[] get_multipart_data(List<String> files, String boundary)

Yazmak istediğiniz sınır, ardından düzen ve ardından verilerdir . Bunu tüm dosyalar için yapın ve ardından kapanış sınırını gönderin . Bu, istediğiniz çok parçalı / form-veri yapısını oluşturur.

Psudo-code'da bu

loop for all files
    write "--boundary"
    write "Content-Disposition: ...."
    write image_data
end
write "--boundary--"

Kod şöyle yazılabilir, önce değişkenlerinizi tanımlarsınız

ByteArrayOutputStream message = null;
DataOutputStream stream = null;

FileInputStream fileInputStream;

int maxBufferSize = 1024 * 1024;
byte[] buffer = new byte[maxBufferSize];
byte[] sendData = new byte[0];

Veriler burada üretilecek. Sınırın birleştirilmesi ve ardından verilerin okunması ile başlar . Bu veriler akışa yazılır ve tüm dosyalar / resimler için döngüye devam edersiniz.

try {
    message = new ByteArrayOutputStream();
    stream = new DataOutputStream(message);

    // Loop though all file names
    for(String fileName : files) {
        stream.writeBytes("--" + boundary + "\r\n"); // Start boundary
        stream.writeBytes("Content-Disposition: form-data; name=\"" + fileName + "\"\r\n\r\n");

        // Read the image data
        fileInputStream = new FileInputStream(fileName);
        int readBytes = 0;
        while((readBytes = fileInputStream.read(buffer)) != -1) {
            // Write file data to output
            stream.write(buffer, 0, readBytes);
        }
        fileInputStream.close();

        stream.writeBytes("\r\n");
    }
    stream.writeBytes("--" + boundary + "--\r\n"); // Closing boundary

    sendData = message.toByteArray();
} catch(IOException e) {
    e.printStackTrace();
}

Şimdi bayt dizisi sendData, HttpURLConnection'ınızla göndermeniz gereken çok bölümlü / form verilerini içerecektir.

Burada uzun zamandır aktif değilim. Daha spesifikasyona ihtiyacınız olup olmadığını veya metnimi açıklığa kavuşturduğumu söyleyin: D


Ben döngü çalıştırmak sonra dizi yükleme için birden fazla istek yapmak gerekir. Tek çağrıda sunucuya bir dizi yüklemem gerekiyor.
Ritu

Ne undertod gelen tek bir HttpURLConnection çağrısında sunucuya n görüntü göndermek istiyorum. ZipEntry ile dosyaları girdiğiniz bir zip formatı kullanmayı deneyebilirsiniz, aksi takdirde yazdıklarım hala tek bir istek olacaktır. @Ritu
HardCoded

Zaman uyumsuzluğunuzun dışında bir döngü kullanmak sizin için mümkün mü? Örneğin, yükleme için 3 dosyanız varsa, bağımsız olarak 3 zaman uyumsuz yürütürsünüz. Bu şekilde bir görüntü (yükleme işlemi) için bir sorun veya sorun bulunursa, diğer görüntüler (işlemler) yüklenmeye devam eder. sınıfınızdaki bir sayaçla sayın ve gerekirse bir gecikme süresi (tahmini süre) tutun (yükleme sırasında mevcut bir sorun hakkında uyarmak için).
maniaq

1
@maniaq Aynı görev için birden fazla zaman uyumsuzluğu çalıştırmak en uygun kod değildir. Mümkün olan her yerde şebeke çağrısından kaçınmalıyız.
androidXP

0

FileinputStream , ArrayList'i desteklemez. Ancak ObjectOutputStream kullanarak bir yol var . Ayrıca ArrayList'inizi serileştirir. Koddaki değişiklikleri kontrol edin.

       //Changes required in your code
        ArrayList<String> uploadFiles = new ArrayList<>();
        uploadFiles.add(Images);
        uploadFiles.add(Images);
        uploadFiles.add(Images);
        uploadFiles.add(Images);

        fileInputStream = new FileInputStream("listImages"); 
        java.io.ObjectOutputStream oos = new java.io.ObjectOutputStream(fileInputStream); 
        oos.writeObject(uploadFiles);

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

Mutlu Kodlama :)


0

Tek eşzamansız görev kullanmanın sizin için bir zorunluluk olup olmadığından emin değilim.

Söylediğiniz gibi, kodunuz tek görüntü için kesinlikle iyi çalışıyor. Bu yüzden arraylist'ten birden fazla dosya yüklemek için AsyncTask'ınızı biraz değiştirmeniz yeterlidir. Sadece bir dosyayı birbiri ardına yükleyin Veya bu kadar fazla değişiklik yapmak istemiyorsanız, sadece yüklenen öğenin dizinini tutan global değişkeni beyan edin ve OnPostExecute'de async görevinin yeni bir örneğini oluşturun ve bir sonraki öğeyi arististe aktarın. Umarım bu açıktır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.