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

使用RestTemplate的Spring Boot多部分内容类型HTTP请求

壤驷华辉
2023-03-14

我试图在Spring Boot中使用RestTemplate来模拟这个请求

curl -X POST 
'https://my.craftar.net/api/v0/image/?api_key=123456789abcdefghijk123456789abcdefghijk' 
-F "item=/api/v0/item/4fe672886ec142f6ab6d72d54acf046f/" 
-F "file=@back_cover.png"

这是我的代码:

MultiValueMap<String, Object> params= new LinkedMultiValueMap<>();
params.add("item", "/api/v0/item/4fe672886ec142f6ab6d72d54acf046f/");

final String filename=file.getOriginalFilename();
Resource contentsAsResource = new ByteArrayResource(file.getBytes()){
                      @Override
                      public String getFilename(){
                        return filename;
                      }
};

HttpHeaders imageHeaders = new HttpHeaders();
imageHeaders.setContentType(MediaType.IMAGE_PNG);
HttpEntity<Resource> imageEntity = new HttpEntity<Resource>(contentsAsResource, imageHeaders);
params.add("file", imageEntity);

HttpHeaders headers = new HttpHeaders();
headers.setAccept(Collections.singletonList(MediaType.ALL));
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
HttpEntity<MultiValueMap<String,Object>> requestEntity =new HttpEntity<>(params,headers);

try {
    ResponseEntity<String> responseEntity = restTemplate.exchange(url,HttpMethod.POST, requestEntity, String.class);
    return responseEntity.getBody();
  } catch (final HttpClientErrorException httpClientErrorException) {
      return httpClientErrorException.getResponseBodyAsString();
  } catch (Exception exception) {
      return exception.getMessage();
  }

上面的请求抛出一个HttpClientErrorException,这就是响应体的样子

{“错误”:{“消息”:“需要多部分/表单数据;边界=<..>内容,但获得多部分/表单数据;边界=X6G0xWVXDZX4N8PYNU8IHGANGG4TWJ3DGMaryDS。”,“代码”:“错误内容类型”}}

我也尝试过使用FileSystemResource,但它抛出了相同的异常。问题可能出在多部分内容类型的数据格式上。

如果可以帮助的话,这是Postman使用OKHTTP在一个成功的请求上生成的代码模板。

OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW");

RequestBody body = RequestBody.create(mediaType, 
"------WebKitFormBoundary7MA4YWxkTrZu0gW\r\n
Content-Disposition: form-data; name=\"item\"\r\n\r\n/api/v0/item/3d8dcdd1daa54bcfafd8d1c6a58249b5/\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW\r\n
Content-Disposition: form-data; name=\"file\"; filename=\"times_logo.png\"\r\nContent-Type: image/png\r\n\r\n\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW--");

Request request = new Request.Builder()
.url("https://my.craftar.net/api/v0/image/?api_key=c6d4750c7368806fab27294fba8d0f93d48e1e11")
.post(body)
.addHeader("content-type", "multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW")
.addHeader("cache-control", "no-cache")
.addHeader("Postman-Token", "cf09a989-338e-4d68-8968-b30a43384e5f")
.build();

Response response = client.newCall(request).execute();

共有1个答案

田信然
2023-03-14

只需将资源添加到params,而不是创建HttpEntity

params.add("file", contentsAsResource);
 类似资料:
  • 我正在尝试通过API发送post请求。呼叫要求: 我已经使用Charles HTTP代理查看需要发送哪些头/内容。 我的请求:(基本上抄录自查尔斯的多部分章节) 如有任何帮助,我们将不胜感激!干杯!

  • 我正在使用Spring Integration接收一个HTTP请求,它在多部分请求中嵌套了多部分内容,如下所示。当使用CommonsMultipartResolver作为解析器时,传递给接收服务激活器的LinkedMultiValueMap包含所有部件的映射,但嵌入的MultiParter是包含全部内容的UploadedMultipartFile。在示例边界2中--extkdvsqgextqi2w

  • 我的HTTP放调用响应由以下代码打印。 我想打印要在console或其他格式上打印的内容类型信息。基本上我希望看到c#中的内容类型。我该怎么做?

  • 如果REST API Web请求中的标头使用逗号格式(如RFC 1867中所示): 或者使用分号,如RFC 1049和RFC 2045:

  • 我们目前正在Android中使用okhttp3和Reformation2来使用多部分/表单数据进行POST类型的网络api调用,api请求和响应如下所示 如果您观察到,请求标题Content-Type具有 下面是代码 我在发送定制的请求头内容类型时遇到了一个问题,它是“”基本上我需要更新内容类型头以适应“”为此我尝试了以下代码 这导致添加""到Content-Type,但这导致删除或不添加现有属性

  • 问题内容: 我有一个用go语言编写的网络服务器,并且正在提供来自不同来源(本地,其他服务器,S3)的一些音频文件。我想为此文件提供部分内容,以便HTML音频标签能够搜索和循环。 我该如何实现?我知道包功能可以做到这一点,但是我如何通过自己提供文件来实现呢?我需要在没有此操作的情况下执行此操作,以便可以使用相同的处理程序处理来自不同来源的文件。 问题答案: 提供部分内容并非易事。有关介绍,请参见Wi