Я пытаюсь отправить изображение продукта и продукта из внешнего интерфейса Angular 7 в бэкэнд SpringMVC.
Чтобы добавить поддержку файлов Multipart, я добавил этот bean-компонент в свой AppConfig.
@Bean(name = "multipartResolver")
public CommonsMultipartResolver multipartResolver() {
CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
multipartResolver.setMaxUploadSize(1000000);
return multipartResolver;
}
Так как я хочу получить объект Product отдельно внутри контроллера, я использую @RequestPart для извлечения обоих по отдельности, например:
@RequestMapping(value = "save", method = RequestMethod.POST)
public ResponseEntity addProduct(@Valid @RequestPart Product product, @RequestPart MultipartFile[] images, BindingResult bindingResult, HttpServletRequest
}
На веб-интерфейсе я добавляю изображение в FormData следующим образом:
let formData = new FormData();
formData.append('product', new Blob([JSON.stringify(this.product)],{ type: "application/json" }));
// I iterate and append all the images like this
formData.append('image[]', this.images, this.images.name);
this.http.post(this.appService.getApiUrl() + "api/product/save/", product);
Проблема в том, что всякий раз, когда я отправляю форму, я получаю это исключение в качестве ответа: HTTP Status 415 - Неподдерживаемый тип носителя .
Я попытался отладить эту проблему, установив точки останова внутри класса CommonsMultipartResolver и после отслеживания запроса по коду. Я обнаружил, что при вызове getSupportedMediaTypes () он возвращает только два типа мультимедиа:
- применение / JSON
- Применение / * + * 1021 JSON *
Внутри следующего метода в AbstractHttpMessageConverter :
protected boolean canRead(@Nullable MediaType mediaType) {
if (mediaType == null) {
return true;
} else {
Iterator var2 = this.getSupportedMediaTypes().iterator();
MediaType supportedMediaType;
do {
if (!var2.hasNext()) {
return false;
}
supportedMediaType = (MediaType)var2.next();
} while(!supportedMediaType.includes(mediaType));
return true;
}
}
Найдя это, я попытался добавить MediaType.MULTIPART_FORM_DATA
вот так внутри AppConfig:
@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
for (HttpMessageConverter converter : converters) {
if (converter instanceof MappingJackson2HttpMessageConverter) {
List<MediaType> types = new ArrayList<>();
types.add(MediaType.APPLICATION_JSON);
types.add(MediaType.APPLICATION_JSON_UTF8);
types.add(MediaType.MULTIPART_FORM_DATA);
((MappingJackson2HttpMessageConverter) converter).setSupportedMediaTypes(types);
Hibernate5Module hibernate5Module = new Hibernate5Module();
hibernate5Module.disable(Hibernate5Module.Feature.USE_TRANSIENT_ANNOTATION);
ObjectMapper mapper = ((MappingJackson2HttpMessageConverter) converter).getObjectMapper();
mapper.registerModule(hibernate5Module);
}
}
}
Но это все равно не сработает. Когда приложение запускается, я вижу конструктор AbstractJackson2HttpMessageConverter , вызываемый с помощью моих MediaTypes , но после него они перезаписываются большим количеством обращений к одному и тому же конструктору.
Можно ли как-то сохранить MediaType для сохранения? Возможно, я смотрю не в ту сторону, поэтому любое понимание будет полезным.