通过Volley上传图片时出现错误。具有图像数组和文本数组。

4

以下是解决方案

我正在使用Volley库上传图像。条件是我需要发送:

  1. key1 = 字符串值
  2. key2 = 字符串值
  3. key3{=file} = 图像值,即jpeg、jpg等

这是我正在使用的代码(已经尝试过的部分是注释掉的)-

import com.android.volley.AuthFailureError;
import com.android.volley.NetworkResponse;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.VolleyLog;
import com.android.volley.toolbox.HttpHeaderParser;
import <APP_CLASS IGNORE THIS>.Config

import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.util.CharsetUtils;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * Created by Jimit Patel on 26/09/15.
 */
public class MyClass extends Request<String> {

    private static final String TAG = MyClass.class.getSimpleName();
    private static final boolean IS_DEBUG = true;
    private static final String FILE_PART_NAME = "file";

    private MultipartEntityBuilder multipartEntityBuilder;
    private Response.Listener<String> mListener;
    private Map<String, String> mRequestParams;
    private File file;
    private String tokenId;

    public AddWardrobeRequest(int method, String url, Response.Listener<String> listener, Response.ErrorListener errorListener,
                              File file, Map<String, String> requestParams, String tokenId) {
        super(method, url, errorListener);

        mListener = listener;
        this.file = file;
        this.tokenId = tokenId;
        mRequestParams = requestParams;

        buildMultipartEntity();
    }

    @Override
    protected Response<String> parseNetworkResponse(NetworkResponse response) {
        return Response.success("Result", getCacheEntry());
    }

    @Override
    protected void deliverResponse(String response) {
        mListener.onResponse(response);
    }

    @Override
    public Map<String, String> getHeaders() throws AuthFailureError {
        Map<String, String> headers = super.getHeaders();

        if (headers == null
                || headers.equals(Collections.emptyMap())) {
            headers = new HashMap<>();
        }
        headers.put(Config.HEADER_AUTHORIZATION, "Bearer " + tokenId);
//        headers.put("Accept", "application/json");
//        headers.put("Content-Type", "multipart/form-data");

        return headers;
    }

    @Override
    public String getBodyContentType() {
        String contentTypeHeader = multipartEntityBuilder.build().getContentType().getValue();
        return contentTypeHeader;
    }

    @Override
    public byte[] getBody() throws AuthFailureError {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        try {
            multipartEntityBuilder.build().writeTo(bos);
        } catch (IOException e) {
            VolleyLog.e("IOException writing to ByteArrayOutputStream bos, building the multipart request.");
        }

        return bos.toByteArray();
    }

    private void buildMultipartEntity() {
        multipartEntityBuilder = MultipartEntityBuilder.create();
        multipartEntityBuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
//        multipartEntityBuilder.setLaxMode().setBoundary("xx").setCharset(Charset.forName("UTF-8"));
//        try {
//            multipartEntityBuilder.setCharset(CharsetUtils.get("UTF-8"));
//        } catch (UnsupportedEncodingException e) {
//            e.printStackTrace();
//        }
        multipartEntityBuilder.addPart(FILE_PART_NAME, new FileBody(file) );
        Set<String> keys = mRequestParams.keySet();
        for (String key : keys)
            multipartEntityBuilder.addTextBody(key, mRequestParams.get(key));
    }
}

以下是我遇到的错误。
Process: com.stylabs.APP.app, PID: 12804
java.lang.NoSuchFieldError: No static field INSTANCE of type Lorg/apache/http/message/BasicHeaderValueFormatter; in class Lorg/apache/http/message/BasicHeaderValueFormatter; or its superclasses (declaration of 'org.apache.http.message.BasicHeaderValueFormatter' appears in /system/framework/ext.jar)
        at org.apache.http.entity.ContentType.toString(ContentType.java:153)
        at org.apache.http.entity.mime.MultipartFormEntity.<init>(MultipartFormEntity.java:53)
        at org.apache.http.entity.mime.MultipartEntityBuilder.buildEntity(MultipartEntityBuilder.java:236)
        at org.apache.http.entity.mime.MultipartEntityBuilder.build(MultipartEntityBuilder.java:240)
        at MyClass.getBody(MyClass.java:90)
        at com.android.volley.toolbox.HurlStack.addBodyIfExists(HurlStack.java:253)
        at com.android.volley.toolbox.HurlStack.setConnectionParametersForRequest(HurlStack.java:227)
        at com.android.volley.toolbox.HurlStack.performRequest(HurlStack.java:107)
        at com.android.volley.toolbox.BasicNetwork.performRequest(BasicNetwork.java:96)
        at com.android.volley.NetworkDispatcher.run(NetworkDispatcher.java:112)

请帮助我。先行致谢!

解决方案

