Posting a File and Associated Data to a RESTful WebService preferably as JSON

后端 未结 11 842
没有蜡笔的小新
没有蜡笔的小新 2020-11-22 10:45

This is probably going to be a stupid question but I\'m having one of those nights. In an application I am developing RESTful API and we want the client to send data as JSON

相关标签:
11条回答
  • 2020-11-22 11:29

    Since the only missing example is the ANDROID example, I'll add it. This technique uses a custom AsyncTask that should be declared inside your Activity class.

    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);
        }
    
    }
    

    So, when you want to upload your file just call:

    new UploadFile().execute();
    
    0 讨论(0)
  • 2020-11-22 11:29
    @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
    }
    
    0 讨论(0)
  • 2020-11-22 11:32

    I know that this thread is quite old, however, I am missing here one option. If you have metadata (in any format) that you want to send along with the data to upload, you can make a single multipart/related request.

    The Multipart/Related media type is intended for compound objects consisting of several inter-related body parts.

    You can check RFC 2387 specification for more in-depth details.

    Basically each part of such a request can have content with different type and all parts are somehow related (e.g. an image and it metadata). The parts are identified by a boundary string, and the final boundary string is followed by two hyphens.

    Example:

    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--
    
    0 讨论(0)
  • 2020-11-22 11:40

    FormData Objects: Upload Files Using Ajax

    XMLHttpRequest Level 2 adds support for the new FormData interface. FormData objects provide a way to easily construct a set of key/value pairs representing form fields and their values, which can then be easily sent using the XMLHttpRequest send() method.

    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

    0 讨论(0)
  • 2020-11-22 11:40

    You could try using https://square.github.io/okhttp/ library. You can set the request body to multipart and then add the file and json objects separately like so:

    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());
    
    0 讨论(0)
提交回复
热议问题