英文:
How to send multipart/form-data with Spring RestTemplate?
问题
我想向一个 REST 端点发送 POST
请求。该 REST 端点的文档如下:
> 创建一个节点并将其添加为节点 nodeId 的主要子节点。
>
> 此端点支持 JSON 和 multipart/form-data(文件上传)两种方式。
>
> 使用 multipart/form-data
>
> 使用 filedata 字段来表示要上传的内容,例如,以下 curl 命令将在测试用户的主目录中创建一个带有 test.txt 内容的节点。
>
> curl -utest:test -X POST
> host:port/alfresco/api/-default-/public/alfresco/versions/1/nodes/-my-/children
> -F filedata=@test.txt
>
> 您可以使用 name 字段为新文件指定替代名称。
>
> 您可以使用 nodeType 字段创建特定类型。默认为 cm:content
我通过以下代码成功地向该端点发送了正确的请求:
@Override
public ResponseEntity<byte[]> postNode(String nodeId, byte[] content) {
MultiValueMap<String, Object> bodyMap = new LinkedMultiValueMap<>();
ByteArrayResource contentsAsResource = new ByteArrayResource(content) {
@Override
public String getFilename() {
return "name22222";
}
};
bodyMap.add("filedata", contentsAsResource);
///bodyMap.add("filedata", content);// 为什么这行不起作用?!
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(bodyMap, headers);
return restTemplate.exchange("/nodes/{nodeId}/children", HttpMethod.POST, requestEntity, byte[].class, nodeId);
}
但我有两个问题:
1 - 为什么注释掉的那行不起作用?
2 - 文档中说:
> 您可以使用 name 字段为新文件指定替代名称。
我没有使用 "name"
字段,但服务器将我的文件保存为正确的名称(="name22222"
),为什么?(我以为 multipart/form-data
是一种简单的名称-值方式,如果这是正确的,那么我有一个名为 "filedata" 的字段,其值是我的 byte
数组内容,那么文件名是如何发送的?)。我如何使用一个 字段 来指定文件名?
更新:
我认为我找到了答案。我只需要阅读关于 multipart/form-data
的内容!
英文:
I want to send a POST
request to a rest endpoint. the rest endpoint documentation says:
> Create a node and add it as a primary child of node nodeId.
>
> This endpoint supports both JSON and multipart/form-data (file
> upload).
>
> Using multipart/form-data
>
> Use the filedata field to represent the content to upload, for
> example, the following curl command will create a node with the
> contents of test.txt in the test user's home folder.
>
> curl -utest:test -X POST
> host:port/alfresco/api/-default-/public/alfresco/versions/1/nodes/-my-/children
> -F filedata=@test.txt
>
> You can use the name field to give an alternative name for the new
> file.
>
> You can use the nodeType field to create a specific type. The default
> is cm:content
I managed to send a correct request to this endpoint by the following code:
@Override
public ResponseEntity<byte[]> postNode(String nodeId, byte[] content) {
MultiValueMap<String, Object> bodyMap = new LinkedMultiValueMap<>();
ByteArrayResource contentsAsResource = new ByteArrayResource(content) {
@Override
public String getFilename() {
return "name22222";
}
};
bodyMap.add("filedata", contentsAsResource);
///bodyMap.add("filedata", content);// why this does not work??!
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(bodyMap, headers);
return restTemplate.exchange("/nodes/{nodeId}/children", HttpMethod.POST, requestEntity, byte[].class, nodeId);
}
but I have two questions:
1 - why the commented line does not work?
2 - the docs says :
> You can use the name field to give an alternative name for the new
> file.
I did not use a "name"
field, but the server saved my files with the correct name(="name22222"
), why?(I thought multipart/form-data
is a kind of a simple name-value, if this is correct then I have a field named "filedata" and its value is my byte
array content, so how the file name is send?). and how can I specify the file name with a field?
update :
i think i found my answers. i just need to read about multipart/form-data
!
答案1
得分: 5
也许这个示例对于了解如何使用Spring上传一个或多个文件会很有帮助。
byte[] fileContent = "testFileContent".getBytes();
String filename = "testFile.xml";
MultiValueMap<String, String> fileMap = new LinkedMultiValueMap<>();
ContentDisposition contentDisposition = ContentDisposition
.builder("form-data")
.name("file")
.filename(filename)
.build();
fileMap.add(HttpHeaders.CONTENT_DISPOSITION, contentDisposition.toString());
HttpEntity<byte[]> fileEntity = new HttpEntity<>(fileContent, fileMap);
MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
body.add("file", fileEntity);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(body, headers);
ResponseEntity<String> response = restTemplate
.postForEntity("/import/file", requestEntity, String.class);
英文:
Perhaps this example will be useful to find out how you can upload one or more files using Spring.
byte[] fileContent = "testFileContent".getBytes();
String filename = "testFile.xml";
MultiValueMap<String, String> fileMap = new LinkedMultiValueMap<>();
ContentDisposition contentDisposition = ContentDisposition
.builder("form-data")
.name("file")
.filename(filename)
.build();
fileMap.add(HttpHeaders.CONTENT_DISPOSITION, contentDisposition.toString());
HttpEntity<byte[]> fileEntity = new HttpEntity<>(fileContent, fileMap);
MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
body.add("file", fileEntity);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(body, headers);
ResponseEntity<String> response = restTemplate
.postForEntity("/import/file, requestEntity, String.class);
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论