如何使用REST Web服务上传包含元数据的文件?
我有一个REST Web服务,当前公开此URL:
HTTP://服务器/数据/媒体
用户可以在POST
以下JSON:
{
"Name": "Test",
"Latitude": 12.59817,
"Longitude": 52.12873
}
以创建新的媒体元数据。
现在我需要能够与媒体元数据同时上传文件。 这是怎么回事? 我可以引入一个名为file
和base64的新属性,但我想知道是否有更好的方法。
还有一些HTML表单可以发送multipart/form-data
,但我使用的是REST Web服务,如果可能的话,我想坚持使用JSON。
我同意格雷格的观点,两阶段的方法是一个合理的解决方案,但我会以相反的方式去做。 我会做:
POST http://server/data/media
body:
{
"Name": "Test",
"Latitude": 12.59817,
"Longitude": 52.12873
}
要创建元数据条目并返回如下响应:
201 Created
Location: http://server/data/media/21323
{
"Name": "Test",
"Latitude": 12.59817,
"Longitude": 52.12873,
"ContentUrl": "http://server/data/media/21323/content"
}
客户端然后可以使用这个ContentUrl并且用文件数据做PUT。
这种方法的好处在于,当你的服务器开始被大量的数据压低时,你返回的url可以指向其他具有更多空间/容量的服务器。 或者如果带宽是一个问题,你可以实现某种循环方法。
仅仅因为你没有用JSON包装整个请求体,并不意味着使用multipart/form-data
在一个请求中发布JSON和文件(或多个文件)不是RESTful:
curl -F "metadata=<metadata.json" -F "file=@my-file.tar.gz" http://example.com/add-file
在服务器端 (这里使用Python作为编程语言):
class AddFileResource(Resource):
def render_POST(self, request):
metadata = json.loads(request.args['metadata'][0])
file_body = request.args['file'][0]
...
要上传多个文件,可以为每个文件使用单独的“表单字段”:
curl -F "metadata=<metadata.json" -F "file1=@some-file.tar.gz" -F "file2=@some-other-file.tar.gz" http://example.com/add-file
...在这种情况下,服务器代码将有request.args['file1'][0]
和request.args['file2'][0]
或者为很多人重复使用同一个:
curl -F "metadata=<metadata.json" -F "files=@some-file.tar.gz" -F "files=@some-other-file.tar.gz" http://example.com/add-file
...在这种情况下, request.args['files']
将只是一个长度为2的列表。
或者一次将多个文件实际传递到单个字段中:
curl -F "metadata=<metadata.json" -F "files=@some-file.tar.gz,some-other-file.tar.gz" http://example.com/add-file
...在这种情况下, request.args['files']
将是一个包含所有文件的字符串,您必须自己解析 - 不知道该怎么做,但我相信这并不困难,或者更好只是使用以前的方法。
@
和<
的不同之处在于@
使文件作为文件上载被附加,而<
作为文本字段附加文件的内容。
PS仅仅因为我将curl
用作生成POST
请求的方式并不意味着不能从Python等编程语言发送完全相同的HTTP请求,也不能使用任何功能强大的工具。
解决这个问题的一种方法是将上传分为两个阶段。 首先,您可以使用POST上传文件本身,其中服务器将一些标识符返回给客户端(标识符可能是文件内容的SHA1)。 然后,第二个请求将元数据与文件数据相关联:
{
"Name": "Test",
"Latitude": 12.59817,
"Longitude": 52.12873,
"ContentID": "7a788f56fa49ae0ba5ebde780efe4d6a89b5db47"
}
包括编码到JSON请求本身的文件数据base64将增加传输数据的大小33%。 根据文件的整体大小,这可能很重要,也可能不重要。
另一种方法可能是使用原始文件数据的POST,但在HTTP请求头中包含任何元数据。 但是,这在基本的REST操作之外有点让人头疼,并且对于某些HTTP客户端库可能会更加尴尬。
链接地址: http://www.djcxy.com/p/8561.html上一篇: How do I upload a file with metadata using a REST web service?
下一篇: Powershell & Curl