5

У меня есть 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("\r\n--" + strBoundary + "\r\n"); 
request.writeBytes("Content-Disposition: form-data; name=\"" + attachmentName + "\";filename=\"" + imageFileName + "\"" + "\r\n"); 
request.writeBytes("Content-Type: image/jpeg " + "\r\n"); 
request.writeBytes("\r\n"); 
request.write(baos.toByteArray()); 

// **** End content wrapper: 
request.writeBytes("\r\n--"+ strBoundary + "--\r\n"); 

// Flush output buffer: 
request.flush();request.close(); 

Не знаю, как сделать все остальное, но это то, что у меня есть для залпа, который не работает. Я делал Multipart раньше, но не с границей и в этом странном формате.

общественный класс ImageMultiRequest extends StringRequest { final String GRUNDARY = "something"; final Строка crlf = "\ r \ n"; final Строка twoHyphens = "-";

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

} 

ответ

3

этот это мой рабочий пример кода (только для небольших файлов):

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> 
+1

Эй, спасибо за решение, спасло мне массу времени, приветствует вас в вашей честь! (Поднимая стакан) – JPM