984 Stimmen

Senden einer Datei und zugehöriger Daten an einen RESTful WebService vorzugsweise als JSON

In einer Anwendung, die ich entwickle RESTful API und wir wollen den Client, um Daten als JSON senden. Ein Teil dieser Anwendung erfordert, dass der Client eine Datei (normalerweise ein Bild) sowie Informationen über das Bild hochlädt.

Es fällt mir schwer, herauszufinden, wie dies in einer einzigen Anfrage geschieht. Ist es möglich, Base64 die Dateidaten in eine JSON-Zeichenfolge? Muss ich 2 Anfragen an den Server stellen? Sollte ich JSON nicht für diese Aufgabe verwenden?

Als Randbemerkung, wir sind mit Grails auf dem Backend und diese Dienste werden von nativen mobilen Clients (iPhone, Android, etc.) zugegriffen, wenn etwas davon einen Unterschied macht.

3 Stimmen

Wie geht man also am besten vor?

8 Stimmen

Senden Sie die Metadaten im URL-Abfrage-String anstelle von JSON.

0 Stimmen

8voto

lakhan_Ideavate Punkte 265

FormData-Objekte: Dateien hochladen mit Ajax

XMLHttpRequest Level 2 bietet Unterstützung für die neue FormData-Schnittstelle. FormData-Objekte bieten die Möglichkeit, auf einfache Weise eine Reihe von Schlüssel/Wert-Paaren zu erstellen, die Formularfelder und ihre Werte darstellen und dann mit der Methode XMLHttpRequest send() gesendet werden können.

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

6voto

lifeisfoo Punkte 13648

Da das einzige fehlende Beispiel die Android-Beispiel füge ich es hinzu. Diese Technik verwendet eine benutzerdefinierte AsyncTask, die innerhalb Ihrer Activity-Klasse deklariert werden sollte.

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

}

Wenn Sie also Ihre Datei hochladen wollen, rufen Sie einfach an:

new UploadFile().execute();

3voto

Aslam anwer Punkte 715

Ich wollte einige Zeichenfolgen an den Backend-Server senden. Ich habe nicht json mit multipart verwenden, habe ich Anfrage-Parameter verwendet.

@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)

Die Url würde wie folgt aussehen

http://localhost:8080/file/upload?uuid=46f073d0&type=PASSPORT

Ich übergebe zwei Parameter (uuid und Typ) zusammen mit dem Datei-Upload. Hoffe, dies wird helfen, die nicht die komplexe Json-Daten zu senden.

2voto

OneXer Punkte 303

Sie könnten versuchen, Folgendes zu verwenden https://square.github.io/okhttp/ Bibliothek. Sie können den Anforderungskörper auf Multipart einstellen und dann die Datei- und Json-Objekte separat wie folgt hinzufügen:

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

1voto

sunleo Punkte 9602
@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
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X