Send Image in JSON request

2020-06-18 01:14发布

问题:

I'm using JSON with REST api for using web service.

Now I also need to send Images in request. Is it possible?

If yes, what changes do I need to do on client/server side.

And in my Java code, how should I send the image content (do I need to set a content type separately)?

回答1:

The way to do that would be to send it as content inside a HttpPost request as below

HttpClient client = new DefaultHttpClient();
HttpPost postRequest = new HttpPost(url);
String body = getMessageBody();
try
{
    postRequest.setEntity(new StringEntity(body, "UTF8"));
    postRequest.setHeader("Content-Type", "application/x-www-form-urlencoded");
    HttpResponse response = client.execute(postRequest);
    return response;
} catch (UnsupportedEncodingException e)
{
    e.printStackTrace();
} catch (ClientProtocolException e)
{
    e.printStackTrace();
} catch (IOException e)
{
    e.printStackTrace();
}

The way you would string encode the image would be to do the following.

BufferedImage img = ImageIO.read(new File("filename.jpg"));             
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(img, "jpg", baos);
baos.flush();
Base64 base = new Base64(false);
String encodedImage = base.encodeToString(baos.toByteArray());
baos.close();
encodedImage = java.net.URLEncoder.encode(encodedImage, "ISO-8859-1");

Good luck



回答2:

Sample app side code that worked for me. You can send image in one valuepair and the json in another valuepair: (Here "uploadedfile" tag defines the valuepair as the path of the image file in sd card during checking in post function, other tags will be considered as text data)

List<NameValuePair> values; values = new ArrayList<NameValuePair>();

        System.out.println(Constants.all_datas.get(pos).getBookName());

        values.add(new NameValuePair("uploadedfile",
                Constants.book_image_path
                        + Constants.all_datas.get(pos).getImage()));

        values.add(new NameValuePair("id", Constants.all_datas.get(pos)
                .getBookid() + ""));
        values.add(new NameValuePair("bookname", Constants.all_datas
                .get(pos).getBookName()));
        values.add(new NameValuePair("price", Constants.all_datas.get(
                pos).getPrice()));
        values.add(new NameValuePair("writtername", Constants.all_datas
                .get(pos).getWritterName()));
        values.add(new NameValuePair("publishername",
                Constants.all_datas.get(pos).getPublisherName()));

        post(values);

// Post Function

public void post(final List<NameValuePair> nameValuePairs) {
        // Setting progressDialog properties
        progressDialog = ProgressDialog.show(CustomBookActivity.this, "",
                "Syncing Book Data...");

        mHandler = new Handler();
        // Function to run after thread
        mUpdateResults = new Runnable() {
            public void run() {

                progressDialog.dismiss();

                // Something

            }
        };
        new Thread() {
            @Override
            public void run() {

                HttpClient httpClient = new DefaultHttpClient();
                HttpContext localContext = new BasicHttpContext();
                HttpPost httpPost = new HttpPost(URL);

                try {
                    MultipartEntity entity = new MultipartEntity(
                            HttpMultipartMode.BROWSER_COMPATIBLE);

                    for (int index = 0; index < nameValuePairs.size(); index++) {
                        if (nameValuePairs.get(index).getName()
                                .equalsIgnoreCase("uploadedfile")) {
                            // If the key equals to "uploadedfile", we use FileBody
                            // to transfer the data
                            entity.addPart(
                                    nameValuePairs.get(index).getName(),
                                    new FileBody(new File(nameValuePairs.get(
                                            index).getValue())));
                        } else {
                            // Normal string data
                            entity.addPart(nameValuePairs.get(index).getName(),
                                    new StringBody(nameValuePairs.get(index)
                                            .getValue()));
                        }
                    }

                    httpPost.setEntity(entity);

                    HttpResponse response = httpClient.execute(httpPost,
                            localContext);
                    HttpEntity result_entity = response.getEntity();
                    String htmlResponse = EntityUtils.toString(result_entity);
                    result = htmlResponse;
                    System.out.println("SYNC:::" + result);
                    // server = true;
                } catch (IOException e) {
                    e.printStackTrace();
                    // server = false;
                }

                // dismiss the progress dialog

                // Calling post function
                mHandler.post(mUpdateResults);

            }
        }.start();

    }

Apache Mime4J, HTTPCore, HTTPMime libary jars need to be added to project



回答3:

I use this code in my AsyncTask:

@Override
protected String doInBackground(String... str) {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    mBitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
    String encodedImage = bitmapToString(mBitmap);

    ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
    nameValuePairs.add(new BasicNameValuePair("data", encodedImage));

    try {
        HttpClient httpclient = new DefaultHttpClient();
        HttpPost httppost = new HttpPost(
                "http://192.168.0.107:8300/upload/upload");
        httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
        HttpResponse response = httpclient.execute(httppost);
        String the_string_response = convertResponseToString(response);
        return the_string_response;
    } catch (Exception e) {
        System.out.println("Error in http connection " + e.toString());
        return "error";
    }
}

public String bitmapToString(Bitmap bitmap) {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
    byte[] b = baos.toByteArray();
    String temp = null;
    try {
        System.gc();
        temp = Base64.encodeToString(b, Base64.DEFAULT);
    } catch (Exception e) {
        e.printStackTrace();
    } catch (OutOfMemoryError e) {
        baos = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.JPEG, 50, baos);
        b = baos.toByteArray();
        temp = Base64.encodeToString(b, Base64.DEFAULT);
        Log.e("PictureDemo", "Out of memory error catched");
    }
    return temp;
}

private String convertResponseToString(HttpResponse response)
        throws IllegalStateException, IOException {

    String res = "";
    StringBuffer buffer = new StringBuffer();
    inputStream = response.getEntity().getContent();
    int contentLength = (int) response.getEntity().getContentLength();
    if (contentLength < 0) {
    } else {
        byte[] data = new byte[512];
        int len = 0;
        try {
            while (-1 != (len = inputStream.read(data))) {
                buffer.append(new String(data, 0, len));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            inputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        res = buffer.toString();
    }
    return res;
}


回答4:

You should not send the image itself, but url from which it can be downloaded.

Otherwise:

  • you make the request too big
  • usually you would like to load the images asynchronously, which can only be achieved if the contents are separated from the other data.
  • you most probably would not be able to make use of automatic JSON parsing libraries like GSON, Jackson, or the integrated in the Adnroid SDKAndroidObject