我一直在这个站点和其他站点中搜索有关使用JSON正文进行POST请求的解决方案,但是我发现的解决方案似乎对我不起作用。作为参考,这是我使用终端上的curl发出的成功请求:
curl -I -X POST -H "x-app-id:myID" -H "x-app-key:myKey"
-H "Content-Type:application/json" -H "x-remote-user-id:0"
https://trackapi.nutritionix.com/v2/natural/exercise -d '{
$+ "query":"ran 3 miles",
$+ "gender":"female",
$+ "weight_kg":72.5,
$+ "height_cm":167.64,
$+ "age":30
$+ }'
我尝试将其转换为android应用程序的尝试使我陷入凌空,而四处搜索导致我使用以下代码段:
try {
RequestQueue requestQueue = Volley.newRequestQueue(this);
JSONObject jsonBody = new JSONObject();
jsonBody.put("query", "ran 3 miles");
jsonBody.put("gender", "female");
jsonBody.put("weight_kg", 72.5);
jsonBody.put("height_cm", 167.64);
jsonBody.put("age", 30);
final String mRequestBody = jsonBody.toString();
String url = "https://trackapi.nutritionix.com/v2/natural/exercise";
StringRequest stringRequest = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {
@Override
public void onResponse(String response) {
Log.i("LOG_RESPONSE", response);
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.e("LOG_RESPONSE", error.getMessage());
}
}) {
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> params = new HashMap<>();
params.put("x-app-id", "myID");
params.put("x-app-key", "myKey");
params.put("Content-Type", "application/json");
params.put("x-remote-user-id", "0");
return params;
}
@Override
public String getBodyContentType() {
return "application/json; charset=utf-8";
}
@Override
public byte[] getBody() throws AuthFailureError {
try {
return mRequestBody == null ? null : mRequestBody.getBytes("utf-8");
} catch (UnsupportedEncodingException uee) {
VolleyLog.wtf("Unsupported Encoding while trying to get the bytes of %s using %s", mRequestBody, "utf-8");
return null;
}
}
@Override
protected Response<String> parseNetworkResponse(NetworkResponse response) {
String responseString = "";
if (response != null) {
responseString = String.valueOf(response.statusCode);
}
return Response.success(responseString, HttpHeaderParser.parseCacheHeaders(response));
}
};
requestQueue.add(stringRequest);
} catch (JSONException e) {
e.printStackTrace();
}
API规定必须在正文中发送数据,这就是为什么我排除了getParams函数的原因。该代码段似乎对互联网上的其他所有人都有效,但是我一直从中收到400条消息。我也将相同的curl请求转换为邮递员中的请求,并且在那里也很好用。有人对我哪里出问题有任何见识吗?
答案 0 :(得分:0)
我使用这种方法发送请求。
您将使用这种方法。
executePost("https://trackapi.nutritionix.com/v2/natural/exercise", mRequestBody, API_KEY);
请注意,对我来说,如您所见,对于生产环境或较低环境,我有不同的API密钥。因此,您可能不需要API_KEY部分...而是查看标题,您将..:)
public static String executePost(String targetURL, String requestJSON, String apikey) {
HttpURLConnection connection = null;
InputStream is = null;
try {
//Create connection
URL url = new URL(targetURL);
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/json");
//TODO may be prod or preprod api key
if (apikey.equals(Constants.APIKEY_PREPROD)) {
connection.setRequestProperty("Authorization", Constants.APIKEY_PREPROD);
}
if (apikey.equals(Constants.APIKEY_PROD)){
connection.setRequestProperty("Authorization", Constants.APIKEY_PROD);
}
connection.setRequestProperty("Content-Length", Integer.toString(requestJSON.getBytes().length));
connection.setRequestProperty("Content-Language", "en-US");
connection.setUseCaches(false);
connection.setDoOutput(true);
//Send request
DataOutputStream wr = new DataOutputStream (
connection.getOutputStream());
wr.writeBytes(requestJSON);
wr.close();
//Get Response
try {
is = connection.getInputStream();
} catch (IOException ioe) {
if (connection instanceof HttpURLConnection) {
HttpURLConnection httpConn = (HttpURLConnection) connection;
int statusCode = httpConn.getResponseCode();
if (statusCode != 200) {
is = httpConn.getErrorStream();
}
}
}
BufferedReader rd = new BufferedReader(new InputStreamReader(is));
StringBuilder response = new StringBuilder(); // or StringBuffer if Java version 5+
String line;
while ((line = rd.readLine()) != null) {
response.append(line);
response.append('\r');
}
rd.close();
return response.toString();
} catch (Exception e) {
e.printStackTrace();
return null;
} finally {
if (connection != null) {
connection.disconnect();
}
}
}
我还想澄清一些其他内容。此代码在我的本地计算机上使用,不面向客户。代码的安全性不是,对于我的用例来说也不是问题。确保安全存储API密钥。
答案 1 :(得分:0)
确定要在x-app-id
和其他字段中传递正确的ID?因为根据日志,它说"x-app-id" = "myId"
您需要传递应用程序的实际ID。
另外, 您已经在
content-type
中定义了getBodyContentType()
,所以请不要在getHeaders()
中提及它,或者相反。
根据API documentation,x-remote-user-id
不是必需的。也许这就是您的请求返回400错误的原因