cancel
Showing results for 
Search instead for 
Did you mean: 

how to use REST API to create a attachment for a task

roundmonkey
Champ in-the-making
Champ in-the-making
Hi,

I used following codes to upload a attachment on a task, but I always got "400: attachment name is required", I really don't know what I missed, pls help.

FileBody fb=mew FileBody(new File("d:/test.xlsx"));

HttpPost httppost = new HttpPost(url);

MultipartEntity reqEntity = new MultipartEntity();

reqEntity.addPart("name", fb);

reqEntity.addPart("name", "test.xlsx");

httppost.setEntity(reqEntity);

java.lang.Exception: createAttachmentByTaskId for task[9505] error, cause: {"errorMessage":"Attachment name is required.","statusCode":400}

9 REPLIES 9

frederikherema1
Star Contributor
Star Contributor
Don't add the file-body as a part with name "name". Rather, use any other field-name, like:


reqEntity.addPart("file", fb);
reqEntity.addPart("name", "test.xlsx");

Thank you for your quickly reply.

I tried, but it didn't work, still the same issue.

Pls kindly check my codes as followings:

File attachFile = new File("D:/test.xlsx");
respMsg = createAttachmentByTaskId(taskId, attachFile, userName, password);

FileBody fb = new FileBody(attachFile);
HttpResponse resp = JsonRequest.multipartRequest(url, fb, true, userName, password);

public static HttpResponse multipartRequest(String url, FileBody fb, boolean auth, String userName, String password)
  throws Exception {
HttpResponse resp = null;
JSONObject returnResult = null;
DefaultHttpClient client = new DefaultHttpClient();
try {
  HttpPost httppost = new HttpPost(url);
  MultipartEntity reqEntity = new MultipartEntity();
  reqEntity.addPart("file", fb);
  reqEntity.addPart("name", new StringBody("test.xlsx"));
  httppost.setEntity(reqEntity);
  logger.info("post: " + url);
  if (auth) {
   client.getCredentialsProvider().setCredentials(
     new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT, AuthScope.ANY_REALM),
     new UsernamePasswordCredentials(userName, password));
   AuthCache authCache = new BasicAuthCache();
   BasicScheme basicAuth = new BasicScheme();
   String restServerAddr = PropertiesUtil.getProperty("activiti.rest.server.address");
   int restServerPort = StringUtil.getInt(PropertiesUtil.getProperty("activiti.rest.server.port"));
   authCache.put(new HttpHost(restServerAddr, restServerPort, "http"), basicAuth);
   BasicHttpContext localcontext = new BasicHttpContext();
   localcontext.setAttribute(ClientContext.AUTH_CACHE, authCache);
   httppost.addHeader(HTTP.CONTENT_TYPE, "multipart/form-data; boundary=—————————28617237579832");
   resp = client.execute(httppost, localcontext);
  } else {
   resp = client.execute(httppost);
  }
  return resp;
} catch (Exception e) {
  logger.error("multipartRequest for [" + url + "] error: " + e.getMessage(), e);
} finally {
  try {
   client.getConnectionManager().shutdown();
  } catch (Exception ignore) {
  }
}
return resp;
}

Hi frederikheremans,

It done, following is my modified codes:

HttpPost httppost = new HttpPost(url);
MultipartEntity reqEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
reqEntity.addPart("file", fb);
reqEntity.addPart("name", new StringBody("test.xlsx"));
httppost.setEntity(reqEntity);

the Key point is I must use new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);

Seems the MultipartEntity reqEntity = new MultipartEntity() can not be done, that's so weird, anyway, thank you so much.

Yeah, it's working by following codes:

MultipartEntity reqEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
reqEntity.addPart("file", fb);

frederikherema1
Star Contributor
Star Contributor
Is it working now, or not?

pkonyves
Champ in-the-making
Champ in-the-making
Hi,

We are trying to upload files as attachments, but using Jersey client, and did not succeed. Could you post an example HTTP POST request that works?

We tried the following with Jersey, that resulted in "Attachment name is required" error:
<code>
WebResource serviceWebResource = client.resource(baseUrl + "/runtime/tasks/" + taskId + "/attachments");
  ClientResponse res = null;
  FormDataMultiPart fdmp = new FormDataMultiPart();
  fdmp.field("name", "An attachment");
  fdmp.field("description", "An attachment description");
  fdmp.field("type", "myType");
  fdmp.bodyPart(new FileDataBodyPart("file", new File("/tmp/Sample.txt"), MediaType.APPLICATION_OCTET_STREAM_TYPE));
  res = serviceWebResource.type(MediaType.MULTIPART_FORM_DATA).post(ClientResponse.class, fdmp);
  return res.getStatus();
</code>

Then tried using <blockcode>fdmp.bodyPart( new FormDataBodyPart("name", "An attachment"));</blockcode> instead of FormDataMultiPart.field, but no success: same error. Using this method, the HTTP POST request looked like this:

