提交 11094982 编写于 作者: F Frederik Heremans

Added task-attachment support to REST

上级 0ddeb72e
......@@ -23,10 +23,12 @@ import org.activiti.engine.impl.bpmn.deployer.BpmnDeployer;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.task.Attachment;
import org.activiti.engine.task.Comment;
import org.activiti.engine.task.Event;
import org.activiti.engine.task.IdentityLink;
import org.activiti.engine.task.Task;
import org.activiti.rest.api.engine.AttachmentResponse;
import org.activiti.rest.api.engine.CommentResponse;
import org.activiti.rest.api.engine.EventResponse;
import org.activiti.rest.api.engine.variable.BooleanRestVariableConverter;
......@@ -281,6 +283,30 @@ public class RestResponseFactory {
return result ;
}
public AttachmentResponse createAttachmentResponse(SecuredResource securedResource, Attachment attachment) {
AttachmentResponse result = new AttachmentResponse();
result.setId(attachment.getId());
result.setName(attachment.getName());
result.setDescription(attachment.getDescription());
result.setType(attachment.getType());
if(attachment.getUrl() == null && attachment.getTaskId() != null) {
// Attachment content can be streamed
result.setContentUrl(securedResource.createFullResourceUrl(RestUrls.URL_TASK_ATTACHMENT_DATA, attachment.getTaskId(), attachment.getId()));
} else {
result.setExternalUrl(attachment.getUrl());
}
if(attachment.getTaskId() != null) {
result.setUrl(securedResource.createFullResourceUrl(RestUrls.URL_TASK_ATTACHMENT, attachment.getTaskId(), attachment.getId()));
result.setTaskUrl(securedResource.createFullResourceUrl(RestUrls.URL_TASK, attachment.getTaskId()));
}
if(attachment.getProcessInstanceId() != null) {
result.setTaskUrl(securedResource.createFullResourceUrl(RestUrls.URL_PROCESS_INSTANCE, attachment.getProcessInstanceId()));
}
return result ;
}
/**
* Called once when the converters need to be initialized. Override of custom conversion
......
......@@ -41,6 +41,8 @@ public final class RestUrls {
public static final String SEGMENT_IDENTITYLINKS = "identitylinks";
public static final String SEGMENT_COMMENTS = "comments";
public static final String SEGMENT_EVENTS = "events";
public static final String SEGMENT_ATTACHMENTS = "attachments";
public static final String SEGMENT_ATTACHMENT_CONTENT = "content";
public static final String SEGMENT_IDENTITYLINKS_FAMILY_GROUPS = "groups";
public static final String SEGMENT_IDENTITYLINKS_FAMILY_USERS = "users";
public static final String SEGMENT_VARIABLE_DATA = "data";
......@@ -144,6 +146,21 @@ public final class RestUrls {
*/
public static final String[] URL_TASK_EVENT = {SEGMENT_RUNTIME_RESOURCES, SEGMENT_TASK_RESOURCE, "{0}", SEGMENT_EVENTS, "{1}"};
/**
* URL template for an task's attachments: <i>runtime/tasks/{0:taskId}/attachments</i>
*/
public static final String[] URL_TASK_ATTACHMENT_COLLECTION = {SEGMENT_RUNTIME_RESOURCES, SEGMENT_TASK_RESOURCE, "{0}", SEGMENT_ATTACHMENTS};
/**
* URL template for an attachment on a task: <i>runtime/tasks/{0:taskId}/attachments/{1:attachmentId}</i>
*/
public static final String[] URL_TASK_ATTACHMENT = {SEGMENT_RUNTIME_RESOURCES, SEGMENT_TASK_RESOURCE, "{0}", SEGMENT_ATTACHMENTS, "{1}"};
/**
* URL template for the content for an attachment on a task: <i>runtime/tasks/{0:taskId}/attachments/{1:attachmentId}/content</i>
*/
public static final String[] URL_TASK_ATTACHMENT_DATA = {SEGMENT_RUNTIME_RESOURCES, SEGMENT_TASK_RESOURCE, "{0}", SEGMENT_ATTACHMENTS, "{1}", SEGMENT_ATTACHMENT_CONTENT};
/**
* URL template for execution collection: <i>runtime/executions/{0:executionId}</i>
*/
......
/* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.activiti.rest.api.engine;
/**
* @author Frederik Heremans
*/
public class AttachmentRequest {
private String name;
private String description;
private String type;
private String externalUrl;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getExternalUrl() {
return externalUrl;
}
public void setExternalUrl(String externalUrl) {
this.externalUrl = externalUrl;
}
}
/* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.activiti.rest.api.engine;
/**
* @author Frederik Heremans
*/
public class AttachmentResponse {
private String id;
private String url;
private String name;
private String description;
private String type;
private String taskUrl;
private String processInstanceUrl;
private String externalUrl;
private String contentUrl;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getTaskUrl() {
return taskUrl;
}
public void setTaskUrl(String taskUrl) {
this.taskUrl = taskUrl;
}
public String getProcessInstanceUrl() {
return processInstanceUrl;
}
public void setProcessInstanceUrl(String processInstanceUrl) {
this.processInstanceUrl = processInstanceUrl;
}
public String getExternalUrl() {
return externalUrl;
}
public void setExternalUrl(String externalUrl) {
this.externalUrl = externalUrl;
}
public String getContentUrl() {
return contentUrl;
}
public void setContentUrl(String contentUrl) {
this.contentUrl = contentUrl;
}
}
......@@ -30,7 +30,7 @@ import org.restlet.resource.Get;
/**
* @author Tijs Rademakers
*/
public class TaskAttachmentResource extends SecuredResource {
public class LegacyTaskAttachmentResource extends SecuredResource {
@Get
public InputRepresentation getAttachment() {
......
/* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.activiti.rest.api.task;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.activiti.engine.ActivitiIllegalArgumentException;
import org.activiti.engine.task.Attachment;
import org.activiti.engine.task.Task;
import org.activiti.rest.api.ActivitiUtil;
import org.activiti.rest.api.RestResponseFactory;
import org.activiti.rest.api.engine.AttachmentRequest;
import org.activiti.rest.api.engine.AttachmentResponse;
import org.activiti.rest.application.ActivitiRestServicesApplication;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.restlet.data.MediaType;
import org.restlet.data.Status;
import org.restlet.ext.fileupload.RestletFileUpload;
import org.restlet.representation.Representation;
import org.restlet.resource.Get;
import org.restlet.resource.Post;
import org.restlet.resource.ResourceException;
/**
* @author Frederik Heremans
*/
public class TaskAttachmentCollectionResource extends TaskBasedResource {
@Get
public List<AttachmentResponse> getAttachments() {
if(!authenticate())
return null;
List<AttachmentResponse> result = new ArrayList<AttachmentResponse>();
RestResponseFactory responseFactory = getApplication(ActivitiRestServicesApplication.class).getRestResponseFactory();
Task task = getTaskFromRequest();
for(Attachment attachment : ActivitiUtil.getTaskService().getTaskAttachments(task.getId())) {
result.add(responseFactory.createAttachmentResponse(this, attachment));
}
return result;
}
@Post
public AttachmentResponse createAttachment(Representation representation) {
if (authenticate() == false)
return null;
AttachmentResponse result = null;
Task task = getTaskFromRequest();
try {
if (MediaType.MULTIPART_FORM_DATA.isCompatible(representation.getMediaType())) {
result = createBinaryAttachment(representation, task);
} else {
result = createSimpleAttachment(representation, task);
}
} catch (IOException e) {
throw new ResourceException(Status.CLIENT_ERROR_BAD_REQUEST, e);
} catch (FileUploadException e) {
throw new ResourceException(Status.CLIENT_ERROR_BAD_REQUEST, e);
}
setStatus(Status.SUCCESS_CREATED);
return result;
}
protected AttachmentResponse createSimpleAttachment(Representation representation, Task task) throws IOException {
AttachmentRequest req = getConverterService().toObject(representation, AttachmentRequest.class, this);
if (req.getName() == null) {
throw new ActivitiIllegalArgumentException("Attachment name is required.");
}
Attachment createdAttachment = ActivitiUtil.getTaskService().createAttachment(req.getType(), task.getId(), null, req.getName(),
req.getDescription(), req.getExternalUrl());
return getApplication(ActivitiRestServicesApplication.class).getRestResponseFactory().createAttachmentResponse(this, createdAttachment);
}
protected AttachmentResponse createBinaryAttachment(Representation representation, Task task) throws FileUploadException, IOException {
RestletFileUpload upload = new RestletFileUpload(new DiskFileItemFactory());
List<FileItem> items = upload.parseRepresentation(representation);
String name = null;
String description = null;
String type = null;
FileItem uploadItem = null;
for (FileItem fileItem : items) {
if(fileItem.isFormField()) {
if("name".equals(fileItem.getFieldName())) {
name = fileItem.getString("UTF-8");
} else if("description".equals(fileItem.getFieldName())) {
description = fileItem.getString("UTF-8");
} else if("type".equals(fileItem.getFieldName())) {
type = fileItem.getString("UTF-8");
}
} else if(fileItem.getName() != null) {
uploadItem = fileItem;
}
}
if (name == null) {
throw new ActivitiIllegalArgumentException("Attachment name is required.");
}
if (uploadItem == null) {
throw new ActivitiIllegalArgumentException("Attachment content is required.");
}
Attachment createdAttachment = ActivitiUtil.getTaskService().createAttachment(type, task.getId(), null, name,
description, uploadItem.getInputStream());
setStatus(Status.SUCCESS_CREATED);
return getApplication(ActivitiRestServicesApplication.class).getRestResponseFactory().createAttachmentResponse(this, createdAttachment);
}
}
/* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.activiti.rest.api.task;
import java.io.InputStream;
import org.activiti.engine.ActivitiIllegalArgumentException;
import org.activiti.engine.ActivitiObjectNotFoundException;
import org.activiti.engine.task.Attachment;
import org.activiti.engine.task.Task;
import org.activiti.rest.api.ActivitiUtil;
import org.restlet.data.MediaType;
import org.restlet.representation.InputRepresentation;
import org.restlet.resource.Get;
/**
* @author Frederik Heremans
*/
public class TaskAttachmentContentResource extends TaskBasedResource {
@Get
public InputRepresentation getAttachmentContent() {
if(!authenticate())
return null;
Task task = getTaskFromRequest();
String attachmentId = getAttribute("attachmentId");
if(attachmentId == null) {
throw new ActivitiIllegalArgumentException("AttachmentId is required.");
}
Attachment attachment = ActivitiUtil.getTaskService().getAttachment(attachmentId);
if(attachment == null || !task.getId().equals(attachment.getTaskId())) {
throw new ActivitiObjectNotFoundException("Task '" + task.getId() +"' doesn't have an attachment with id '" + attachmentId + "'.", Attachment.class);
}
InputStream attachmentStream = ActivitiUtil.getTaskService().getAttachmentContent(attachmentId);
if(attachmentStream == null) {
throw new ActivitiObjectNotFoundException("Attachment with id '" + attachmentId + "' doesn't have content associated with it.", Attachment.class);
}
// Try extracting media-type is type is set and is a valid type
MediaType type = null;
if(attachment.getType() != null && MediaType.valueOf(attachment.getType()) != null) {
type = MediaType.valueOf(attachment.getType());
}
if(type == null || !type.isConcrete()) {
type = MediaType.APPLICATION_OCTET_STREAM;
}
return new InputRepresentation(attachmentStream, type);
}
}
/* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.activiti.rest.api.task;
import org.activiti.engine.ActivitiIllegalArgumentException;
import org.activiti.engine.ActivitiObjectNotFoundException;
import org.activiti.engine.task.Attachment;
import org.activiti.engine.task.Comment;
import org.activiti.engine.task.Task;
import org.activiti.rest.api.ActivitiUtil;
import org.activiti.rest.api.engine.AttachmentResponse;
import org.activiti.rest.application.ActivitiRestServicesApplication;
import org.restlet.data.Status;
import org.restlet.resource.Delete;
import org.restlet.resource.Get;
/**
* @author Frederik Heremans
*/
public class TaskAttachmentResource extends TaskBasedResource {
@Get
public AttachmentResponse getAttachment() {
if(!authenticate())
return null;
Task task = getTaskFromRequest();
String attachmentId = getAttribute("attachmentId");
if(attachmentId == null) {
throw new ActivitiIllegalArgumentException("AttachmentId is required.");
}
Attachment attachment = ActivitiUtil.getTaskService().getAttachment(attachmentId);
if(attachment == null || !task.getId().equals(attachment.getTaskId())) {
throw new ActivitiObjectNotFoundException("Task '" + task.getId() +"' doesn't have an attachment with id '" + attachmentId + "'.", Comment.class);
}
return getApplication(ActivitiRestServicesApplication.class).getRestResponseFactory()
.createAttachmentResponse(this, attachment);
}
@Delete
public void delegteAttachment() {
if(!authenticate())
return;
Task task = getTaskFromRequest();
String attachmentId = getAttribute("attachmentId");
if(attachmentId == null) {
throw new ActivitiIllegalArgumentException("AttachmentId is required.");
}
Attachment attachment = ActivitiUtil.getTaskService().getAttachment(attachmentId);
if(attachment == null || !task.getId().equals(attachment.getTaskId())) {
throw new ActivitiObjectNotFoundException("Task '" + task.getId() +"' doesn't have an attachment with id '" + attachmentId + "'.", Comment.class);
}
ActivitiUtil.getTaskService().deleteAttachment(attachmentId);
setStatus(Status.SUCCESS_NO_CONTENT);
}
}
......@@ -43,7 +43,7 @@ public class TaskCommentResource extends TaskBasedResource {
}
Comment comment = ActivitiUtil.getTaskService().getComment(commentId);
if(comment == null) {
if(comment == null || !task.getId().equals(comment.getTaskId())) {
throw new ActivitiObjectNotFoundException("Task '" + task.getId() +"' doesn't have a comment with id '" + commentId + "'.", Comment.class);
}
......
......@@ -31,7 +31,7 @@ import org.restlet.resource.Get;
public class TaskEventCollectionResource extends TaskBasedResource {
@Get
public List<EventResponse> getComments() {
public List<EventResponse> getEvents() {
if(!authenticate())
return null;
......
......@@ -44,7 +44,7 @@ public class TaskEventResource extends TaskBasedResource {
}
Event event = ActivitiUtil.getTaskService().getEvent(eventId);
if(event == null) {
if(event == null || !task.getId().equals(event.getTaskId())) {
throw new ActivitiObjectNotFoundException("Task '" + task.getId() +"' doesn't have an event with id '" + eventId + "'.", Event.class);
}
......
......@@ -15,7 +15,7 @@ import org.activiti.rest.api.identity.UserResource;
import org.activiti.rest.api.identity.UserSearchResource;
import org.activiti.rest.api.legacy.TaskAddResource;
import org.activiti.rest.api.legacy.TaskAttachmentAddResource;
import org.activiti.rest.api.legacy.TaskAttachmentResource;
import org.activiti.rest.api.legacy.LegacyTaskAttachmentResource;
import org.activiti.rest.api.legacy.TaskFormResource;
import org.activiti.rest.api.legacy.TaskOperationResource;
import org.activiti.rest.api.legacy.TaskPropertiesResource;
......@@ -55,6 +55,9 @@ import org.activiti.rest.api.repository.DeploymentResourceResource;
import org.activiti.rest.api.repository.ProcessDefinitionCollectionResource;
import org.activiti.rest.api.repository.ProcessDefinitionResource;
import org.activiti.rest.api.repository.SimpleWorkflowResource;
import org.activiti.rest.api.task.TaskAttachmentCollectionResource;
import org.activiti.rest.api.task.TaskAttachmentContentResource;
import org.activiti.rest.api.task.TaskAttachmentResource;
import org.activiti.rest.api.task.TaskCollectionResource;
import org.activiti.rest.api.task.TaskCommentCollectionResource;
import org.activiti.rest.api.task.TaskCommentResource;
......@@ -97,6 +100,9 @@ public class RestServicesInit {
router.attach("/runtime/tasks/{taskId}/comments/{commentId}", TaskCommentResource.class);
router.attach("/runtime/tasks/{taskId}/events", TaskEventCollectionResource.class);
router.attach("/runtime/tasks/{taskId}/events/{eventId}", TaskEventResource.class);
router.attach("/runtime/tasks/{taskId}/attachments", TaskAttachmentCollectionResource.class);
router.attach("/runtime/tasks/{taskId}/attachments/{attachmentId}", TaskAttachmentResource.class);
router.attach("/runtime/tasks/{taskId}/attachments/{attachmentId}/content", TaskAttachmentContentResource.class);
router.attach("/query/tasks", TaskQueryResource.class);
......@@ -141,7 +147,7 @@ public class RestServicesInit {
router.attach("/history/{taskId}/form-properties", HistoricFormPropertiesResource.class);
router.attach("/attachment/{attachmentId}", TaskAttachmentResource.class);
router.attach("/attachment/{attachmentId}", LegacyTaskAttachmentResource.class);
router.attach("/form/{taskId}/properties", TaskPropertiesResource.class);
......
......@@ -3261,6 +3261,454 @@ GET runtime/tasks/{taskId}/identitylinks/groups</programlisting>
</para>
</section>
<section>
<title>Create a new attachment on a task, containing a link to an external resource</title>
<para>
<programlisting>POST runtime/tasks/{taskId}/attachments</programlisting>
</para>
<para>
<table>
<title>URL parameters</title>
<tgroup cols='3'>
<thead>
<row>
<entry>Parameter</entry>
<entry>Required</entry>
<entry>Value</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry>taskId</entry>
<entry>Yes</entry>
<entry>String</entry>
<entry>The id of the task to create the attachment for.</entry>
</row>
</tbody>
</tgroup>
</table>
</para>
<para>
<emphasis role="bold">Request body:</emphasis>
<programlisting>
{
"name":"Simple attachment",
"description":"Simple attachment description",
"type":"simpleType",
"externalUrl":"http://activiti.org"
}</programlisting>
Only the attachment name is required to create a new attachment.
</para>
<para>
<emphasis role="bold">Success response body:</emphasis>
<programlisting>
{
"id":"3",
"url":"http://localhost:8182/runtime/tasks/2/attachments/3",
"name":"Simple attachment",
"description":"Simple attachment description",
"type":"simpleType",
"taskUrl":"http://localhost:8182/runtime/tasks/2",
"processInstanceUrl":null,
"externalUrl":"http://activiti.org",
"contentUrl":null
}</programlisting>
<table>
<title>Response codes</title>
<tgroup cols='2'>
<thead>
<row>
<entry>Response code</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry>201</entry>
<entry>Indicates the attachment was created and the result is returned.</entry>
</row>
<row>
<entry>400</entry>
<entry>Indicates the attachment name is missing from the request.</entry>
</row>
<row>
<entry>404</entry>
<entry>Indicates the requested task was not found.</entry>
</row>
</tbody>
</tgroup>
</table>
</para>
</section>
<section>
<title>Create a new attachment on a task, with an attached file</title>
<para>
<programlisting>POST runtime/tasks/{taskId}/attachments</programlisting>
</para>
<para>
<table>
<title>URL parameters</title>
<tgroup cols='3'>
<thead>
<row>
<entry>Parameter</entry>
<entry>Required</entry>
<entry>Value</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry>taskId</entry>
<entry>Yes</entry>
<entry>String</entry>
<entry>The id of the task to create the attachment for.</entry>
</row>
</tbody>
</tgroup>
</table>
</para>
<para>
<emphasis role="bold">Request body:</emphasis>
The request should be of type <literal>multipart/form-data</literal>. There should be a single file-part included with the binary value of the variable. On top of that, the folowing additionl form-fields can be present:
<itemizedlist>
<listitem>
<para><literal>name</literal>: Required name of the variable.</para>
</listitem>
<listitem>
<para><literal>description</literal>: Description of the attachment, optional.</para>
</listitem>
<listitem>
<para><literal>type</literal>: Type of attachment, optional. Supports any arbitrary string or a valid HTTP content-type.</para>
</listitem>
</itemizedlist>
</para>
<para>
<emphasis role="bold">Success response body:</emphasis>
<programlisting>
{
"id":"5",
"url":"http://localhost:8182/runtime/tasks/2/attachments/5",
"name":"Binary attachment",
"description":"Binary attachment description",
"type":"binaryType",
"taskUrl":"http://localhost:8182/runtime/tasks/2",
"processInstanceUrl":null,
"externalUrl":null,
"contentUrl":"http://localhost:8182/runtime/tasks/2/attachments/5/content"
}</programlisting>
<table>
<title>Response codes</title>
<tgroup cols='2'>
<thead>
<row>
<entry>Response code</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry>201</entry>
<entry>Indicates the attachment was created and the result is returned.</entry>
</row>
<row>
<entry>400</entry>
<entry>Indicates the attachment name is missing from the request or no file was present in the request. The error-message contains additional information.</entry>
</row>
<row>
<entry>404</entry>
<entry>Indicates the requested task was not found.</entry>
</row>
</tbody>
</tgroup>
</table>
</para>
</section>
<section>
<title>Get all attachments on a task</title>
<para>
<programlisting>GET runtime/tasks/{taskId}/attachments</programlisting>
</para>
<para>
<table>
<title>URL parameters</title>
<tgroup cols='3'>
<thead>
<row>
<entry>Parameter</entry>
<entry>Required</entry>
<entry>Value</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry>taskId</entry>
<entry>Yes</entry>
<entry>String</entry>
<entry>The id of the task to get the attachments for.</entry>
</row>
</tbody>
</tgroup>
</table>
</para>
<para>
<emphasis role="bold">Success response body:</emphasis>
<programlisting>
[
{
"id":"3",
"url":"http://localhost:8182/runtime/tasks/2/attachments/3",
"name":"Simple attachment",
"description":"Simple attachment description",
"type":"simpleType",
"taskUrl":"http://localhost:8182/runtime/tasks/2",
"processInstanceUrl":null,
"externalUrl":"http://activiti.org",
"contentUrl":null
},
{
"id":"5",
"url":"http://localhost:8182/runtime/tasks/2/attachments/5",
"name":"Binary attachment",
"description":"Binary attachment description",
"type":"binaryType",
"taskUrl":"http://localhost:8182/runtime/tasks/2",
"processInstanceUrl":null,
"externalUrl":null,
"contentUrl":"http://localhost:8182/runtime/tasks/2/attachments/5/content"
}
]</programlisting>
<table>
<title>Response codes</title>
<tgroup cols='2'>
<thead>
<row>
<entry>Response code</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry>200</entry>
<entry>Indicates the task was found and the attachments are returned.</entry>
</row>
<row>
<entry>404</entry>
<entry>Indicates the requested task was not found.</entry>
</row>
</tbody>
</tgroup>
</table>
</para>
</section>
<section>
<title>Get a single attachment on a task</title>
<para>
<programlisting>GET runtime/tasks/{taskId}/attachments/{attachmentId}</programlisting>
</para>
<para>
<table>
<title>URL parameters</title>
<tgroup cols='3'>
<thead>
<row>
<entry>Parameter</entry>
<entry>Required</entry>
<entry>Value</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry>taskId</entry>
<entry>Yes</entry>
<entry>String</entry>
<entry>The id of the task to get the attachment for.</entry>
</row>
<row>
<entry>attachmentId</entry>
<entry>Yes</entry>
<entry>String</entry>
<entry>The id of the attachment.</entry>
</row>
</tbody>
</tgroup>
</table>
</para>
<para>
<emphasis role="bold">Success response body:</emphasis>
<programlisting>
{
"id":"5",
"url":"http://localhost:8182/runtime/tasks/2/attachments/5",
"name":"Binary attachment",
"description":"Binary attachment description",
"type":"binaryType",
"taskUrl":"http://localhost:8182/runtime/tasks/2",
"processInstanceUrl":null,
"externalUrl":null,
"contentUrl":"http://localhost:8182/runtime/tasks/2/attachments/5/content"
}</programlisting>
<itemizedlist>
<listitem>
<para>
<literal>externalUrl - contentUrl:</literal>In case the attachment is a link to an external resource, the <literal>externalUrl</literal> contains the URL to the external content. If the attachment content is present in the
Activiti engine, the <literal>contentUrl</literal> will contain an URL where the binary content can be streamed from.
</para>
</listitem>
<listitem>
<para>
<literal>type:</literal>Can be any arbitrary value. When a valid formatted media-type (eg. application/xml, text/plain) is included, the binary content HTTP response content-type will be set the the given value.
</para>
</listitem>
</itemizedlist>
</para>
<para>
<table>
<title>Response codes</title>
<tgroup cols='2'>
<thead>
<row>
<entry>Response code</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry>200</entry>
<entry>Indicates the task and attachment were found and the attachment is returned.</entry>
</row>
<row>
<entry>404</entry>
<entry>Indicates the requested task was not found or the tasks doesn't have a attachment with the given ID.</entry>
</row>
</tbody>
</tgroup>
</table>
</para>
</section>
<section>
<title>Get the content for an attachment</title>
<para>
<programlisting>GET runtime/tasks/{taskId}/attachment/{attachmentId}/content</programlisting>
</para>
<para>
<table>
<title>URL parameters</title>
<tgroup cols='3'>
<thead>
<row>
<entry>Parameter</entry>
<entry>Required</entry>
<entry>Value</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry>taskId</entry>
<entry>Yes</entry>
<entry>String</entry>
<entry>The id of the task to get a variable data for.</entry>
</row>
<row>
<entry>attachmentId</entry>
<entry>Yes</entry>
<entry>String</entry>
<entry>The id of the attachment, a <literal>404</literal> is returned when the attachment points to an external URL rather than content attached in Activiti.</entry>
</row>
</tbody>
</tgroup>
</table>
</para>
<para>
<table>
<title>Response codes</title>
<tgroup cols='2'>
<thead>
<row>
<entry>Response code</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry>200</entry>
<entry>Indicates the task and attachment was found and the requested content is returned.</entry>
</row>
<row>
<entry>404</entry>
<entry>Indicates the requested task was not found or the task doesn't have an attachment with the given id or the attachment doesn't have a binary stream available. Status message provides additional information.</entry>
</row>
</tbody>
</tgroup>
</table>
</para>
<para>
<emphasis role="bold">Success response body:</emphasis>
The response body contains the binary content. By default, the content-type of the response is set to <literal>application/octet-stream</literal> unless the attachment type contains a valid Content-type.
</para>
</section>
<section>
<title>Delete a single attachment on a task</title>
<para>
<programlisting>DELETE runtime/tasks/{taskId}/attachments/{attachmentId}</programlisting>
</para>
<para>
<table>
<title>URL parameters</title>
<tgroup cols='3'>
<thead>
<row>
<entry>Parameter</entry>
<entry>Required</entry>
<entry>Value</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry>taskId</entry>
<entry>Yes</entry>
<entry>String</entry>
<entry>The id of the task to delete the attachment for.</entry>
</row>
<row>
<entry>attachmentId</entry>
<entry>Yes</entry>
<entry>String</entry>
<entry>The id of the attachment.</entry>
</row>
</tbody>
</tgroup>
</table>
</para>
<table>
<title>Response codes</title>
<tgroup cols='2'>
<thead>
<row>
<entry>Response code</entry>
<entry>Description</entry>
</row>
</thead>
<tbody>
<row>
<entry>204</entry>
<entry>Indicates the task and attachment were found and the attachment is deleted. Response body is left empty intentionally.</entry>
</row>
<row>
<entry>404</entry>
<entry>Indicates the requested task was not found or the tasks doesn't have a attachment with the given ID.</entry>
</row>
</tbody>
</tgroup>
</table>
</section>
</section>
<!-- Legacy -->
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册