2015-02-06 47 views
1

我試圖使用REST API將文件上傳到OneDrive。下面的代碼打開OneDrive主機的套接字並從OneDrive doc中的示例中爲其提供有效內容,但OneDrive會返回400狀態,並顯示「無效的動詞」消息。OneDrive REST API爲文件上傳提供了400個無效動詞

我知道訪問令牌是有效的,因爲GET調用起作用。訪問令牌具有以下範圍:wl.offline_accesswl.skydrive_update

我試過GET,PUTTING和POSTING到其他文件夾和GETs工作,但PUT和POST失敗。在使用套接字之前,我嘗試了使用Jersey的WebResource,java的HttpUrlConnection,apache的HttpClientcurl的PUT和POST。 OneDrive根據動詞/庫配對的不同錯誤消息進行響應。

我已經發送請求到本地服務器轉儲有效負載,所以我可以驗證沒有問題的套接字代碼。它從文檔發送確切的消息,但空白替換爲控制字符。

import java.io.PrintWriter; 
import java.net.Socket; 
import javax.net.ssl.SSLSocket; 
import javax.net.ssl.SSLSocketFactory; 
import java.io.BufferedReader; 
import java.io.InputStream; 
import java.io.InputStreamReader; 

public class OneDriveUploadTest { 

    public static void main(String[] args) throws Exception { 
     String accessToken = "..."; 

     // this works 
     // String data = "GET https://apis.live.net/v5.0/me/skydrive/files?access_token="+accessToken+"\r\n\r\n"; 

     // this fails 
     String data = "POST https://apis.live.net/v5.0/me/skydrive/files?access_token="+accessToken+"\r\n\r\n--A300x\r\nContent-Disposition: form-data; name=\"file\"; filename=\"HelloWorld.txt\"\r\n\nContent-Type: application/octet-stream\r\nHello, World!\r\n--A300x--\r\n\r\n"; 

     // this also fails 
     // String data = "PUT https://apis.live.net/v5.0/me/skydrive/files/HelloWorld.txt?access_token="+accessToken+"\r\n\r\nHello, World!\r\n\r\n"; 

     SSLSocketFactory socketFactory = (SSLSocketFactory) SSLSocketFactory.getDefault(); 
     Socket socket = (SSLSocket) socketFactory.createSocket("apis.live.net", 443); 
     PrintWriter sout = new PrintWriter(socket.getOutputStream()); 
     sout.print(data); 
     sout.flush(); 
     InputStream sin = socket.getInputStream(); 
     BufferedReader rd = new BufferedReader(new InputStreamReader(sin)); 
     String line; 
     while ((line = rd.readLine()) != null) { 
      System.out.println("got: " + line); 
     } 
     sin.close(); 
     sout.close(); 
     socket.close(); 
    } 
} 

回答

2

我討厭回答我自己的問題,但我發現了一些可行的方法。此代碼使用Apache的HttpClient通過PUT將文件上傳到OneDrive。

import java.io.File; 
import org.apache.http.client.HttpClient; 
import org.apache.http.impl.client.HttpClients; 
import org.apache.http.HttpResponse; 
import org.apache.http.entity.FileEntity; 
import org.apache.http.client.methods.HttpPut; 

public class OneDriveHttpClientUpload { 
    public static void main(String[] args) throws Exception { 
     String accessToken = "..."; 
     String url = "https://apis.live.net/v5.0/me/skydrive/files/HelloWorld.txt?access_token="+accessToken; 
     HttpClient apClient = HttpClients.createDefault(); 
     HttpPut httpPut = new HttpPut(url); 
     FileEntity file = new FileEntity(new File("testfile.txt")); 
     httpPut.setEntity(file); 
     HttpResponse ret = apClient.execute(httpPut); 
    } 
} 
+1

回答你自己的問題比留下它沒有答案好:)。我只想到你的問題的原因是,當你做PUT或POST時(除非你使用分塊編碼),你應該確保包含Content-Length頭。使用像HttpClient這樣的一個優點是它應該「做對HTTP」,所以你不必擔心它。 – Brad 2015-02-09 16:38:52

+0

你說得對。我發送了來自套接字代碼的HttpClient請求發送的內容,並發現上面的示例中的PUT將在添加「Content-Length」和「Host」頭之後起作用。當請求不能從Jersey和HttpClient工作時,我認爲問題在於他們包含的額外頭文件,包括OneDrive示例停止使用,但我想至少需要其中一些頭文件。 – user2084160 2015-02-09 19:17:22

+0

@ user2084160請問我可以從哪裏獲取訪問令牌? – 2017-08-09 06:18:33