<code>
Content-Type: multipart/form-data
–Boundary_9_18250141_1408968937422
Content-Type: text/plain
Content-Disposition: form-data; name="name"

An attachment
–Boundary_9_18250141_1408968937422
Content-Type: text/plain
Content-Disposition: form-data; name="description"

An attachment description
–Boundary_9_18250141_1408968937422
Content-Type: text/plain
Content-Disposition: form-data; name="type"

myType
–Boundary_9_18250141_1408968937422
Content-Type: application/octet-stream
Content-Disposition: form-data; filename="Sample.txt"; modification-date="Fri, 22 Aug 2014 19:36:17 GMT"; size=40; name="file"

SAMPLE-0123456789012345678901234567890


–Boundary_9_18250141_1408968937422–
</code>


Could you give us some hints?

pkonyves
Champ in-the-making
Champ in-the-making
Hi,

We are trying to upload files as attachments, but using Jersey client, and did not succeed. Could you post an example HTTP POST request that works?

We tried the following with Jersey, that resulted in "Attachment name is required" error:
<code>
WebResource serviceWebResource = client.resource(baseUrl + "/runtime/tasks/" + taskId + "/attachments");
  ClientResponse res = null;
  FormDataMultiPart fdmp = new FormDataMultiPart();
  fdmp.field("name", "An attachment");
  fdmp.field("description", "An attachment description");
  fdmp.field("type", "myType");
  fdmp.bodyPart(new FileDataBodyPart("file", new File("/tmp/Sample.txt"), MediaType.APPLICATION_OCTET_STREAM_TYPE));
  res = serviceWebResource.type(MediaType.MULTIPART_FORM_DATA).post(ClientResponse.class, fdmp);
  return res.getStatus();
</code>

Then tried using <blockcode>fdmp.bodyPart( new FormDataBodyPart("name", "An attachment"));</blockcode> instead of FormDataMultiPart.field, but no success: same error. Using this method, the HTTP POST request looked like this:

<code>
Content-Type: multipart/form-data
–Boundary_9_18250141_1408968937422
Content-Type: text/plain
Content-Disposition: form-data; name="name"

An attachment
–Boundary_9_18250141_1408968937422
Content-Type: text/plain
Content-Disposition: form-data; name="description"

An attachment description
–Boundary_9_18250141_1408968937422
Content-Type: text/plain
Content-Disposition: form-data; name="type"

myType
–Boundary_9_18250141_1408968937422
Content-Type: application/octet-stream
Content-Disposition: form-data; filename="Sample.txt"; modification-date="Fri, 22 Aug 2014 19:36:17 GMT"; size=40; name="file"

SAMPLE-0123456789012345678901234567890


–Boundary_9_18250141_1408968937422–
</code>


Could you give us some hints?

jbarrez
Star Contributor
Star Contributor
I'm not familiar with Jersey, but this is how it's done in our unit test:

<code>
      Task task = taskService.newTask();
      taskService.saveTask(task);

      InputStream binaryContent = new ByteArrayInputStream("This is binary content".getBytes());
     
      // Add name, type and scope
      Map<String, String> additionalFields = new HashMap<String, String>();
      additionalFields.put("name", "An attachment");
      additionalFields.put("description", "An attachment description");
      additionalFields.put("type", "myType");
     
      // Upload a valid BPMN-file using multipart-data
      Representation uploadRepresentation = new HttpMultipartRepresentation("value",
              binaryContent, additionalFields);
     
      ClientResource client = getAuthenticatedClient(RestUrls.createRelativeResourceUrl(RestUrls.URL_TASK_ATTACHMENT_COLLECTION,
              task.getId()));
     
      Representation response = client.post(uploadRepresentation);
      assertEquals(Status.SUCCESS_CREATED, client.getResponse().getStatus());
</code>

chittaranjan168
Champ in-the-making
Champ in-the-making
Hi
I'm converting an image  like.

byte[] blobAsBytes = image.getBytes(1, blobLength);
InputStream binaryContent = new ByteArrayInputStream(blobAsBytes);


and trying to post using spring RestTemplate

                     Map<String, Object> bodyMap2 = new HashMap<String, Object>();
       bodyMap2.put("name","Blob Name");
       bodyMap2.put("description", "blobAsBytes");
       bodyMap2.put("type", "multipart/form-data");
          bodyMap2.put("value", binaryContent);
      
       HttpEntity<Map<String, Object>> requestEntity3 = new HttpEntity<Map<String, Object>>(bodyMap2,header);
       responseEntity=restTemplate.exchange(passTaskIdUrl, HttpMethod.POST, requestEntity3, String.class);

result: getting exceptions like
org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: No serializer found for class java.io.ByteArrayInputStream

Please let me know the mistake i have done here.