Android Volley GET请求返回406错误,对应curl请求正常
问题分析与解决方案
首先,你的核心问题出在请求头和请求体的混淆,以及缺少必要的Accept请求头,这直接导致了服务器返回406错误(服务器无法提供客户端可接受的响应格式)。
错误点拆解
- 请求头错误放入请求体:你把
Content-Type、Auth-Token这些本该放在请求头里的字段,错误地添加到了请求体的JSONObject中。服务器无法识别这些作为业务参数的头信息,导致认证和格式校验失败。 - 缺少
Accept请求头:406错误的本质是服务器不知道该返回什么格式的响应给客户端,添加Accept: application/json头可以明确告诉服务器我们只接受JSON格式的响应。 - GET请求带请求体的Volley处理:虽然HTTP标准允许GET请求带请求体,但Volley的
JsonObjectRequest需要正确区分请求头和请求体,不能混在一起。
修正后的代码实现
首先,拆分请求头和请求体,重写getHeaders方法来设置头信息,请求体只保留业务参数:
// 1. 构造仅包含业务参数的请求体 JSONObject requestBody = new JSONObject(); try { requestBody.put("detail", "Y"); } catch(JSONException e) { Log.d(TAG, e.getMessage()); } // 2. 创建JsonObjectRequest并重写getHeaders方法设置请求头 JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, searchRequest, requestBody, new Response.Listener<JSONObject>() { @Override public void onResponse(JSONObject response) { searchDialog.dismiss(); Log.d(TAG, String.valueOf(response)); } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { searchDialog.dismiss(); // 你的错误处理逻辑保持不变 if( error instanceof NetworkError) { Log.d(TAG, error.toString()); Log.d(TAG, "Request to "+searchRequest+" FAILED..."); } else if( error instanceof ServerError) { Log.d(TAG, "Request to "+searchRequest+" FAILED..."); Log.d(TAG, error.toString()); } else if( error instanceof AuthFailureError) { Log.d(TAG, error.toString()); Log.d(TAG, "Request to "+searchRequest+" FAILED..."); } else if( error instanceof ParseError) { Log.d(TAG, error.toString()); Log.d(TAG, "Request to "+searchRequest+" FAILED..."); } else if( error instanceof NoConnectionError) { Log.d(TAG, error.toString()); Log.d(TAG, "Request to "+searchRequest+" FAILED..."); } else if( error instanceof TimeoutError) { Log.d(TAG, error.toString()); Log.d(TAG, "Request to "+searchRequest+" FAILED..."); } } }) { // 重写getHeaders方法,设置正确的请求头 @Override public Map<String, String> getHeaders() throws AuthFailureError { Map<String, String> headers = new HashMap<>(); headers.put("Content-Type", "application/json"); headers.put("Auth-Token", token); headers.put("Accept", "application/json"); // 关键:添加这个头解决406错误 return headers; } }; RequestQueue searchRequestQueue = Volley.newRequestQueue(MainActivity.this); searchRequestQueue.add(jsonObjectRequest);
为什么登录请求能成功?
你的登录请求是POST方法,服务器对POST请求的参数校验可能更宽松,允许Content-Type出现在请求体中,但GET请求的服务器逻辑通常更严格,必须严格区分请求头和请求体,所以登录请求的巧合成功不能作为参考。
额外注意事项
- 确认服务器确实支持GET请求带请求体(你的curl请求成功说明是支持的),如果后续还是有问题,可以考虑把请求改为POST(如果API允许的话),因为GET带请求体并不是所有服务器框架都推荐的做法。
- 检查
token变量是否正确传递,确保和curl中使用的token完全一致。
内容的提问来源于stack exchange,提问作者DevOpsSauce
相关产品推荐
相关产品推荐

