2017-05-04 235 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

我试过这个,我得到了同样的错误。 –