使用 RestTemplate 发送二进制文件,cURL 的 --data-binary 方式
Sending a binary file with RestTemplate, the cURL's --data-binary way
我正在尝试在 Spring 中实现与以下 cURL 命令等效的命令,以调用 API (Twilio) 来上传媒体:
curl --header 'Authorization: Basic <VALID_BASIC_AUTH_TOKEN>' --data-binary "@test.png" https://mcs.us1.twilio.com/v1/Services/<ACCOUNT_ID>/Media -v
此请求完美运行,生成的 headers 为:
> Accept: */*
> Authorization: Basic <VALID_BASIC_AUTH_TOKEN>
> Content-Length: 385884
> Content-Type: application/x-www-form-urlencoded
我在 java 中的代码是:
@Repository
public class TwilioMediaRepository {
private RestTemplate client;
@Value("${twilio.chat.sid}")
private String chatSid;
@Value("${twilio.media.api.endpoint}")
private String endpoint;
@Value("${twilio.all.accountsid}")
private String accountSid;
@Value("${twilio.all.authtoken}")
private String accountSecret;
@Autowired
public TwilioMediaRepository(RestTemplate client) {
this.client = client;
}
public Media postMedia(byte[] file) {
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Arrays.asList(MediaType.ALL));
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
client.getInterceptors().add(new RequestResponseLoggingInterceptor());
client.getInterceptors().add(new BasicAuthorizationInterceptor(accountSid, accountSecret));
HttpEntity<byte[]> entity = new HttpEntity<>(file, headers);
ResponseEntity<Media> media = this.client.postForEntity(generateUrl(), entity, Media.class);
return media.getBody();
}
private String generateUrl() {
return String.format(endpoint, chatSid);
}
}
请求日志显示 headers 与 cURL 请求完全相同:
URI : https://mcs.us1.twilio.com/v1/Services/<ACCOUNT_ID>/Media
Method : POST
Headers : {Accept=[*/*], Content-Type=[application/x-www-form-urlencoded], Content-Length=[385884], Authorization=[Basic <VALID_BASIC_AUTH_TOKEN>]}
Request body: <bunch of unreadable bytes>
但是响应日志显示我的请求对 Twilio 无效:
Status code : 400
Status text : Bad Request
Headers : {Content-Type=[text/html], Date=[Wed, 08 Aug 2018 15:32:50 GMT], Server=[nginx], X-Shenanigans=[none], Content-Length=[166], Connection=[keep-alive]}
Response body: <html>
<head><title>400 Bad Request</title></head>
<body bgcolor="white">
<center><h1>400 Bad Request</h1></center>
<hr><center>nginx</center>
</body>
</html>
我们应该如何发送二进制文件以符合 Spring 中 cURL 的 --data-binary
属性?
我尝试发送 HttpEntity<ByteArrayResource>
、HttpEntity<byte[]>
、HttpEntity<FileSystemResource>
、HttpEntity<ClassPathResource>
但没有成功。
注意:此 API 不支持分段文件上传。
问题已解决。与 cURL 日志显示的相反,我使用的 API 不需要 application/x-www-form-urlencoded
内容类型。
使用文件内容类型解决问题(在我的例子中 image/png
)
我正在尝试在 Spring 中实现与以下 cURL 命令等效的命令,以调用 API (Twilio) 来上传媒体:
curl --header 'Authorization: Basic <VALID_BASIC_AUTH_TOKEN>' --data-binary "@test.png" https://mcs.us1.twilio.com/v1/Services/<ACCOUNT_ID>/Media -v
此请求完美运行,生成的 headers 为:
> Accept: */*
> Authorization: Basic <VALID_BASIC_AUTH_TOKEN>
> Content-Length: 385884
> Content-Type: application/x-www-form-urlencoded
我在 java 中的代码是:
@Repository
public class TwilioMediaRepository {
private RestTemplate client;
@Value("${twilio.chat.sid}")
private String chatSid;
@Value("${twilio.media.api.endpoint}")
private String endpoint;
@Value("${twilio.all.accountsid}")
private String accountSid;
@Value("${twilio.all.authtoken}")
private String accountSecret;
@Autowired
public TwilioMediaRepository(RestTemplate client) {
this.client = client;
}
public Media postMedia(byte[] file) {
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Arrays.asList(MediaType.ALL));
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
client.getInterceptors().add(new RequestResponseLoggingInterceptor());
client.getInterceptors().add(new BasicAuthorizationInterceptor(accountSid, accountSecret));
HttpEntity<byte[]> entity = new HttpEntity<>(file, headers);
ResponseEntity<Media> media = this.client.postForEntity(generateUrl(), entity, Media.class);
return media.getBody();
}
private String generateUrl() {
return String.format(endpoint, chatSid);
}
}
请求日志显示 headers 与 cURL 请求完全相同:
URI : https://mcs.us1.twilio.com/v1/Services/<ACCOUNT_ID>/Media
Method : POST
Headers : {Accept=[*/*], Content-Type=[application/x-www-form-urlencoded], Content-Length=[385884], Authorization=[Basic <VALID_BASIC_AUTH_TOKEN>]}
Request body: <bunch of unreadable bytes>
但是响应日志显示我的请求对 Twilio 无效:
Status code : 400
Status text : Bad Request
Headers : {Content-Type=[text/html], Date=[Wed, 08 Aug 2018 15:32:50 GMT], Server=[nginx], X-Shenanigans=[none], Content-Length=[166], Connection=[keep-alive]}
Response body: <html>
<head><title>400 Bad Request</title></head>
<body bgcolor="white">
<center><h1>400 Bad Request</h1></center>
<hr><center>nginx</center>
</body>
</html>
我们应该如何发送二进制文件以符合 Spring 中 cURL 的 --data-binary
属性?
我尝试发送 HttpEntity<ByteArrayResource>
、HttpEntity<byte[]>
、HttpEntity<FileSystemResource>
、HttpEntity<ClassPathResource>
但没有成功。
注意:此 API 不支持分段文件上传。
问题已解决。与 cURL 日志显示的相反,我使用的 API 不需要 application/x-www-form-urlencoded
内容类型。
使用文件内容类型解决问题(在我的例子中 image/png
)