如何修复未使用Jackson Spring MVC设置的多部分/表单数据媒体类型



我正在尝试将产品和产品图像从Angular 7前端发送到SpringMVC后端。 为了添加对多部分文件的支持,我在我的应用程序配置中添加了这个 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()时,它只返回两种媒体类型:

  1. 应用程序/JSON
  2. 应用程序/*+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;
}
}

找到这个,我尝试在 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的构造函数被我的MediaType调用,但它们被更多对同一构造函数的调用覆盖。 有什么方法可以让媒体类型持久化吗?我可能看错了方向,所以任何见解都会有所帮助。

类路径上需要杰克逊库。Spring 默认情况下不会声明这一点。确保在 Spring MVC 应用程序的类路径中至少有com.fasterxml.jackson.core:jackson-databind可用。Apache Maven的例子:

<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version> 
</dependency>

jackson.version值的示例:2.9.0

1)您需要提供服务器端支持的输入数据。由于您正在发送文件,这意味着服务器正在使用多部分数据。 对于多部分,我们需要设置消耗 = "多部分/表单数据">

@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标头中在前端设置内容类型。内容类型:多部分/表单数据">

相关内容

  • 没有找到相关文章

最新更新