Как отправить на сервер JSON и файл изображения? - PullRequest
0 голосов
/ 16 июня 2020

Я пытаюсь отправить файл JSON и файл изображения вместе на сервер, но мне очень трудно.

1) Если я отправляю только элемент quilt, пропуская formData и Часть $ http ниже на $ http.post ('quilts / create /', quilt), затем установите конечную точку сервера на ожидание (@RequestBody QuiltRequest quiltRequest) без битов о transformRequest и заголовках, он обрабатывает данные в них довольно успешно, но У меня нет изображения для добавления в записи.

2) Если я не добавлю элемент quilt в formData и скажу серверу ожидать (@RequestParam ("image") MultipartFile image ), Я могу сохранить файл изображения на своем сервере и сгенерировать для него строку URL-адреса, но у меня нет другой информации о лоскутном одеяле, чтобы сделать соответствующую запись в базе данных. запрос, и сервер получит и обработает оба?

Большое спасибо!

Клиентская служба:

this.create = function (quilt, image) {
        quilt.size = JSON.parse(quilt.size);
        quilt.maker = JSON.parse(quilt.maker);
        const formData = new FormData();
        formData.append('quiltRequest', quilt);
        formData.append('image', image);
        $http.post('quilts/create/', formData, {
            transformRequest: angular.identity,
            headers: {'Content-Type': undefined}
        }).then(function (response) {
            return window.location = '#!/quilts/created/' + response.data;
        })
    };

Конечная точка на стороне сервера:

    @PostMapping(path = "/create")
    public BigInteger create(@RequestPart QuiltRequest quiltRequest, @RequestPart MultipartFile image) throws IOException {
        // do stuff based on parameters received
    }

Ответы [ 2 ]

0 голосов
/ 17 июня 2020

Мое необходимое решение было дано реальным героем и размещено здесь на тот случай, если кто-то еще с подобной проблемой наткнется на эту ветку :) (Но спасибо пользователю 3562932 за то, что он нашел время, чтобы прочитать и внести предложение) .

На стороне клиента мы переместили пять строк подготовки данных в отдельный метод, так что исходный create () теперь принимает кучу параметров и переходит прямо к $ http.post (url, данные, которые были волшебным образом преобразованы во что-то подходящее для отправки {правила отправки данных}).

        $http.post('quilts/create/', formData(quilt, image), {
            transformRequest: angular.identity,
            headers: {'Content-Type': undefined}
        }).then(function (response) {
            return window.location = '#!/quilts/created/' + response.data;
        })

Магическое преобразование происходит в новой функции formData (), которая принимает в качестве параметров данные, которые мы хотим отправить, и вносит необходимые изменения:
1) создает контейнер formData для данных, которые будут отправлены на POST.
2) преобразовать информацию из формы html в строку (например, текст, числа) в JSON и добавить к formData.
2a) в этом конкретном случае моя структура лоскутного одеяла содержит сведения о размере и изготовителе, которые получены из бэкэнда как JSON и были выбраны на веб-странице из раскрывающихся списков различных размеров и производителей, следовательно, строки синтаксического анализа, чтобы подготовить эти элементы для включения в formData.
3) конвертировать файлы в BLOB, а затем аналогичным образом добавьте.
4) return formData со всей необходимой информацией, аккуратно упакованной и готовой к go!
Примечание: в файле services. js этот метод formData () фактически появляется над create (), но более логично говорить о них таким образом.

function formData(quilt, image) {
        let formData = new FormData();
        quilt.size = JSON.parse(quilt.size);
        quilt.maker = JSON.parse(quilt.maker);
        formData.append('quiltRequest', JSON.stringify(quilt));
        formData.append('image', new Blob([image]));
        return formData;
    }

На стороне сервера мы теперь можем с радостью получить это через:

    @PostMapping(path = "/create", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public BigInteger create(@RequestParam(value = "quiltRequest") String quiltRequest,
                             @RequestParam(value = "image") MultipartFile image) throws IOException {
        QuiltRequest quilt = new ObjectMapper().readValue(quiltRequest, QuiltRequest.class);
        QuiltResponse quiltResponse = quiltService.create(quilt, image);
        return quiltResponse.getQuilt().getId();
    }

In чтобы позволить конечной точке использовать наш захватывающий мультимедийный ввод, мы должны добавить следующий импорт в верхней части класса:

import org.springframework.http.MediaType;

Мы используем другой импорт, чтобы разрешить использование класса MultipartFile, который мы назначили для входящего файла изображения:

import org.springframework.web.multipart.MultipartFile;

Объект JSON с веб-страницы прошел как строку, но это должно быть разобран на его базовые компоненты, чтобы действительно можно было использовать. Здесь в игру вступает ObjectMapper. Вызовите его метод readValue () и передайте строковый аргумент плюс шаблон того, как информация должна выглядеть после распаковки (здесь класс QuiltRequest с определенными свойствами, соответствующими информации, которую мы передали в JSON обратно в клиенте. -конечный сервер). Не забудьте включить необходимый импорт для доступа к ObjectMapper:

import com.fasterxml.jackson.databind.ObjectMapper;

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

0 голосов
/ 16 июня 2020

Помимо этого, я думаю, вы можете попробовать закодировать изображение в строку base64. Отправьте его на сервер и на сервере, вы его декодируете

...