2013-03-05 77 views
1

我试着上传一个文件到skydrive中,其余的api在java中。Java skydrive休息文件上传

这里是我的代码:

public void UploadFile(File upfile) { 
    if (upload_loc == null) { 
     getUploadLocation(); 
    } 

    HttpClient client = new DefaultHttpClient(); 
    client.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1); 
    HttpPost post = new HttpPost(upload_loc + "?" + "access_token=" + access_token); 
    try { 

     MultipartEntity mpEntity = new MultipartEntity(null,"A300x",null); 
     ContentBody cbFile = new FileBody(upfile, "multipart/form-data"); 
     mpEntity.addPart("file", cbFile); 

     post.setEntity(mpEntity); 
     System.out.println(post.toString()); 
     HttpResponse response = client.execute(post); 
     BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent())); 
     String line2 = ""; 
     while ((line2 = rd.readLine()) != null) { 
      System.out.println(line2); 
     } 

    } catch (IOException ex) { 
     Logger.getLogger(Onlab.class.getName()).log(Level.SEVERE, null, ex); 
    } 
    client.getConnectionManager().shutdown(); 

} 

但是当我尝试运行它,我得到这个错误:

{ 
"error": { 
    "code": "request_body_invalid", 
    "message": "The request entity body for multipart form-data POST isn't valid. The expected format is:\u000d\u000a--[boundary]\u000d\u000aContent-Disposition: form-data; name=\"file\"; filename=\"[FileName]\"\u000d\u000aContent-Type: application/octet-stream\u000d\u000a[CR][LF]\u000d\u000a[file contents]\u000d\u000a--[boundary]--[CR][LF]" 
} 
} 

我最大的问题是,我没有看到请求本身。我找不到任何可用的toString方法。我尝试了这种强制边界格式,但我也用空的构造函数尝试了它。

我的文件现在是一些文本的txt,我认为边界是主要问题,或者我应该配置一些更多的参数。当我在调试模式下看到变量时,所有内容都与msdn中的指南相同。

我是在新的世界,如果有可能我想保持这个Apache的lib与简单的使用HttpClient和HttpPost类。

在此先感谢,并对我的英语感到抱歉。

编辑: 好吧,长时间睡眠后,我决定尝试PUT方法,而不是POST。代码工作很好,只需要很少的更改:

public void UploadFile(File upfile) { 
    if (upload_loc == null) { 
     getUploadLocation(); 
    } 
    HttpClient client = new DefaultHttpClient(); 
    client.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1); 
    String fname=upfile.getName(); 
    HttpPut put= new HttpPut(upload_loc +"/"+fname+ "?" + "access_token=" + access_token); 
    try { 
     FileEntity reqEntity=new FileEntity(upfile); 
     put.setEntity(reqEntity); 
     HttpResponse response = client.execute(put); 
     BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent())); 
     String line2 = ""; 
     while ((line2 = rd.readLine()) != null) { 
      System.out.println(line2); 
     } 
    } catch (IOException ex) { 
     Logger.getLogger(Onlab.class.getName()).log(Level.SEVERE, null, ex); 
    } 
    client.getConnectionManager().shutdown(); 
} 

但是对于第一个问题还没有答案。

+0

您可以使用wireshark跟踪HTTP请求吗? – hertzsprung 2013-03-05 23:58:29

+0

不是真的,我坐在1000台计算机网络中,如果我尝试使用过滤器仍然嘈杂,我会获得200口袋/秒。我尝试了这个,但痛苦:) – tg44 2013-03-06 00:13:37

+0

如果你知道远程主机,那应该是一个足够好的过滤器?也许尝试[HttpClient的日志记录](http://hc.apache.org/httpcomponents-client-ga/logging.html)? – hertzsprung 2013-03-06 00:42:02

回答

3

两个快速件事:

  1. 你不应该使用重载MultipartEntity构造函数,除非你真的需要。在这种情况下,你将字符集设置为null,这可能不是一个好主意。此外,您的边界分隔符不够复杂。

  2. 您的文件正文内容类型应反映正在上传的实际文件的内容。 multipart-formdata通常用于HTML表单数据,而不是文件。您应该将其更改为'text/plain',或'image/jpeg',或者其他反映文件真实MIME类型的内容。

用于调试REST请求一些伟大的工具 - REST Console (Chrome)REST Client (Firefox)

关于您收到的错误消息的一些快速注释,它实际上有相当多的细节。期待下列参数的服务为文件部分设置发送:

  • 名称:
  • 文件名:
  • 内容类型:应用程序/八位字节流

你可以使用此代码将HTTP客户端设置为大多数:

ContentBody cbFile = new FileBody(
    upfile, 
    "yourFileNameHere", 
    "application/octet-stream", 
    "UTF-8"); 
+0

我尝试了空的Multipart构造函数和这不像现在这样。我尝试了更多的身体类型没有帮助。我认为这是我看不到的一个小问题。 – tg44 2013-03-06 00:31:31

+0

@ tg44 - 你是否也改变了内容类型?请参阅编辑我的答案,这可能也有帮助。 – Perception 2013-03-06 00:40:29

+0

仍然没有工作,顺便说一下,我认为mpEntry.addFile为我做这个。如果我在调试模式下检查变量,我会在post变量中看到filename参数。 – tg44 2013-03-06 00:56:31