添加spring-boot-starter-hateoas依赖后文件上传API端点失效
问题:添加Spring HATEOAS依赖后文件上传接口返回415不支持媒体类型
原有文件上传接口代码如下,原本可正常运行:
@PostMapping(value = "/documents", consumes = {MediaType.MULTIPART_FORM_DATA_VALUE}) public Mono<ResponseEntity<String>> uploadDocument(@RequestPart Mono<FilePart> file){ return storeDocumentService .upload(file) .map(fileLocation->ResponseEntity.ok(fileLocation)) }
引入org.springframework.boot:spring-boot-starter-hateoas依赖用于返回HATEOAS风格的上传文件链接后,接口立即失效,返回415错误响应:
{ "timestamp": "2023-02-20T04:28:10.620+00:00", "status": 415, "error": "Unsupported Media Type", "path": "/documents" }
日志提示:
2023-02-20T05:28:10.618+01:00 WARN 2993 --- [nio-8080-exec-4] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.HttpMediaTypeNotSupportedException: Content-Type 'application/pdf' is not supported]
注:上传的是PDF文件,请求头Content-Type为multipart/form-data,唯一变更仅为添加HATEOAS依赖。
原因分析
引入Spring HATEOAS依赖后,其自动配置会调整WebFlux的消息转换器优先级,导致原本用于处理multipart/form-data的MultipartHttpMessageConverter被HATEOAS相关转换器覆盖。请求解析时错误地将PDF文件内容(而非整个multipart请求)当作JSON或其他HATEOAS支持的媒体类型解析,最终抛出415错误。
解决方案
方案1:显式指定请求Part名称
修改接口方法的@RequestPart注解,显式指定part名称,确保与前端上传时的文件字段名一致(通常为file):
@PostMapping(value = "/documents", consumes = {MediaType.MULTIPART_FORM_DATA_VALUE}) public Mono<ResponseEntity<String>> uploadDocument(@RequestPart(name = "file") Mono<FilePart> file){ return storeDocumentService .upload(file) .map(fileLocation->ResponseEntity.ok(fileLocation)) }
方案2:调整WebFlux消息转换器优先级
自定义WebFlux配置,将MultipartHttpMessageConverter移到转换器列表最前面,保证其优先处理multipart请求:
import org.springframework.context.annotation.Configuration; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.multipart.MultipartHttpMessageConverter; import org.springframework.web.reactive.config.WebFluxConfigurer; import java.util.List; @Configuration public class WebFluxConfig implements WebFluxConfigurer { @Override public void configureHttpMessageConverters(List<HttpMessageConverter<?>> converters) { for (int i = 0; i < converters.size(); i++) { if (converters.get(i) instanceof MultipartHttpMessageConverter) { MultipartHttpMessageConverter converter = (MultipartHttpMessageConverter) converters.remove(i); converters.add(0, converter); break; } } } }
方案3:排除HATEOAS自动配置(不推荐,仅适用于无需完整HATEOAS自动配置场景)
在启动类中排除HateoasAutoConfiguration,避免其干扰WebFlux的消息转换器配置:
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.hateoas.HateoasAutoConfiguration; @SpringBootApplication(exclude = HateoasAutoConfiguration.class) public class YourApplication { public static void main(String[] args) { SpringApplication.run(YourApplication.class, args); } }
内容的提问来源于stack exchange,提问作者user1796624
相关产品推荐
相关产品推荐

