【问题标题】:Spring WebFlux File Upload: Unsupported Media Type 415 with Multipart uploadSpring WebFlux 文件上传:不支持的媒体类型 415 与分段上传
【发布时间】:2019-10-07 18:03:04
【问题描述】:

我在使用 Spring 的响应式框架处理文件上传时遇到了一些问题。我想我正在关注文档,但无法摆脱这个 415 / Unsupported Media Type 问题。

我的控制器如下所示(根据此处的示例:https://docs.spring.io/spring/docs/current/spring-framework-reference/web-reactive.html#webflux-multipart-forms

package com.test.controllers;

import reactor.core.publisher.Flux;

import org.springframework.http.MediaType;
import org.springframework.http.codec.multipart.FilePart;
import org.springframework.http.codec.multipart.Part;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TestController {

    @RequestMapping(value = "/upload", method = RequestMethod.POST, consumes = MediaType.MULTIPART_FORM_DATA_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
    public Flux<String> uploadHandler(@RequestBody Flux<Part> parts) {
        return parts
                .filter(part -> part instanceof FilePart)
                .ofType(FilePart.class)
                .log()
                .flatMap(p -> Flux.just(p.filename()));
    }

}

虽然发布到此端点,但总是给我相同的输出:

curl -X POST -F "data=@basic.ppt" http://localhost:8080/upload
---
"Unsupported Media Type","message":"Content type 'multipart/form-data;boundary=------------------------537139718d79303c;charset=UTF-8' not supported"

我也尝试过使用@RequestPart("data"),但得到了类似的Unsupported Media Type 错误,尽管是文件的内容类型。

似乎 Spring 在将这些转换为 Part.. 时遇到问题?我被困住了 - 感谢任何帮助!

【问题讨论】:

    标签: java spring spring-boot spring-webflux project-reactor


    【解决方案1】:

    嗯,这不是你问题的直接答案,因为我使用功能端点,但我希望它会以某种方式帮助你。

    import org.springframework.context.annotation.Bean;
    import org.springframework.http.codec.multipart.FilePart;
    import org.springframework.http.codec.multipart.Part;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.reactive.function.BodyExtractors;
    import org.springframework.web.reactive.function.server.HandlerFunction;
    import org.springframework.web.reactive.function.server.RouterFunction;
    import org.springframework.web.reactive.function.server.ServerResponse;
    
    import java.io.File;
    import java.util.Map;
    
    import static org.springframework.web.reactive.function.BodyInserters.fromObject;
    import static org.springframework.web.reactive.function.server.RequestPredicates.POST;
    import static org.springframework.web.reactive.function.server.RequestPredicates.path;
    import static org.springframework.web.reactive.function.server.RouterFunctions.nest;
    import static org.springframework.web.reactive.function.server.RouterFunctions.route;
    
    @Controller
    public class FileUploadController {
    
        @Bean
        RouterFunction<ServerResponse> apiRoutes() {
            return nest(path("/api"),
                    route(POST("/upload"), fileUpload()));
        }
    
        private HandlerFunction<ServerResponse> fileUpload() {
            return request -> {
                return request.body(BodyExtractors.toMultipartData()).flatMap(parts -> {
                            Map<String, Part> map = parts.toSingleValueMap();
                            final FilePart filePart = (FilePart) map.get("file");
                            final String dir = "C:\\JDeveloper\\mywork\\Spring\\SpringTest\\webflux-file-upload\\uploaded";
                            filePart.transferTo(new File(dir + "/" + filePart.filename()));
    
                            return ServerResponse.ok().body(fromObject("ok, file uploaded"));
                        }
                );
            };
        }
    
    }
    

    你可以像这样使用 curl 上传文件:

    curl -F "file=@C:\Users\Wojtek\Desktop\img-5081775796112008742.jpg" localhost:8080/api/fileupload
    

    【讨论】:

      【解决方案2】:

      感谢@kojot 的回答,但在这种情况下,我发现问题在于除了spring-webflux 之外,我还暂时包含了spring-webmvc。您的解决方案可能也行得通,但我想坚持使用 Controller 样式,因此最终将spring-webmvc 从我的build.gradle 中强制排除:

      configurations {
          implementation {
              exclude group: 'org.springframework', module: 'spring-webmvc'
          }
      }
      

      之后,它按照记录的方式工作。

      【讨论】:

        猜你喜欢
        • 2021-10-15
        • 2015-07-21
        • 2021-05-26
        • 1970-01-01
        • 2018-10-29
        • 1970-01-01
        • 2018-06-18
        • 2021-05-20
        • 1970-01-01
        相关资源
        最近更新 更多