【问题标题】:How to upload octet-stream file to spring-mvc application?如何将八位字节流文件上传到 spring-mvc 应用程序?
【发布时间】:2019-05-13 12:53:24
【问题描述】:

通常对于文件上传,我使用了 multipart/form-data 并且效果很好。但是现在我的服务器需要能够接受文件 application/octet-stream。

在服务器端我有:

@ResponseBody
@RequestMapping(path = "/mock",
        consumes = { MediaType.APPLICATION_OCTET_STREAM_VALUE },
        method = RequestMethod.POST)
public ResponseEntity handleFileUpload(@RequestParam("file") MultipartFile file) {
    return ResponseEntity.accepted().build();
}

我正在尝试用 curl 测试它:

curl -v -H "Content-Type:application/octet-stream" \
  --data-binary @/home/user/Desktop/test.txt http://localhost:9090/mock

结果一个有:

org.springframework.web.multipart.MultipartException: Current request is not a multipart request

我注意到“文件”部分没有在我的 curl 命令中指定,但在服务器端是预期的。目前尚不清楚下一步该移到哪里以及什么是损坏的测试命令或服务器或两者兼而有之。

【问题讨论】:

    标签: spring-mvc curl file-upload multipart


    【解决方案1】:

    由于您没有多部分表单数据消息,因此您不能使用MultipartFile

    你现在有两种可能。

    使用 curl 发送多部分消息:
    (查看名为file 的表单数据。)

    curl -F "file=@/home/user/Desktop/test.txt" http://localhost:9090/mock
    

    或者换个控制器:

    @ResponseBody
    @RequestMapping(path = "/mock",
            consumes = { MediaType.APPLICATION_OCTET_STREAM_VALUE },
            method = RequestMethod.POST)
    public ResponseEntity handleFileUpload(final HttpServletRequest request) {
        // request.getInputStream() will contain the content of the posted file
        return ResponseEntity.accepted().build();
    }
    

    【讨论】:

    • 不要手动设置多部分标题,您可能会搞砸边界.. 只需让 curl 自动为您设置该标题,它与 -F 一起使用,您的 curl 命令也会可能以text/plain 发送文件,但此服务器似乎需要application/octet-stream,以强制curl 将其作为八位字节流发送,请执行-F "file=@/home/user/Desktop/test.txt;type=application/octet-stream"
    • 我已经改过了。
    • 您仍在手动设置 multipart-header,您不应该这样做(因为您不知道边界是什么,并且您不提供边界 - 您应该让 curl为你做这一切)
    • 我也改了。
    【解决方案2】:

    要以multipart/form-data 格式上传文件,请使用-F--form

    curl -F "file=@/home/user/Desktop/test.txt" http://localhost:9090/mock
    

    但这可能会将文件发送为Content-Type: text/plain,而不是Content-Type: application/octet-stream,正如我们在netcat服务器中看到的那样:

    $ nc -l 9090
    POST /mock HTTP/1.1
    Host: 127.0.0.1:9090
    User-Agent: curl/7.66.0
    Accept: */*
    Content-Length: 190
    Content-Type: multipart/form-data; boundary=------------------------465160a3b9f7de24
    
    --------------------------465160a3b9f7de24
    Content-Disposition: form-data; name="file"; filename="test.txt"
    Content-Type: text/plain
    
    lol
    
    --------------------------465160a3b9f7de24--
    

    为了强制 curl 将其发送为 application/octet-stream ,请执行 -F "file=@/home/user/Desktop/test.txt;type=application/octet-stream"

    这给了我们:

    $ nc -l 9090
    POST /mock HTTP/1.1
    Host: 127.0.0.1:9090
    User-Agent: curl/7.66.0
    Accept: */*
    Content-Length: 204
    Content-Type: multipart/form-data; boundary=------------------------444e61e5527966d1
    
    --------------------------444e61e5527966d1
    Content-Disposition: form-data; name="file"; filename="test.txt"
    Content-Type: application/octet-stream
    
    lol
    
    --------------------------444e61e5527966d1--
    

    【讨论】:

      猜你喜欢
      • 2022-10-11
      • 2012-08-14
      • 2012-11-17
      • 1970-01-01
      • 2016-11-17
      • 2019-08-24
      • 2023-03-10
      • 2015-01-27
      • 2018-09-26
      相关资源
      最近更新 更多