在一个应用程序中,我正在开发RESTful API,我们希望客户端以JSON形式发送数据。这个应用程序的一部分要求客户端上传一个文件(通常是一个图像)以及关于图像的信息。
我很难在一个请求中找到这种情况。是否可以将文件数据Base64转换为JSON字符串?我是否需要向服务器发送2次帖子?我不应该使用JSON吗?
顺便说一句,我们在后端使用Grails,这些服务是由本地移动客户端(iPhone、Android等)访问的,如果有什么不同的话。
在一个应用程序中,我正在开发RESTful API,我们希望客户端以JSON形式发送数据。这个应用程序的一部分要求客户端上传一个文件(通常是一个图像)以及关于图像的信息。
我很难在一个请求中找到这种情况。是否可以将文件数据Base64转换为JSON字符串?我是否需要向服务器发送2次帖子?我不应该使用JSON吗?
顺便说一句,我们在后端使用Grails,这些服务是由本地移动客户端(iPhone、Android等)访问的,如果有什么不同的话。
当前回答
我想发送一些字符串到后端服务器。我没有使用json与multipart,我已经使用请求参数。
@RequestMapping(value = "/upload", method = RequestMethod.POST)
public void uploadFile(HttpServletRequest request,
HttpServletResponse response, @RequestParam("uuid") String uuid,
@RequestParam("type") DocType type,
@RequestParam("file") MultipartFile uploadfile)
Url看起来像这样
http://localhost:8080/file/upload?uuid=46f073d0&type=PASSPORT
我在文件上传时传递了两个参数(uuid和type)。 希望这将帮助谁没有复杂的json数据发送。
其他回答
你可以使用multipart/form-data内容类型在一个请求中发送文件和数据:
在许多应用程序中,可能会向用户显示 一种形式。用户将填写表单,包括以下信息 类型的、由用户输入生成的或包含在 用户已选择。表单填写后,从 表单从用户发送到接收应用程序。 MultiPart/Form-Data的定义就是从这些定义中派生出来的 应用程序…
从http://www.faqs.org/rfcs/rfc2388.html:
“multipart/form-data”包含一系列的部分。每个部分是 期望包含一个内容处理头[RFC 2183] 处置类型为“form-data”,其中处置包含 一个(额外的)参数“name”,其中的值 参数是表单中的原始字段名。例如,一个部分 可能包含一个头文件: 附加:格式;name = "用户" 与“user”字段的条目对应的值。
You can include file information or field information within each section between boundaries. I've successfully implemented a RESTful service that required the user to submit both data and a form, and multipart/form-data worked perfectly. The service was built using Java/Spring, and the client was using C#, so unfortunately I don't have any Grails examples to give you concerning how to set up the service. You don't need to use JSON in this case since each "form-data" section provides you a place to specify the name of the parameter and its value.
使用multipart/form-data的好处是您使用的是HTTP定义的报头,因此您坚持使用现有HTTP工具创建服务的REST理念。
我在这里问了一个类似的问题:
如何使用REST web服务上传带有元数据的文件?
你基本上有三个选择:
Base64 encode the file, at the expense of increasing the data size by around 33%, and add processing overhead in both the server and the client for encoding/decoding. Send the file first in a multipart/form-data POST, and return an ID to the client. The client then sends the metadata with the ID, and the server re-associates the file and the metadata. Send the metadata first, and return an ID to the client. The client then sends the file with the ID, and the server re-associates the file and the metadata.
请确保您有以下导入。当然还有其他标准的进口
import org.springframework.core.io.FileSystemResource
void uploadzipFiles(String token) {
RestBuilder rest = new RestBuilder(connectTimeout:10000, readTimeout:20000)
def zipFile = new File("testdata.zip")
def Id = "001G00000"
MultiValueMap<String, String> form = new LinkedMultiValueMap<String, String>()
form.add("id", id)
form.add('file',new FileSystemResource(zipFile))
def urld ='''http://URL''';
def resp = rest.post(urld) {
header('X-Auth-Token', clientSecret)
contentType "multipart/form-data"
body(form)
}
println "resp::"+resp
println "resp::"+resp.text
println "resp::"+resp.headers
println "resp::"+resp.body
println "resp::"+resp.status
}
您可以尝试使用https://square.github.io/okhttp/ library。 你可以设置请求主体为multipart,然后分别添加文件和json对象,如下所示:
MultipartBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("uploadFile", uploadFile.getName(), okhttp3.RequestBody.create(uploadFile, MediaType.parse("image/png")))
.addFormDataPart("file metadata", json)
.build();
Request request = new Request.Builder()
.url("https://uploadurl.com/uploadFile")
.post(requestBody)
.build();
try (Response response = client.newCall(request).execute()) {
if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
logger.info(response.body().string());
我知道这个问题很老了,但在过去的几天里,我搜索了整个网络来解决这个问题。我有grails REST web服务和iPhone客户端发送图片,标题和描述。
我不知道我的方法是不是最好的,但是很简单。
我使用UIImagePickerController拍了一张照片,并使用请求的头标签将NSData发送给服务器,以发送图片的数据。
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:@"myServerAddress"]];
[request setHTTPMethod:@"POST"];
[request setHTTPBody:UIImageJPEGRepresentation(picture, 0.5)];
[request setValue:@"image/jpeg" forHTTPHeaderField:@"Content-Type"];
[request setValue:@"myPhotoTitle" forHTTPHeaderField:@"Photo-Title"];
[request setValue:@"myPhotoDescription" forHTTPHeaderField:@"Photo-Description"];
NSURLResponse *response;
NSError *error;
[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
在服务器端,我使用以下代码接收照片:
InputStream is = request.inputStream
def receivedPhotoFile = (IOUtils.toByteArray(is))
def photo = new Photo()
photo.photoFile = receivedPhotoFile //photoFile is a transient attribute
photo.title = request.getHeader("Photo-Title")
photo.description = request.getHeader("Photo-Description")
photo.imageURL = "temp"
if (photo.save()) {
File saveLocation = grailsAttributes.getApplicationContext().getResource(File.separator + "images").getFile()
saveLocation.mkdirs()
File tempFile = File.createTempFile("photo", ".jpg", saveLocation)
photo.imageURL = saveLocation.getName() + "/" + tempFile.getName()
tempFile.append(photo.photoFile);
} else {
println("Error")
}
我不知道将来是否会有问题,但现在在生产环境中工作得很好。