在一个应用程序中,我正在开发RESTful API,我们希望客户端以JSON形式发送数据。这个应用程序的一部分要求客户端上传一个文件(通常是一个图像)以及关于图像的信息。
我很难在一个请求中找到这种情况。是否可以将文件数据Base64转换为JSON字符串?我是否需要向服务器发送2次帖子?我不应该使用JSON吗?
顺便说一句,我们在后端使用Grails,这些服务是由本地移动客户端(iPhone、Android等)访问的,如果有什么不同的话。
在一个应用程序中,我正在开发RESTful API,我们希望客户端以JSON形式发送数据。这个应用程序的一部分要求客户端上传一个文件(通常是一个图像)以及关于图像的信息。
我很难在一个请求中找到这种情况。是否可以将文件数据Base64转换为JSON字符串?我是否需要向服务器发送2次帖子?我不应该使用JSON吗?
顺便说一句,我们在后端使用Grails,这些服务是由本地移动客户端(iPhone、Android等)访问的,如果有什么不同的话。
当前回答
请确保您有以下导入。当然还有其他标准的进口
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
}
其他回答
@RequestMapping(value = "/uploadImageJson", method = RequestMethod.POST)
public @ResponseBody Object jsongStrImage(@RequestParam(value="image") MultipartFile image, @RequestParam String jsonStr) {
-- use com.fasterxml.jackson.databind.ObjectMapper convert Json String to Object
}
我知道这个线程是相当旧的,但是,我在这里错过了一个选项。如果您有元数据(任何格式),希望将其与要上传的数据一起发送,则可以发出单个多部分/相关请求。
Multipart/Related媒体类型用于由几个相互关联的主体部分组成的复合对象。
您可以查看RFC 2387规范以获得更深入的细节。
基本上,这样的请求的每个部分都可以有不同类型的内容,并且所有部分都以某种方式相关(例如,图像和它的元数据)。各部分由一个边界字符串标识,最后的边界字符串后面跟着两个连字符。
例子:
POST /upload HTTP/1.1
Host: www.hostname.com
Content-Type: multipart/related; boundary=xyz
Content-Length: [actual-content-length]
--xyz
Content-Type: application/json; charset=UTF-8
{
"name": "Sample image",
"desc": "...",
...
}
--xyz
Content-Type: image/jpeg
[image data]
[image data]
[image data]
...
--foo_bar_baz--
由于唯一缺少的例子是ANDROID的例子,我将添加它。 该技术使用一个自定义AsyncTask,应该在Activity类中声明。
private class UploadFile extends AsyncTask<Void, Integer, String> {
@Override
protected void onPreExecute() {
// set a status bar or show a dialog to the user here
super.onPreExecute();
}
@Override
protected void onProgressUpdate(Integer... progress) {
// progress[0] is the current status (e.g. 10%)
// here you can update the user interface with the current status
}
@Override
protected String doInBackground(Void... params) {
return uploadFile();
}
private String uploadFile() {
String responseString = null;
HttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost("http://example.com/upload-file");
try {
AndroidMultiPartEntity ampEntity = new AndroidMultiPartEntity(
new ProgressListener() {
@Override
public void transferred(long num) {
// this trigger the progressUpdate event
publishProgress((int) ((num / (float) totalSize) * 100));
}
});
File myFile = new File("/my/image/path/example.jpg");
ampEntity.addPart("fileFieldName", new FileBody(myFile));
totalSize = ampEntity.getContentLength();
httpPost.setEntity(ampEntity);
// Making server call
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
int statusCode = httpResponse.getStatusLine().getStatusCode();
if (statusCode == 200) {
responseString = EntityUtils.toString(httpEntity);
} else {
responseString = "Error, http status: "
+ statusCode;
}
} catch (Exception e) {
responseString = e.getMessage();
}
return responseString;
}
@Override
protected void onPostExecute(String result) {
// if you want update the user interface with upload result
super.onPostExecute(result);
}
}
所以,当你想上传文件时,只需调用:
new UploadFile().execute();
请确保您有以下导入。当然还有其他标准的进口
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
}
FormData对象:使用Ajax上传文件
XMLHttpRequest Level 2增加了对新的FormData接口的支持。 FormData对象提供了一种方法,可以轻松地构造一组表示表单字段及其值的键/值对,然后可以使用XMLHttpRequest send()方法轻松地发送这些字段。
function AjaxFileUpload() {
var file = document.getElementById("files");
//var file = fileInput;
var fd = new FormData();
fd.append("imageFileData", file);
var xhr = new XMLHttpRequest();
xhr.open("POST", '/ws/fileUpload.do');
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
alert('success');
}
else if (uploadResult == 'success')
alert('error');
};
xhr.send(fd);
}
https://developer.mozilla.org/en-US/docs/Web/API/FormData