通过Volley发送带有边界的多部分文件时出现问题



我有一个客户HTTP调用使用标准apache类工作,但我试图创建一个自定义的Volley类来处理这个问题。下面是标准调用的代码:

HttpURLConnection conn = (HttpURLConnection) new URL(strUrl).openConnection();
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setConnectTimeout(30000);
conn.setUseCaches(true);
conn.setRequestMethod("POST");
conn.setRequestProperty("Authorization", "Token " + m_apiKey);
conn.setRequestProperty("Accept", "text/plain , application/json");
conn.setRequestProperty("Connection", "Keep-Alive");
conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + strBoundary);
conn.connect();

// **** Start content wrapper:
DataOutputStream request = new DataOutputStream(conn.getOutputStream());
request.writeBytes("rn--" + strBoundary + "rn");
request.writeBytes("Content-Disposition: form-data; name="" + attachmentName + "";filename="" + imageFileName + """ + "rn");
request.writeBytes("Content-Type: image/jpeg " + "rn");
request.writeBytes("rn");
request.write(baos.toByteArray());
// **** End content wrapper:
request.writeBytes("rn--"+ strBoundary + "--rn");
// Flush output buffer:
request.flush();request.close();

不知道如何做剩下的,但这是我对不工作的排球。我以前做过Multipart,但是没有边界和这种奇怪的格式。

ImageMultiRequest扩展StringRequest最终字符串边界= "某物";最终字符串crlf = "rn";

双连字符= "——";
private final MultipartEntityBuilder entityBuilder = MultipartEntityBuilder.create();
private Response.Listener<String> mListener = null;
private Response.ErrorListener mEListener;
//
private final File mFilePart;
private Map<String, String> parameters;
private Map<String, String> header;
MultipartEntity entity = new MultipartEntity();
protected String apiKey;
ByteArrayOutputStream bos;
public ImageMultiRequest(String apiKey, String url, Listener<String> rListener, ErrorListener eListener, File file) {
    super(Method.POST, url, rListener, eListener);
    setShouldCache(false);
    this.apiKey = apiKey;
    this.bos = bos;
    mListener = rListener;
    mEListener = eListener;
    mFilePart = file;
    entityBuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
    entityBuilder.setBoundary(BOUNDARY);
    buildMultipartEntity();
}
@Override
public String getBodyContentType() {
    return "multipart/form-data; boundary=" + BOUNDARY + "; charset=utf-8";
}
/**
 * Overrides the base class to add the Accept: application/json header
 */
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
    Map<String, String> headers = super.getHeaders();
    if (headers == null || headers.equals(Collections.emptyMap())) {
        headers = new HashMap<String, String>();
    }
    headers.put("Content-Type", "multipart/form-data;boundary=" + BOUNDARY+ "; charset=utf-8");
    headers.put("Connection", "Keep-Alive");
    headers.put("Accept", "text/plain , application/json");
    headers.put("Authorization", "Token " + apiKey);
    return headers;
}
@Override
public byte[] getBody() throws AuthFailureError {
    buildMultipartEntity();
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    try {
        entityBuilder.build().writeTo(bos);
    } catch (IOException e) {
        VolleyLog.e("IOException writing to ByteArrayOutputStream");
    }
    return bos.toByteArray();
}
private void buildMultipartEntity() {
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    entityBuilder.addPart("Content-Type: image/jpeg " + crlf + crlf, new ByteArrayBody(bos.toByteArray(), "car"));
  }
}

=================================================

基于以下答案的解决方案

这是我想到的工作,这可能是与多部分文件嵌入内容体的其他问题