尽管我被标记为重复,但我在那里没有找到任何解决方案。最终我还是找到了我所缺失的东西。我在安卓上重新阅读了文档,可以在此处找到 - http://developer.android.com/preview/behavior-changes.html#behavior-apache-http-client

因此,我删除了所有这些包括 httpcore, httpmime, httpclient 等的 httpcomponents。现在不知道在 stack overflow 上建议的哪个是正确的,也许昨天它们都是对的,但现在不再适用于 M 预览 +。 取而代之,请添加:

android {
   useLibrary 'org.apache.http.legacy'
}

之前使用过的请求类已更改如下 -

import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    
    import com.android.volley.AuthFailureError;
    import com.android.volley.NetworkResponse;
    import com.android.volley.Request;
    import com.android.volley.Response;
    import com.android.volley.VolleyError;
    import <APP_CLASS IGNORE THIS>.Config
    
    import java.io.ByteArrayInputStream;
    import java.io.ByteArrayOutputStream;
    import java.io.DataOutputStream;
    import java.io.File;
    import java.io.IOException;
    import java.util.Collections;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.Set;
    
    /**
     * Created by Jimit Patel on 26/09/15.
     */
    public class MyClass extends Request<String> {
    
        private static final String TAG = AddWardrobeRequest.class.getSimpleName();
        private static final boolean IS_DEBUG = true;

// This is the key for the file to be sent
        private static final String FILE_PART_NAME = "file";
    
        private Response.Listener<String> mListener;
        private Response.ErrorListener mErrorListener;
        private Map<String, String> mRequestParams;
        private File file;
        private String tokenId;
    
        private final String BOUNDARY = "3i2ndDfv2rTHiSisAbouNdArYfORhtTPEefj3q2f";
        private final String CRLF = "\r\n";
        private final int MAX_BUFFER_SIZE = 1024 * 1024;
    
        public MyClass(int method, String url, Response.Listener<String> listener, Response.ErrorListener errorListener,
                                  File file, Map<String, String> requestParams, String tokenId) {
            super(method, url, errorListener);
    
            mListener = listener;
            mErrorListener = errorListener;
            this.file = file;
            this.tokenId = tokenId;
            mRequestParams = requestParams
        }
    
        @Override
        protected Response<String> parseNetworkResponse(NetworkResponse response) {
            return Response.success(new String(response.data), getCacheEntry());
        }
    
        @Override
        protected void deliverResponse(String response) {
            mListener.onResponse(response);
        }
    
        @Override
        public Map<String, String> getHeaders() throws AuthFailureError {
            Map<String, String> headers = super.getHeaders();
    
            if (headers == null
                    || headers.equals(Collections.emptyMap())) {
                headers = new HashMap<>();
            }
            headers.put(Config.HEADER_AUTHORIZATION, "Bearer " + tokenId);
            headers.put("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);
    
            return headers;
        }
    
        @Override
        protected VolleyError parseNetworkError(VolleyError volleyError) {
            return super.parseNetworkError(volleyError);
        }
    
        @Override
        public void deliverError(VolleyError error) {
            mErrorListener.onErrorResponse(error);
        }
    
        @Override
        public byte[] getBody() throws AuthFailureError {
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
    DataOutputStream dos = new DataOutputStream(bos);
    try {
        PrintWriter pw = new PrintWriter(new OutputStreamWriter(dos, "UTF-8"));

        Set<String> keys = mRequestParams.keySet();


pw.append(CRLF);
        for (String key : keys) {
            pw.append("--" + BOUNDARY + CRLF);
            pw.append("Content-Disposition: form-data; ");
            pw.append("name=\"" + key + "\"" + CRLF + CRLF + mRequestParams.get(key) + CRLF);
        }

        pw.append("--" + BOUNDARY + CRLF);
        pw.append("Content-Disposition: form-data; ");
        pw.append("name=\"" + FILE_PART_NAME + "\"; filename=\"" + file.getName() + "\"" + CRLF + CRLF);

        dos.writeBytes(pw.toString());
        pw.flush();
        FileInputStream inputStream = new FileInputStream(file);
        int bytesAvailable = inputStream.available();
        int bufferSize = Math.min(bytesAvailable, MAX_BUFFER_SIZE);
        byte[] buffer = new byte[bufferSize];
        int bytesRead;
        while ((bytesRead = inputStream.read(buffer)) != -1)
            dos.write(buffer, 0, bytesRead);

        dos.writeBytes(CRLF + "--" + BOUNDARY + "--" + CRLF);
    } catch (IOException e) {
        e.printStackTrace();
    }
    return bos.toByteArray();
        }
    }

最终我得到了所需的正确响应。希望这能帮助像我一样遇到问题的其他人。 :)
1个回答

1

对不起伙计,我已经找到了解决方案,不想再添加更多的库... 无论如何,还是谢谢。 - Jimit Patel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接