Обработка Multipart Request с пустым полем на backend java Spring

Рейтинг: 0Ответов: 1Опубликовано: 17.04.2023

Есть контроллер и эндпойнт обрабатывающие POST-запрос, в котором приходит XML-файл и др. параметры:

@RestController
@ResponseBody
@RequestMapping("/label-integrity")
@RequiredArgsConstructor
public class LabelIntegrityController {

    private final IntegrityLabelService integrityLabelService;

    @PostMapping(value = "/verify-double", consumes = { MediaType.MULTIPART_FORM_DATA_VALUE})
    @Secured("ROLE_rPageMain")
    public LabelResultTypeDto getVerifyDoubleLabelIntegrity(@RequestParam("file") MultipartFile file, SuvLogFilterDto suvLogFilterDto) {
        return this.integrityLabelService.verifyDoubleLabelIntegrity(suvLogFilterDto, file);
    }
}

С фронта запрос отправляется следующим образом:

public getVerifyDoubleLabelIntegrity(id: string, messageGuid: string, eventCode: Array<string>, typeMessage: string, destination: string, file?: FormData) {
    const url = `${this._url}/verify-double`;

    return this.http
      .post<VerifyLabelIntegrityResponseModel>(url, file, { params: { id, messageGuid, eventCode, typeMessage, destination } })
      .pipe(
        tap(_ => this.logger.debug(`post VerifyDoubleLabelIntegrity`)),
        take(1),
        share()
      );
  }

Объект "file" может быть заполнен - XML-файл, а может быть undefined.

Когда объект "file" заполнен, то всё нормально, но когда он не заполнен (данный кейс необходим), то возникает ошибка:

org.springframework.web.HttpMediaTypeNotSupportedException: Content type '' not supported

Пробовал создавать пустой объект и отправлять его на бэк:

if (file === null || file === undefined) {
      file = new FormData();
    }

Но это вызывает другую ошибку:

org.springframework.web.multipart.support.MissingServletRequestPartException: Required request part 'file' is not present

Пробовал в описание эндпойнта добавить MediaType.ALL_VALUE:

@PostMapping(value = "/verify-double", consumes = { MediaType.MULTIPART_FORM_DATA_VALUE, MediaType.ALL_VALUE})

Но это тоже вызвало уже другую ошибку.

Пробовал в аннотации параметра прописать requared = false, но это вызвало ту же ошибку:

@PostMapping(value = "/verify-double", consumes = { MediaType.MULTIPART_FORM_DATA_VALUE})
    @Secured("ROLE_rPageMain")
    public LabelResultTypeDto getVerifyDoubleLabelIntegrity(@RequestParam(value = "file", required = false) MultipartFile file, SuvLogFilterDto suvLogFilterDto) {
        ...
    }

org.springframework.web.HttpMediaTypeNotSupportedException: Content type '' not supported at org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping.handleNoMatch(RequestMappingInfoHandlerMapping.java:227) at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.lookupHandlerMethod(AbstractHandlerMethodMapping.java:422)

Оф. доках нашёл пример различных вариантов использования и даже unit-тестирования Multipart Request Multipart Request Handling in Spring, но варианта с пустым form-data нет.

Как можно прописать контроллер, что бы он мог обрабатывать запросы с пустым объектом @RequestParam("file") MultipartFile file?

Как вариант решения:

  • на фронте создать пустую форму:

    if (file === null || file === undefined) { file = new FormData(); }

  • на бэке @RequestPart в место @RequestParam && required = false

    @PostMapping(value = "/verify-double", consumes = { MediaType.MULTIPART_FORM_DATA_VALUE}) @Secured("ROLE_rPageMain") public LabelResultTypeDto getVerifyDoubleLabelIntegrity(@RequestPart(value = "file", required = false) MultipartFile file, SuvLogFilterDto suvLogFilterDto) { ... }

Ответы

▲ 0

Замени @RequestParam на @RequestPart И там уже можно будет использовать (required = false) Вот пример: public LabelResultTypeDto getVerifyDoubleLabelIntegrity(@RequestPart(required = false) MultipartFile file, SuvLogFilterDto suvLogFilterDto)