2017-05-04 259 views
2

我試圖使用Volley庫向JAVA安卓應用程序發送POST請求到Azure IoT Hub,但是出現此錯誤: BasicNetwork.performRequest:意外的響應代碼400爲https://elca-iot.azure-devices.net/devices/elca-main-device/messages/events?api-version=2016-02-03Android Volley POST請求返回錯誤400(錯誤請求)

要訪問物聯網中心我需要使用一個SAS密鑰,我需要包含在請求的標題。而Android應用程序代碼如下:

RequestQueue queue = Volley.newRequestQueue(c); 
    String url = "https://elca-iot.azure-devices.net/devices/" + deviceId + "/messages/events?api-version=2016-02-03)"; 
    // Request a string response from the provided URL. 
    StringRequest stringRequest = new StringRequest(Request.Method.POST, 
      url, new Response.Listener<String>() { 
     @Override 
     public void onResponse(String response) { 
      onPostResponse(response, c, true); 
     } 
    }, new Response.ErrorListener() { 
     @Override 
     public void onErrorResponse(VolleyError error) { 
      Log.d("Error", error.getMessage()); 
      onPostResponse(error.getMessage(), c, false); 
     } 
    }) { 
     @Override 
     public Map<String, String> getHeaders() throws AuthFailureError { 
      Map<String, String> params = new HashMap<String, String>(); 
      //params.put("Content-Type", "application/xml"); 
      params.put("Authorization", "[My SAS Key]"); 
      params.put("Cache-Control", "no-cache"); 
      return params; 
     } 
     /* 
     @Override 
     public Map<String, String> getParams() throws AuthFailureError { 
      Map<String, String> params = new HashMap<String, String>(); 
      params.put("api-version","2016-02-03"); 
      return params; 
     }*/ 
     @Override 
     public String getBodyContentType() { 
      return "application/text; charset=UTF-8"; 
     } 
     @Override 
     public byte[] getBody(){ 
      return "On".getBytes(); 
     } 
    }; 
    try { 
     Log.d("request", String.valueOf(stringRequest.getMethod()==Request.Method.POST)); 
    } catch (Exception authFailureError) { 
     authFailureError.printStackTrace(); 
    } 
    // Add the request to the RequestQueue. 
    queue.add(stringRequest); 

我試着做郵差使用相同的請求和它的工作,我不知道爲什麼它不與Android應用程序的工作。下面是與郵差的請求的HTTP代碼:

POST /devices/elca-main-device/messages/events?api-version=2016-02-03 HTTP/1.1 
Host: elca-iot.azure-devices.net 
Authorization: [My SAS Key] 
Content-Type: application/x-www-form-urlencoded 
Cache-Control: no-cache 
Postman-Token: d0aa354a-f79c-e574-893a-c259232aa5cb 

on 

編輯:

Screenshot of POSTMAN

+0

你明確地將Content-Type設置爲'application/text',而郵遞員請求表明它應該是'application/x-www-form-urlencoded',這是Volley的默認值。檢查是否刪除,解決問題 – akash93

+0

我試過這個,它不起作用。 –

+0

你會發送一個屏幕截圖從你的帖子男子@MarcosFelipe –

回答

0

看來問題就出在地圖中的價值。 []無法逃脫。

params.put("Authorization", "[My SAS Key]"); 

我所做的是在創建參數的同時,我用UTF-8編碼了key和value。

params.put("Authorization", URLEncoder.encode("[My SAS Key]", "UTF-8")); 

我也在這個問題上掙扎了3天。它可能看起來像一個工作,但它爲我工作。

+0

謝謝,這對我有用! –

0

看來問題是body content type 嘗試getHeadersgetBodyContentType

 @Override 
     public Map<String, String> getHeaders() throws AuthFailureError { 
      Map<String, String> params = new HashMap<String, String>(); 
      //params.put("Content-Type", "application/xml"); 
      params.put("Authorization", "[My SAS Key]"); 
      params.put("Cache-Control", "no-cache"); 
      params.put("Content-Type", "application/x-www-form-urlencoded"); 
      return params; 
     } 
     /* 
     @Override 
     public Map<String, String> getParams() throws AuthFailureError { 
      Map<String, String> params = new HashMap<String, String>(); 
      params.put("api-version","2016-02-03"); 
      return params; 
     }*/ 
     @Override 
     public String getBodyContentType() { 
      return "application/x-www-form-urlencoded; charset=UTF-8"; 
     } 
加入它既
+0

仍然收到相同的錯誤。 –

0

get頭和內容類型

@Override 
    public Map<String, String> getHeaders() throws AuthFailureError { 
     Map<String, String> params = new HashMap<String, String>(); 
     //params.put("Content-Type", "application/xml"); 
     params.put("Authorization", "[My SAS Key]"); 
     params.put("Cache-Control", "no-cache"); 
     params.put("Content-Type", "application/x-www-form-urlencoded"); 
     return params; 
    } 
    /* 
    @Override 
    public Map<String, String> getParams() throws AuthFailureError { 
     Map<String, String> params = new HashMap<String, String>(); 
     params.put("api-version","2016-02-03"); 
     return params; 
    }*/ 
    @Override 
    public String getBodyContentType() { 
     return "application/x-www-form-urlencoded; charset=UTF-8"; 
    } 
+0

沒有任何變化。 –

0

根據天青IoTHub的Common error codes,400錯誤代碼的含義"The body of the request is not valid; for example, it cannot be parsed, or the object cannot be validated."

同時,爲Common parameters and headers的官方REST參考說,"Set the Content-Type header to application/json."

所以請嘗試更改代碼如下。

  1. 添加Content-Type頭中的getHeaders方法。

    params.put("Content-Type", "application/json"); 
    
  2. 更改getBodyContentType方法的利潤歸還值,並在getBody方法使用getBytesUTF-8

    @Override 
    public String getBodyContentType() { 
        return "application/json; charset=UTF-8"; 
    } 
    @Override 
    public byte[] getBody(){ 
        return "On".getBytes("UTF-8"); 
    } 
    
+0

我試過這個,我得到了同樣的錯誤。 –