首页 > 解决方案 > 需要帮助发送表单数据(android)

问题描述

一天中的好时光,我在发送数据方面需要帮助,我是 android 新手,我还不了解所有内容。无论如何,我无法将 Post 请求发送到 multipart / form-data。试图这样做:

public class FilesUploadingTask2 extends AsyncTask<Void, Void, String> {

    // Конец строки
    private String lineEnd = "\r\n";
    // Два тире
    private String twoHyphens = "--";
    // Разделитель
    private String boundary =  "----WebKitFormBoundaryefkgxHeaEjv3FGL7";

    // Переменные для считывания файла в оперативную память
    private int bytesRead, bytesAvailable, bufferSize;
    private byte[] buffer;
    private int maxBufferSize = 1*1024*1024;

    // Путь к файлу в памяти устройства
    private String filePath;
    private JSONObject JsonToSend;
    // Адрес метода api для загрузки файла на сервер
    public final String API_FILES_UPLOADING_PATH = globalvariables.globURL + "/api/v1/shares/report/";

    // Ключ, под которым файл передается на сервер
    public static final String FORM_FILE_NAME = "photos";

    public FilesUploadingTask2(String filePath, JSONObject js) {
        this.filePath = filePath;
        this.JsonToSend = js;
    }
    public void addFormField(BufferedWriter dos, String parameter, String value){
        try {
            dos.write(twoHyphens + boundary + lineEnd);
            dos.write("Content-Disposition: form-data; name=\""+parameter+"\"" + lineEnd);
            dos.write("Content-Type: text/plain; charset=UTF-8" + lineEnd);
            dos.write(lineEnd);
            dos.write(value + lineEnd);
            dos.flush();
        }
        catch(Exception e){

        }
    }
    public void addFormField2(BufferedWriter dos, String parameter, int value){
        try {
            dos.write(twoHyphens + boundary + lineEnd);
            dos.write("Content-Disposition: form-data; name=\""+parameter+"\"" + lineEnd);
            dos.write("Content-Type: text/plain; charset=UTF-8" + lineEnd);
            dos.write(lineEnd);
            dos.write(value + lineEnd);
            dos.flush();
        }
        catch(Exception e){

        }
    }
    public void addFormField3(BufferedWriter dos, String parameter){
        try {
            dos.write(twoHyphens + boundary + lineEnd);
            dos.write("Content-Disposition: form-data; name=\""+parameter+"\"" + lineEnd);
            dos.write("Content-Type: text/plain; charset=UTF-8" + lineEnd);
            dos.write(lineEnd);
            dos.write(null + lineEnd);
            dos.flush();
        }
        catch(Exception e){

        }
    }
    @Override
    protected String doInBackground(Void... params) {
        // Результат выполнения запроса, полученный от сервера
        String result = null;

        try {
            // Создание ссылки для отправки файла
            URL uploadUrl = new URL(API_FILES_UPLOADING_PATH);

            // Создание соединения для отправки файла
            HttpURLConnection connection = (HttpURLConnection) uploadUrl.openConnection();

            // Разрешение ввода соединению
            connection.setDoInput(true);
            // Разрешение вывода соединению
            connection.setDoOutput(true);
            // Отключение кеширования
            connection.setUseCaches(false);

            // Задание запросу типа POST
            connection.setRequestMethod("POST");

            // Задание необходимых свойств запросу
            connection.setRequestProperty("Authorization", "token " + globalvariables.ClientToken);
            connection.setRequestProperty("Connection", "Keep-Alive");
            connection.setRequestProperty("Content-Type", "multipart/form-data;boundary="+boundary);
            connection.setRequestProperty("Accept","application/json");

            // Создание потока для записи в соединение
            DataOutputStream outputStream = new DataOutputStream(connection.getOutputStream());
            BufferedWriter outputStream2 = new BufferedWriter(new OutputStreamWriter(outputStream, "UTF-8"));
            JSONObject Test = new JSONObject();
            Log.d("gogogo", JsonToSend.toString());
            try {
                Test.put("product", 1514);
                Test.put("price", 1514);
                Test.put("quantity", 131);
                Test.put("measure", 0);
                Test.put("productData", JsonToSend.toString());
            } catch (JSONException e) {
                Log.e("MYAPP", "unexpected JSON exception", e);
            }



            // Начало контента
            outputStream.writeBytes(twoHyphens + boundary + lineEnd);
            // Заголовок элемента формы
            outputStream.writeBytes("Content-Disposition: form-data; name=\"" +
                    FORM_FILE_NAME + "\"; filename=\"" + filePath + "\"" + lineEnd);
            // Тип данных элемента формы
            outputStream.writeBytes("Content-Type: image/jpeg" + lineEnd);
            // Конец заголовка
            outputStream.writeBytes(lineEnd);
            // Поток для считывания файла в оперативную память
            FileInputStream fileInputStream = new FileInputStream(new File(filePath));

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

            // Считывание файла в оперативную память и запись его в соединение
            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);

            // Получение ответа от сервера
            int serverResponseCode = connection.getResponseCode();

            // Закрытие соединений и потоков
            fileInputStream.close();
            outputStream.flush();
            outputStream.close();
            addFormField(outputStream2, "products", Test.toString());
            addFormField3(outputStream2, "report_date");
            addFormField3(outputStream2, "report_sum");
            addFormField2(outputStream2, "check_number", 3333);
            addFormField2(outputStream2, "report_sum", 4444);;
            Log.i("STATUS", String.valueOf(connection.getResponseCode()));
            Log.i("MSG" , connection.getRequestMethod());
            // Считка ответа от сервера в зависимости от успеха
            if(serverResponseCode == 201) {
                result = readStream(connection.getInputStream());
            } else {
                result = readStream(connection.getErrorStream());
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (ProtocolException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return result;
    }

    // Считка потока в строку
    public 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();
    }
}

这是所需的调度形式:

{ 照片:[],产品:[],report_date:null,report_sum:null,check_number:“”,qr_img:null,qr_link:“”}

旧的表单数据表单:

------WebKitFormBoundaryefkgxHeaEjv3FGL7 内容处置:表单数据;name="report_date" 2018-08-17T12:00:00.000Z ------WebKitFormBoundaryefkgxHeaEjv3FGL7 内容处置:表单数据;名称="照片"; filename="Снимок экранаот 2018-08-06 15-46-27.png" Content-Type: image/png ------WebKitFormBoundaryefkgxHeaEjv3FGL7 Content-Disposition: form-data; 名称="照片"; filename="Снимок экранаот 2018-08-06 13-38-02.png" Content-Type: image/png ------WebKitFormBoundaryefkgxHeaEjv3FGL7 Content-Disposition: form-data; 名称="照片"; filename="Collage.jpg" Content-Type: image/jpeg ------WebKitFormBoundaryefkgxHeaEjv3FGL7 Content-Disposition: form-data; 名称="照片"; 文件名="Gatsby.jpg" 内容类型:image/jpeg ------WebKitFormBoundaryefkgxHeaEjv3FGL7 Content-Disposition: form-data; name="products" {"product":11292,"price":0,"quantity":"12","measure":10,"productData":{"id":11292,"title":"Bellini multi PG 02 75х300 (1-й сорт)","full_title":"Bellini multi PG 02 75х300 (1-й сорт) Bellini Кв.М.","brand_title":"","collect_title":"Bellini"," slug":"bellini-multi-pg-02-75kh300-1-i-sort","image":null,"brand":null,"collect":1844,"category":23,"barcode":" 010400000177","price":"0.00","measure":10,"measure_display":"Кв.М.","group":"" }} ------WebKitFormBoundaryefkgxHeaEjv3FGL7 Content-Disposition: form-data; name="report_sum" 44440 ------WebKitFormBoundaryefkgxHeaEjv3FGL7 内容处置:表单数据;name="check_number" 33333 ------WebKitFormBoundaryefkgxHeaEjv3FGL7--

我将非常感谢您的帮助,我已经整理了很长时间,但没有成功(PS我为语言知识不佳道歉

标签: android

解决方案


HttpURLConnection与 formdata/multipart 一起使用可能会很棘手,或者需要多行代码。尝试使用像 retrofit 或 okhttp 这样的网络库,它们提供简单的代码和更多的好处。

使用 okhttp :-

首先在gradle中添加依赖:-

compile 'com.squareup.okhttp3:okhttp:3.11.0'

现在创建一个请求:-

OkHttpClient client = new OkHttpClient();
RequestBody requestBody = new MultipartBody.Builder()
    .setType(MultipartBody.FORM)
    .addFormDataPart("somParam", "someValue")
    .build();

Request request = new Request.Builder()
    .url(BASE_URL + route)
    .post(requestBody)
    .build();


 //synchrounous call
  Response response = client.newCall(request).execute();

确保从后台线程调用它,例如。在 asynktask 的 doInBackground 中,并返回 response.body.string()。

好的http参考


推荐阅读