2013-04-16 28 views
0

我正在使用google-http-client for java來處理Android上的http連接。使用GoogleHttpClient發送multipart/form-data

一切都是HunkyDori到目前爲止直到試圖發送一個multipart/form-data內容。

我有點卡住了,我在考慮修改MultipartContent類來創建我自己的MultipartFormContent版本。

我需要一個版本的MultipartEntity這將用途不同的工作,如:

HttpClient httpclient = new DefaultHttpClient(); 
HttpPost httppost = new HttpPost(url); 

FileBody bin = new FileBody(new File(fileName)); 
StringBody comment = new StringBody("Filename: " + fileName); 

MultipartEntity reqEntity = new MultipartEntity(); 
reqEntity.addPart("bin", bin); 
reqEntity.addPart("comment", comment); 
httppost.setEntity(reqEntity); 

HttpResponse response = httpclient.execute(httppost); 
HttpEntity resEntity = response.getEntity(); 

從閱讀周圍,multipart/relativemultipart/form之間,唯一的區別是,一個打印出來的時候增加了名字?

任何人都有關於使用MultipartContent類來支持'name'字段的想法。

問候。

回答

0

好吧,我創建了基於斷MultipartContent類的以下類:

/** 
* Serializes MIME multipart content to the form-data standard. Adapated from {@link MultipartContent} 
* <p/> 
* <p> 
* By default the media type is {@code "multipart/form-data; boundary=__END_OF_PART__"}, but this may 
* be customized by calling {@link #setMediaType(HttpMediaType)}, {@link #getMediaType()}, or 
* {@link #setBoundary(String)}. 
* </p> 
* <p/> 
* <p> 
* Implementation is not thread-safe. 
* </p> 
* 
* @author Christopher Jenkins 
* @since 1.15 
*/ 
public class MultipartFormContent extends AbstractHttpContent 
{ 

    static final String NEWLINE = "\r\n"; 
    private static final String TWO_DASHES = "--"; 
    /** 
    * Parts of the HTTP multipart request. 
    */ 
    private ArrayList<Part> parts = new ArrayList<Part>(); 

    public MultipartFormContent() 
    { 
     super(new HttpMediaType("multipart/form-data").setParameter("boundary", "__END_OF_PART__")); 
    } 

    public void writeTo(OutputStream out) throws IOException 
    { 
     Writer writer = new OutputStreamWriter(out, getCharset()); 
     String boundary = getBoundary(); 

     //TODO use http headers again like MultipartContent 
     HttpHeaders headers; 
     String contentDisposition = null; 
     HttpContent content = null; 
     StreamingContent streamingContent = null; 
     for (Part part : parts) 
     { 
      // analyze the headers 
      headers = new HttpHeaders().setAcceptEncoding(null); 
      if (part.headers != null) 
       headers.fromHttpHeaders(part.headers); 
      headers.setContentEncoding(null) 
        .setUserAgent(null) 
        .setContentType(null) 
        .setContentLength(null) 
        .set("Content-Transfer-Encoding", null); 

      // Write disposition 
      if (part.getName() != null) 
      { 
       contentDisposition = String.format("form-data; name=\"%s\"", part.name); 
       // Do we have a filename? 
       // Then add to the content dispos 
       if (part.filename != null) 
        contentDisposition += String.format("; filename=\"%s\"", part.filename); 
       headers.set("Content-Disposition", contentDisposition); 
      } 

      // analyze the content 
      content = part.content; 
      streamingContent = null; 
      if (content != null) 
      { 
       headers.setContentType(content.getType()); 
       headers.set("Content-Transfer-Encoding", Arrays.asList("binary")); 
       final HttpEncoding encoding = part.encoding; 
       if (encoding == null) 
        streamingContent = content; 
       else 
       { 
        headers.setContentEncoding(encoding.getName()); 
        streamingContent = new HttpEncodingStreamingContent(content, encoding); 
       } 
      } 

      // write separator 
      writer.write(TWO_DASHES); 
      writer.write(boundary); 
      writer.write(NEWLINE); 
      // Write Headers 
      HttpHeaders.serializeHeadersForMultipartRequests(headers, null, null, writer); 
      // write content 
      if (streamingContent != null) 
      { 
       writer.write(NEWLINE); 
       writer.flush(); 
       streamingContent.writeTo(out); 
       writer.write(NEWLINE); 
      } 
     } 
     // write end separator 
     writer.write(TWO_DASHES); 
     writer.write(boundary); 
     writer.write(TWO_DASHES); 
     writer.write(NEWLINE); 
     writer.flush(); 
    } 

    @Override 
    public boolean retrySupported() 
    { 
     for (Part part : parts) 
     { 
      if (!part.content.retrySupported()) 
      { 
       return false; 
      } 
     } 
     return true; 
    } 

