当前位置: 首页 > 知识库问答 >
问题:

使用RestTemplate发送多部分文件

常小白
2023-03-14

我有两台服务器,其中服务器A向服务器B发送文件。在服务器B上,我有一个接收给定类别文件的endpoint。这是我需要将文件发送到的endpoint的签名:

@PostMapping("/uploadMultipleFiles/{projectId}")
public List<UploadFileResponseDts> uploadMultipleFiles(@RequestParam("files") MultipartFile[] files, @RequestParam("categoryId") Long categoryId, @PathVariable("projectId") Long projectId) {
    return uploadMulitpleFiles(files, categoryId, projectId);
}

现在我在用RESTTemplateExchange创建这样的请求时遇到了麻烦。在服务器A上,我试图逐个发送文件(服务器B上的endpoint需要接受多部分数组,因为它也在其他地方使用)。这就是我所尝试的:

public Optional<String> uploadFile(File file, Long projectId) throws Exception {

    String authToken = getAccessToken();
    String projectFileUploadEndpoint = fileUploadEndpoint + SEPARATOR + projectId;

    FileInputStream input = new FileInputStream(file);
    byte[] bytes = IOUtils.toByteArray(input);

    MultiValueMap<String, Object> parts =
            new LinkedMultiValueMap<>();
            parts.add("files", new ByteArrayResource(bytes));
    parts.add("categoryId", 0L);

    RestTemplate restTemplate = new RestTemplate();
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.MULTIPART_FORM_DATA);
    headers.set("Authorization", authToken);

    HttpEntity<MultiValueMap<String, Object>> requestEntity =
            new HttpEntity<>(parts, headers);

    ResponseEntity<String> response =
            restTemplate.exchange(projectFileUploadEndpoint ,
                    HttpMethod.POST, requestEntity, String.class);

    return Optional.empty();
}

这几乎工作,唯一的问题是,在服务器B文件@recestParam(文件)MultipartFile[]文件总是空。我假设问题是我在服务器A上组装部件的方式,但是我找不到我的错误。你能指出来吗?

共有1个答案

潘泰
2023-03-14

在您的控制器中一切都很好,问题在于您的客户端代码。

基本上,您应该使用FileSystemResources对象而不是ByteArrayResources。基本动机是关于文件元数据。使用FileSystemResourcesSpring能够重建所需的MultipartFile信息,因此您的代码可能如下所示

  @Test
  public void contextLoads()
  {
    File file = new File("test.txt");
    FileSystemResource fileSystemResource = new FileSystemResource(file);

    MultiValueMap<String, Object> parts = new LinkedMultiValueMap<>();
    parts.add("categoryId", 0L);
    parts.add("files", fileSystemResource);

    String serviceUrl = "http://localhost:8080/uploadMultipleFiles/0";

    RequestEntity<MultiValueMap<String, Object>> requestEntity = post(fromPath(serviceUrl).build().toUri())
      .contentType(MediaType.MULTIPART_FORM_DATA)
      .body(parts);

    RestTemplate restTemplate = new RestTemplate();

    restTemplate.setErrorHandler(new ResponseErrorHandler()
    {
      @Override
      public boolean hasError(ClientHttpResponse response) throws IOException
      {
        return false;
      }

      @Override
      public void handleError(ClientHttpResponse response) throws IOException
      {
        System.out.println(response);
      }
    });
    ResponseEntity<String> response = restTemplate.exchange(serviceUrl, HttpMethod.POST, requestEntity, String.class);

    assertThat(200, Is.is(response.getStatusCode()));

  }

我希望这个测试用例能够帮助您解决这个问题

 类似资料:
  • 我正在尝试用RestTemplate上传一个文件到带有Jetty的Raspberry Pi。在Pi上有一个运行的servlet: 这是我得到的输出: UI-elements.html已上传! org.springframework.web.multipart.support.StandardMultipartTtpServletRequest$StandardMultipartFile@47e76

  • 我想通过调用rest web服务上传文件。此web服务需要MultipartFile。 我在这里读到我可以做到这一点:使用Spring Rest模板Spring Web MVC上传多部分文件 这是我的代码: 杰克逊尝试以JSON形式序列化该文件,但它失败了,并出现以下错误: 如何禁用文件的json序列化?

  • 问题内容: 我可以将文件作为多部分发送到servlet吗?我正在制作表单并将其作为多部分提交,但是以某种方式我没有收到成功上传它的回复。我不希望刷新页面,因此它必须由ajax进行。 问题答案: 只有使用XHR API(以前称为“ XHR2”或“ XHR Level 2”的一部分,当前称为“ XHR高级功能”)才有可能。 有了这个HTML, 您可以按以下方式上传: XHR将注意适当的头和请求主体编码

  • 大家好,在我的microservice和spring boot应用程序中,我有一个前端员工microservice,它使用另一个带有文件上传endpoint的microservice。调用服务基于spring rest控制器,我正在尝试在Spring Boot应用程序中使用RestTemplate使用文件上载endpoint。简而言之,尝试上载PDF文件。 我已经探索了以下SO帖子,但它对我不起作

  • 我将调用一个POST REST API,它在其主体中接受一个文件。 如果我发送几个KB的文件(使用下面的代码),大约需要300毫秒。如果我发送大约5 GB的文件,它会抛出内存异常。 是否有一种可能的方法可以按顺序将文件作为块发送?目前,我们正在避免任何并行处理。 非常感谢您在代码或参考方面的任何帮助。

  • 有一个只接受内容类型multipart/mixed的REST API。 正在尝试使用restTemplate并生成内容类型为multipart/mixed的REST请求。如果注释setContentType restTemplate默认为多部分/表单数据。 但运气不好,举个例子,我如何调用API生成多部分/混合请求? 也许这个有帮助