使用HttpURLConnection提交JSON POST请求

Aus*_*tin 1 java json curl scala httprequest

我正在尝试使用Scala中的HttpURLConnection提交json发布请求。我遵循了两个教程,并制作了:

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()
}
Run Code Online (Sandbox Code Playgroud)

它响应:

Sent: '{"schedule":"R/2014-02-02T00:00:00Z/PT24H", "name":"Scala-Post-Test", "command":"which scalac", "epsilon":"PT15M", "owner":"myemail@thecompany.com", "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
Run Code Online (Sandbox Code Playgroud)

源于

val in = new BufferedReader(new InputStreamReader(conn.getInputStream))
Run Code Online (Sandbox Code Playgroud)

但是如果我根据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":"myemail@thecompany.com", "async":false}' http://localhost:4040/scheduler/iso8601

requirement failed: Vertex already exists in graph Scala-Post-Test
Run Code Online (Sandbox Code Playgroud)

(这是我的期望)

有什么问题的见解吗?我现在尝试嗅探数据包以确定有什么不同。

(注意:我以前已经放弃了sys.process._

Bri*_*ach 5

问题在这里:

Sent: '{"schedule":"R/2014-02-02T00:00:00Z/PT24H", "name":"Scala-Post-Test", "command":"which scalac", "epsilon":"PT15M", "owner":"myemail@thecompany.com", "async":false}' to http://localhost:4040/scheduler/iso8601 received 500
Run Code Online (Sandbox Code Playgroud)

您会注意到您的JSON被单引号引起来。这使其无效。

另外值得注意的是,尽管此代码有效,但您正在使用a DataOutputStream.writeBytes()来输出数据。如果您的字符串中包含除单字节字符以外的任何内容,这将是一个问题。它将每个高位剥离8位char(Java使用2字节字符来保存UTF-16代码点)。

最好使用更适合String输出的东西。用于输入的相同技术,例如:

BufferedWriter out = 
    new BufferedWriter(new OutputStreamWriter(conn.getOutputStream));
out.write(jsonString);
out.close();
Run Code Online (Sandbox Code Playgroud)