【问题标题】:Send Image in JSON request在 JSON 请求中发送图像
【发布时间】:2014-04-07 07:35:55
【问题描述】:

我正在使用JSONREST api 来使用网络服务。

现在我还需要在请求中发送图像。有可能吗?

如果是,我需要在客户端/服务器端进行哪些更改。

而在我的Java代码中,我应该如何发送图片内容(是否需要单独设置内容类型)?

【问题讨论】:

标签: java android json rest


【解决方案1】:

这样做的方法是将其作为内容发送到 HttpPost 请求中,如下所示

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

您对图像进行字符串编码的方式是执行以下操作。

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

祝你好运

【讨论】:

    【解决方案2】:

    对我有用的示例应用端代码。您可以在一个 valuepair 中发送图像,在另一个 valuepair 中发送 json:(这里“uploadedfile”标签将 valuepair 定义为在 post 功能签入时图像文件在 sd 卡中的路径,其他标签将被视为文本数据)

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

    //发布功能

    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 库需要添加到项目中

    【讨论】:

    • 很少查询..您是否使用包(org.apache.http.NameValuePair)的NameValuePair ... & Constants.all_datas.get(pos).getImage()的返回类型是什么,是String。如果是,则必须将byte[] 转换为String
    • NameValuePair 来自 apache mime4j 库,getImage() 方法返回设备中图像的路径。
    • 如果我需要在一个请求中发送多个图像怎么办。像 {id:"1", images:image1, image2} ?
    • 添加另一个带有“uploadedfile”标签的名称值对。
    【解决方案3】:

    我在我的 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】:

      您不应该发送图像本身,而是可以从中下载图像的网址。

      否则:

      • 你的请求太大了
      • 通常您希望异步加载图像,这只能在内容与其他数据分开的情况下实现。
      • 您很可能无法使用自动 JSON 解析库,如 GSON、Jackson 或集成在 Adnroid SDKAndroidObject

      【讨论】:

      • 图像可以通过 JSON 上传,这是一种标准做法,因此上述所有原因都毫无意义
      • @vishal by 'images are' 你的意思是 Facebook、G+、instagram、soundcloud、twitter 中的图片会立即为你加载内容,或者更确切地说,你的性能很糟糕,并非如此- 您个人选择将它们放入 JSON 的流行应用程序?
      • 仔细阅读关于上传图片而不是下载的问题,对于在应用程序中获取图片,它无疑是链接而不是上传?
      • @vishal 我仍然不确定问题是否与上传有关,但即使是这样,我也不会承担将图像转换为文本格式(比如 x64)的开销,当客户端可以以原始格式传输。此外,您需要处理网络故障并进行重试,而 REST 不适用于此类任务。
      • 这是关于上传因为他正在寻找的代码是用 Java 编写的,而且答案也不难
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-02-16
      • 2018-02-07
      • 1970-01-01
      • 2017-04-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多