2014-01-21 213 views
1

我想在Scala中使用HttpURLConnection提交json發佈請求。我跟着跟着兩個教程和生產這樣的:使用HttpURLConnection提交json POST請求

def sendPost(url: String, jsonHash: String) { 
    val conn: HttpURLConnection = new URL(url).openConnection().asInstanceOf[HttpURLConnection] 
    conn.setRequestMethod("POST") 
    conn.setRequestProperty("Content-Type", "application/json") 
    conn.setRequestProperty("Accept", "application/json") 
    conn.setDoOutput(true) 
    conn.connect() 

    val wr = new DataOutputStream(conn.getOutputStream) 
    wr.writeBytes(jsonHash) 
    wr.flush() 
    wr.close() 

    val responseCode = conn.getResponseCode 

    println("Sent: " + jsonHash + " to " + url + " received " + responseCode) 

    val in = new BufferedReader(new InputStreamReader(conn.getInputStream)) 
    var response: String = "" 
    while(response != null) { 
    response = in.readLine() 
    println(response) 
    } 
    in.close() 
} 

它與迴應:

Sent: '{"schedule":"R/2014-02-02T00:00:00Z/PT24H", "name":"Scala-Post-Test", "command":"which scalac", "epsilon":"PT15M", "owner":"[email protected]", "async":false}' to http://localhost:4040/scheduler/iso8601 received 500 

java.io.IOException: Server returned HTTP response code: 500 for URL: http://localhost:4040/scheduler/iso8601 

val in = new BufferedReader(new InputStreamReader(conn.getInputStream)) 

制止,但如果我重建爲curl請求時,它工作正常:

curl -X POST -H 'Content-Type: application/json' -d '{"schedule":"R/2014-02-02T00:00:00Z/PT24H", "name":"Scala-Post-Test", "command":"which scalac", "epsilon":"PT15M", "owner":"[email protected]", "async":false}' http://localhost:4040/scheduler/iso8601 

requirement failed: Vertex already exists in graph Scala-Post-Test 

(這是我期望的)

任何洞察到什麼是錯的?我正在嘗試嗅探數據包以確定不同之處。

(注:我以前在sys.process._放棄)

+1

使用'PrintWriter'(而不是'DataOutputStream')。 –

+1

^^暫時忽略它。雖然這裏通常不使用'DataOutputStream',但在這種情況下沒有任何區別。當你輸出'jsonHash'字符串時,它顯示你的JSON被單引號括起來;這可能是問題。 –

+0

啊哈!你是正確的,單引號導致500. - 或許,nc -l現在看起來是一樣的,但400錯誤請求。搜索仍在繼續。 – Austin

回答

4

問題就在這裏:

Sent: '{"schedule":"R/2014-02-02T00:00:00Z/PT24H", "name":"Scala-Post-Test", "command":"which scalac", "epsilon":"PT15M", "owner":"[email protected]", "async":false}' to http://localhost:4040/scheduler/iso8601 received 500 

你會注意到你的JSON由單引號包圍。這使它無效。

另外值得注意的是,雖然此代碼工作,您正在使用DataOutputStream.writeBytes()輸出您的數據。如果您的字符串包含任何內容但不包含單字節字符,則這會造成問題;它會從每個char中去除高8位(Java使用2字節的字符來保存UTF-16碼點)。

最好使用更適合String輸出的東西。用於輸入的相同技術,例如:

BufferedWriter out = 
    new BufferedWriter(new OutputStreamWriter(conn.getOutputStream)); 
out.write(jsonString); 
out.close();