package com.cars.android.common.volley;
import com.android.volley.AuthFailureError;
import com.android.volley.Response;
import com.android.volley.Response.ErrorListener;
import com.android.volley.Response.Listener;
import com.android.volley.VolleyLog;
import com.android.volley.toolbox.StringRequest;
import org.apache.http.HttpEntity;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
public class ImageMultiRequest extends StringRequest {
    final String BOUNDARY = "myboundary";
    private final MultipartEntityBuilder entityBuilder = MultipartEntityBuilder.create();
    HttpEntity entity = new MultipartEntity();
    private Response.Listener<String> mListener = null;
    private Response.ErrorListener mEListener;
    //
    private final File mFilePart;
    protected String apiKey;
    public ImageMultiRequest(String apiKey, String url, Listener<String> rListener, ErrorListener eListener, File file) {
        super(Method.POST, url, rListener, eListener);
        setShouldCache(false);
        this.apiKey = apiKey;
        mListener = rListener;
        mEListener = eListener;
        mFilePart = file;
        entityBuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
        entityBuilder.setBoundary(BOUNDARY);
        ContentType contentType = ContentType.create("image/png");
        entityBuilder.addBinaryBody("file", file, contentType, "car");
        entity = entityBuilder.build();
    }
    @Override
    public String getBodyContentType() {
        return entity.getContentType().getValue();
    }
    /**
     * Overrides the base class to add the Accept: application/json header
     */
    @Override
    public Map<String, String> getHeaders() throws AuthFailureError {
        Map<String, String> headers = super.getHeaders();
        if (headers == null || headers.equals(Collections.emptyMap())) {
            headers = new HashMap<String, String>();
        }
        headers.put("Content-Type", "multipart/form-data;boundary=" + BOUNDARY+ "; charset=utf-8");
        headers.put("Connection", "Keep-Alive");
        headers.put("Accept", "text/plain , application/json");
        headers.put("Authorization", "Token " + apiKey);
        return headers;
    }
    @Override
    public byte[] getBody() throws AuthFailureError {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        try {
            entity.writeTo(bos);
        } catch (IOException e) {
            VolleyLog.e("IOException writing to ByteArrayOutputStream");
        }
        return bos.toByteArray();
    }
}

这是我的工作示例代码(只测试了小文件):

public class FileUploadActivity extends Activity {
    private final Context mContext = this;
    HttpEntity httpEntity;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_file_upload);   
        Drawable drawable = getResources().getDrawable(R.drawable.ic_action_home);
        if (drawable != null) {
            Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();
            ByteArrayOutputStream stream = new ByteArrayOutputStream();
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
            final byte[] bitmapdata = stream.toByteArray();
            String url = "http://10.0.2.2/api/fileupload";
            MultipartEntityBuilder builder = MultipartEntityBuilder.create();
            builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
            // Add binary body
            if (bitmapdata != null) {
                ContentType contentType = ContentType.create("image/png");
                String fileName = "ic_action_home.png";
                builder.addBinaryBody("file", bitmapdata, contentType, fileName);
                httpEntity = builder.build();
                MyRequest myRequest = new MyRequest(Request.Method.POST, url, new Response.Listener<NetworkResponse>() {
                    @Override
                    public void onResponse(NetworkResponse response) {
                        try {                            
                            String jsonString = new String(response.data,
                                    HttpHeaderParser.parseCharset(response.headers));
                            Toast.makeText(mContext, jsonString, Toast.LENGTH_SHORT).show();
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }, new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        Toast.makeText(mContext, error.toString(), Toast.LENGTH_SHORT).show();                        
                    }
                }) {
                    @Override
                    public String getBodyContentType() {
                        return httpEntity.getContentType().getValue();
                    }
                    @Override
                    public byte[] getBody() throws AuthFailureError {
                        ByteArrayOutputStream bos = new ByteArrayOutputStream();
                        try {
                            httpEntity.writeTo(bos);
                        } catch (IOException e) {
                            VolleyLog.e("IOException writing to ByteArrayOutputStream");
                        }
                        return bos.toByteArray();
                    }
                };
                MySingleton.getInstance(this).addToRequestQueue(myRequest);
            }
        }
    }
    ...
}
public class MyRequest extends Request<NetworkResponse>

相关内容

  • 没有找到相关文章

最新更新