如何修复未使用Jackson Spring MVC设置的multipart / form-data MediaType

问题描述 投票:0回答:2

我正在尝试将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()时,它只返回两种媒体类型:

  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的构造函数是用我的MediaTypes调用的,但是它们会被更多对同一构造函数的调用覆盖。有什么办法可以让MediaType继续存在吗?我可能会朝错误的方向看,所以任何见解都会有所帮助。

spring spring-mvc jackson jackson2 fasterxml
2个回答
0
投票

类路径上需要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


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“

© www.soinside.com 2019 - 2024. All rights reserved.