我正在尝试将Angular 7前端的产品和产品图像发送到SpringMVC后端。为了添加对Multipart文件的支持,我在AppConfig中添加了这个bean。
@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状态415 - 不支持的媒体类型。我尝试通过在CommonsMultipartResolver类中设置断点来调试此问题,并在通过代码跟踪请求后,我发现当调用getSupportedMediaTypes()时,它只返回两种媒体类型:
在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;
}
}
发现这个我尝试在AppConfig中添加这样的MediaType.MULTIPART_FORM_DATA
:
@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继续存在吗?我可能会朝错误的方向看,所以任何见解都会有所帮助。
类路径上需要Jackson库。 Spring默认不声明这一点。确保至少com.fasterxml.jackson.core:jackson-databind
在Spring MVC应用程序的类路径中可用。 Apache Maven的示例:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
jackson.version
值的示例:2.9.0
1)您需要在服务器端提供支持的输入数据。由于您要发送文件,意味着服务器正在使用多部分数据。对于multipart,我们需要设置consumemes =“multipart / form-data”
@RequestMapping(value = "save", method = RequestMethod.POST, consumes = "multipart/form-data")
public ResponseEntity addProduct(@Valid @RequestPart Product product, @RequestPart MultipartFile[] images, BindingResult bindingResult, HttpServletRequest
}
2)由于表单正在发送多部分数据,我们需要在post调用的http头中设置前端的内容类型。 content-type:multipart / form-data“