Данные и файл формы загрузки загрузки Spring

Я делаю приложение REST для весенней загрузки. Я пытаюсь создать контроллер загрузки многокомпонентной формы, который будет обрабатывать данные формы и загрузку файла вместе. Это мой код контроллера на данный момент:

    @RequestMapping(value = "", method = RequestMethod.POST, headers = "Content-Type=multipart/form-data")
    @PreAuthorize("hasRole('ROLE_MODERATOR')")
    @ResponseStatus(HttpStatus.CREATED)
    public void createNewObjectWithImage(
            /*@RequestParam(value = "file", required=true) MultipartFile file,
            @RequestParam(value = "param_name_1", required=true) final String param_name_1,
            @RequestParam(value = "param_name_2", required=true) final String param_name_2,
            @RequestParam(value = "param_name_3", required=true) final String param_name_3,
            @RequestParam(value = "param_name_4", required=true) final String param_name_4,
            @RequestParam(value = "param_name_5", required=true) final String param_name_5*/
            @ModelAttribute ModelDTO model,
            BindingResult result) throws MyRestPreconditionsException {

        //ModelDTO model = new ModelDTO(param_name_1, param_name_2, param_name_3, param_name_4, param_name_5);

        modelValidator.validate(model, result);
        if (result.hasErrors()){
            MyRestPreconditionsException ex = new MyRestPreconditionsException(
                    "Model creation error",
                    "Some of the elements in the request are missing or invalid");
            ex.getErrors().addAll(
                    result.getFieldErrors().stream().map(f -> f.getField()+" - "+f.getDefaultMessage()).collect(Collectors.toList()));
            throw ex;
        }
// at the moment, model has a MultipartFile property
        //model.setImage(file);
        modelServiceImpl.addNew(model);
    }

Я пробовал как с аннотацией @ModelAttribute, так и с параметрами отправки запроса, но оба эти метода не дали результата.

Это запрос, который я отправляю:

---------------------------acebdf13572468
Content-Disposition: form-data; name = "file"; filename = "mint.jpg"
Content-Type: image/jpeg

<@INCLUDE *C:\Users\Lazaruss\Desktop\mint.jpg*@>
---------------------------acebdf13572468
Content-Disposition: form-data; name=”param_name_1”

string_value_1
---------------------------acebdf13572468
Content-Disposition: form-data; name=”param_name_2”

string_value_2
---------------------------acebdf13572468
Content-Disposition: form-data; name=”param_name_3”

string_value_3
---------------------------acebdf13572468
Content-Disposition: form-data; name=”param_name_4”

string_value_4
---------------------------acebdf13572468
Content-Disposition: form-data; name=”param_name_5”

string_value_5
---------------------------acebdf13572468--

Мое приложение не имеет состояния и использует весеннюю безопасность с полномочиями. В свой пакет безопасности я включил класс AbstractSecurityWebApplicationInitializer

public class SecurityApplicationInitializer extends AbstractSecurityWebApplicationInitializer {

    @Override
    protected void beforeSpringSecurityFilterChain(ServletContext servletContext) {
            insertFilters(servletContext, new MultipartFilter());
        }
    }

Я также использую StandardServletMultipartResolver в своем классе @Configuration

И в свой WebInitializer я добавляю этот код:

MultipartConfigElement multipartConfigElement = new MultipartConfigElement("/tmp", 
                3 * 1024 * 1024, 6 * 1024 * 1024, 1 * 512 * 1024);        
apiSR.setMultipartConfig(multipartConfigElement);

Когда я пытаюсь использовать контроллер с закомментированным кодом (аннотации @RequestParams), я получаю ошибку 404 not found. И когда я пытаюсь использовать контроллер с аннотацией @ModuleAttribute, объект модели пуст.

Какой у вас внешний клиент? Как отправить запрос.

Moler 21.08.2018 08:02

Я использую скрипач

Lazaruss 21.08.2018 19:04
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
6
2
28 378
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

У меня была аналогичная проблема. Если вы хотите отправить Object + Multipart. Вы должны (или, по крайней мере, я не знаю другого решения) сделать свой контроллер таким:

public void createNewObjectWithImage(@RequestParam("model") String model, @RequestParam(value = "file", required = false) MultipartFile file)

А затем: Преобразуйте строку в свой объект, используя:

ObjectMapper mapper = new ObjectMapper();
ModelDTO modelDTO = mapper.readValue(model, ModelDTO.class);

А в Почтальоне его можно отправить так:

Можете ли вы тогда отметить это как правильный ответ? :) @Lazaruss

Moler 23.08.2018 08:08

Решил мою проблему

Ullas Sharma 23.01.2019 19:28

@CrazySabbath Это совсем не хакерство, о чем ты вообще говоришь?

prettyvoid 19.05.2019 13:06

@prettyvoid прошло много времени с тех пор, как я написал этот комментарий, но я думаю, что причина в том, что нужно десериализовать объект самостоятельно. В целом вы правы, это не хакерство. Мне просто не совсем понравился ответ, думаю, мне следовало подобрать слова по-другому.

CrazySabbath 20.05.2019 15:13

что делать, если у вас есть более одного файла для загрузки с помощью одной и той же формы, как это сделать?

leeCoder 15.04.2020 00:40

@leeCoder Я не тестировал его, но постараюсь ожидать, что в вашем методе будут файлы List <Multipart>, я думаю, он должен работать.

Jose Henrique Felipetto 26.05.2020 02:04

Кажется, этот подход работает, но я не могу применять к нему настраиваемые валидаторы ограничений.

Jean Willian S. J. 08.07.2020 15:10

может получать объекты и файлы

@PostMapping(value = "/v1/catalog/create", consumes = MediaType.MULTIPART_FORM_DATA_VALUE )
public void createNewObjectWithImage(
         @RequestPart ModelTO modelTO,
         @RequestPart MultipartFile image)

МодельТО

public class ModelTO {

    private String name;


    public ModelTO() {
        super();
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}

и пример завитка:

curl -X POST "https://your-url.com/v1/catalog/create" -H  "accept: application/json;charset=UTF-8" -H  "Content-Type: multipart/form-data" -F "image=@/pathtoimage/powerRager.jpg;type=image/jpeg" -F "modelTO = {\"name\":\"White\"};type=application/json;charset=utf-8"

Почтальон и другое программное обеспечение не поддерживает отправку типа приложения / json для параметров формы.

Почтальон поддерживает отправку типа контента. Просто нажмите ... и проверьте тип содержимого.

Marouane Gazanayi 20.11.2019 12:36

Другие вопросы по теме