mhrsalehi
mhrsalehi

Reputation: 1384

How to send multipart/form-data with Spring RestTemplate?

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 [email protected]

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!

Upvotes: 3

Views: 8223

Answers (1)

Danil Kuznetsov
Danil Kuznetsov

Reputation: 814

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);

Upvotes: 9

Related Questions