Как отправить тело в виде form-data?

В Java можно отправить тело запроса в формате form-data с использованием стандартной библиотеки Java и HTTPURLConnection класса. Для этого можно использовать следующий код:

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.UUID;

public class FormDataExample {

    public static void main(String[] args) {
        try {
            // Создаем URL-объект для получения подключения к серверу
            URL url = new URL("http://example.com/upload");
            
            // Создаем HTTPURLConnection объект
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            
            // Устанавливаем метод запроса на POST
            connection.setRequestMethod("POST");
            
            // Включаем флаг для отправки тела запроса
            connection.setDoOutput(true);
            
            // Генерируем уникальный boundary для разделения полей
            String boundary = UUID.randomUUID().toString();
            
            // Устанавливаем значение заголовка Content-Type
            connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
            
            // Создаем поток для записи данных в тело запроса
            OutputStream output = connection.getOutputStream();
            PrintWriter writer = new PrintWriter(new OutputStreamWriter(output, "UTF-8"), true);
            
            // Добавляем поле и его значение к телу запроса
            writer.append("--").append(boundary).append("rn");
            writer.append("Content-Disposition: form-data; name="field1"rnrn");
            writer.append("value1").append("rn").flush();
            
            // Добавляем файл к телу запроса
            File file = new File("path_to_file");
            writer.append("--").append(boundary).append("rn");
            writer.append("Content-Disposition: form-data; name="file"; filename="").append(file.getName()).append(""rn");
            writer.append("Content-Type: ").append(URLConnection.guessContentTypeFromName(file.getName())).append("rnrn");
            writer.flush();
            Files.copy(file.toPath(), output);
            output.flush();
            
            // Завершаем форму форм-data
            writer.append("rn").flush();
            writer.append("--").append(boundary).append("--").append("rn").flush();
            
            // Отправляем запрос и получаем ответ
            int responseCode = connection.getResponseCode();
            
            // Читаем ответ сервера
            BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            String line;
            StringBuilder response = new StringBuilder();
            while ((line = reader.readLine()) != null) {
                response.append(line);
            }
            reader.close();
            
            // Закрываем подключение
            connection.disconnect();
            
            // Выводим информацию о результате выполнения запроса
            System.out.println("Response Code: " + responseCode);
            System.out.println("Response: " + response.toString());
            
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

В этом примере мы создаем HTTPURLConnection объект и устанавливаем его метод запроса на POST. Далее мы включаем флаг для отправки тела запроса (setDoOutput(true)) и устанавливаем заголовок Content-Type в значение multipart/form-data, указывая уникальный boundary для разделения полей.

Затем мы создаем поток вывода и создаем объект PrintWriter для записи данных в тело запроса. Мы добавляем поля и их значения в тело запроса, используя Writer.append() метод.

Мы также добавляем файл к телу запроса, указывая его полный путь и имя файла. Файл копируется в тело запроса с помощью Files.copy() метода.

После добавления всех полей и файлов мы завершаем форму форм-data, добавляя boundary в конец тела запроса.

Затем мы отправляем запрос (connection.getResponseCode()) и читаем ответ сервера (connection.getInputStream()). Ответ сохраняется в StringBuilder и выводится на консоль.

Наконец, мы закрываем поток, отключаемся от сервера и выводим информацию о результате выполнения запроса.

Надеюсь, это подробное объяснение помогло вам! Если у вас возникнут вопросы, не стесняйтесь задавать.