    @Override 
    public MultipartFormContent setMediaType(HttpMediaType mediaType) 
    { 
     super.setMediaType(mediaType); 
     return this; 
    } 

    /** 
    * Returns an unmodifiable view of the parts of the HTTP multipart request. 
    */ 
    public final Collection<Part> getParts() 
    { 
     return Collections.unmodifiableCollection(parts); 
    } 

    /** 
    * Sets the parts of the HTTP multipart request. 
    * <p/> 
    * <p> 
    * Overriding is only supported for the purpose of calling the super implementation and changing 
    * the return type, but nothing else. 
    * </p> 
    */ 
    public MultipartFormContent setParts(Collection<Part> parts) 
    { 
     this.parts = new ArrayList<Part>(parts); 
     return this; 
    } 

    /** 
    * Adds an HTTP multipart part. 
    * <p/> 
    * <p> 
    * Overriding is only supported for the purpose of calling the super implementation and changing 
    * the return type, but nothing else. 
    * </p> 
    */ 
    public MultipartFormContent addPart(Part part) 
    { 
     parts.add(Preconditions.checkNotNull(part)); 
     return this; 
    } 

    /** 
    * Returns the boundary string to use. 
    */ 
    public final String getBoundary() 
    { 
     return getMediaType().getParameter("boundary"); 
    } 

    /** 
    * Sets the boundary string to use. 
    * <p/> 
    * <p> 
    * Defaults to {@code "__END_OF_PART__"}. 
    * </p> 
    * <p/> 
    * <p> 
    * Overriding is only supported for the purpose of calling the super implementation and changing 
    * the return type, but nothing else. 
    * </p> 
    */ 
    public MultipartFormContent setBoundary(String boundary) 
    { 
     getMediaType().setParameter("boundary", Preconditions.checkNotNull(boundary)); 
     return this; 
    } 

    /** 
    * Single part of a multi-part request. 
    * <p/> 
    * <p> 
    * Implementation is not thread-safe. 
    * </p> 
    */ 
    public static final class Part 
    { 

     /** 
     * Name of this FormPart 
     */ 
     private String name; 
     /** 
     * FileName of the File being uploaded or {@code null} for none. 
     */ 
     private String filename; 
     /** 
     * HTTP header or {@code null} for none. 
     */ 
     private HttpHeaders headers; 
     /** 
     * HTTP content or {@code null} for none. 
     */ 
     private HttpContent content; 
     /** 
     * HTTP encoding or {@code null} for none. 
     */ 
     private HttpEncoding encoding; 

     public Part() 
     { 
      this(null, null); 
     } 

     /** 
     * @param headers HTTP headers or {@code null} for none 
     * @param content HTTP content or {@code null} for none 
     */ 
     public Part(String name, HttpContent content) 
     { 
      setName(name); 
      setContent(content); 
     } 

     /** 
     * Returns the HTTP content or {@code null} for none. 
     */ 
     public HttpContent getContent() 
     { 
      return content; 
     } 

     /** 
     * Sets the HTTP content or {@code null} for none. 
     */ 
     public Part setContent(HttpContent content) 
     { 
      this.content = content; 
      if (content instanceof FileContent) 
      { 
       final File file = ((FileContent) content).getFile(); 
       if (file != null && file.exists()) 
       { 
        setFilename(file.getName()); 
       } 
      } 
      return this; 
     } 

     public String getName() 
     { 
      return name; 
     } 

     public Part setName(final String name) 
     { 
      this.name = name; 
      return this; 
     } 

     public String getFilename() 
     { 
      return filename; 
     } 

     /** 
     * Set the HTTP form-part filename or null for none. 
     * 
     * @param filename 
     */ 
     public Part setFilename(final String filename) 
     { 
      this.filename = filename; 
      return this; 
     } 

     /** 
     * Returns the HTTP headers or {@code null} for none. 
     */ 
     public HttpHeaders getHeaders() 
     { 
      return headers; 
     } 

     /** 
     * Sets the HTTP headers or {@code null} for none. 
     */ 
     public Part setHeaders(final HttpHeaders headers) 
     { 
      this.headers = headers; 
      return this; 
     } 

     /** 
     * Returns the HTTP encoding or {@code null} for none. 
     */ 
     public HttpEncoding getEncoding() 
     { 
      return encoding; 
     } 

     /** 
     * Sets the HTTP encoding or {@code null} for none. 
     */ 
     public Part setEncoding(HttpEncoding encoding) 
     { 
      this.encoding = encoding; 
      return this; 
     } 
    } 
} 

這是爲我工作,我使用針對Cloudinary。