Android Volley提交RecyclerView文本参数时JSON转换错误求助
嘿,我来帮你搞定这个问题!首先咱们先拆解一下你遇到的错误:
"Value no of type java.lang.String cannot be converted to JSONObject"
这个错误的核心原因是:服务器返回的响应不是你预期的JSON格式,而是字符串"no",当你尝试用new JSONObject(response)去解析这个字符串时,自然就会抛出转换异常。
为什么会返回"no"?
看你loadDistricts()方法里的代码:你用了Request.Method.GET请求,但同时重写了getParams()方法。这里有个Volley的关键知识点:GET请求不会自动把getParams()里的参数添加到请求中——GET请求的参数需要手动拼在URL末尾,而getParams()是给POST请求准备的,用来传递请求体参数。
这就导致你的服务器根本没收到state参数,所以返回了"no"(应该是服务器找不到对应数据时的默认返回)。
解决方案
方案1:改用POST请求(推荐)
把请求方法改成Request.Method.POST,这样Volley会自动把getParams()里的参数作为请求体发送给服务器,服务器就能正确获取到state参数了:
private void loadDistricts() { RequestQueue queue = Volley.newRequestQueue(States.this); // 把GET请求改为POST请求 StringRequest request = new StringRequest(Request.Method.POST, url_districts, new Response.Listener<String>() { @Override public void onResponse(String response) { // 先打印响应内容,方便排查问题 Log.d("DistrictResponse", response); try { JSONObject obj = new JSONObject(response); JSONArray statesArray = obj.getJSONArray("districts"); for(int i=0; i<statesArray.length(); i++) { JSONObject stateObject = statesArray.getJSONObject(i); String DtHindi = stateObject.getString("DtHindi"); String DTName = stateObject.getString("DTName"); String District11 = stateObject.getString("District11"); District districts = new District(DtHindi, DTName, District11); dist_list.add(districts); districtAdapter.notifyDataSetChanged(); } } catch (JSONException e) { e.printStackTrace(); Toast.makeText(States.this, e.getMessage(), Toast.LENGTH_LONG).show(); } } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { Toast.makeText(States.this, error.getMessage(), Toast.LENGTH_LONG).show(); } }){ @Override protected Map<String, String> getParams() throws AuthFailureError { Map<String, String> map = new HashMap<String, String>(); map.put("state", state.getText().toString()); return map; } }; queue.add(request); }
方案2:如果一定要用GET请求,手动拼接URL参数
把state参数直接拼在url_districts后面,注意要对参数值进行URL编码,避免特殊字符导致的问题:
private void loadDistricts() { RequestQueue queue = Volley.newRequestQueue(States.this); try { // 手动拼接参数到URL,并编码特殊字符 String encodedState = URLEncoder.encode(state.getText().toString(), "UTF-8"); String urlWithParams = url_districts + "?state=" + encodedState; StringRequest request = new StringRequest(Request.Method.GET, urlWithParams, new Response.Listener<String>() { @Override public void onResponse(String response) { Log.d("DistrictResponse", response); try { JSONObject obj = new JSONObject(response); JSONArray statesArray = obj.getJSONArray("districts"); for(int i=0; i<statesArray.length(); i++) { JSONObject stateObject = statesArray.getJSONObject(i); String DtHindi = stateObject.getString("DtHindi"); String DTName = stateObject.getString("DTName"); String District11 = stateObject.getString("District11"); District districts = new District(DtHindi, DTName, District11); dist_list.add(districts); districtAdapter.notifyDataSetChanged(); } } catch (JSONException e) { e.printStackTrace(); Toast.makeText(States.this, e.getMessage(), Toast.LENGTH_LONG).show(); } } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { Toast.makeText(States.this, error.getMessage(), Toast.LENGTH_LONG).show(); } }); queue.add(request); } catch (UnsupportedEncodingException e) { e.printStackTrace(); Toast.makeText(States.this, "参数编码失败", Toast.LENGTH_SHORT).show(); } }
额外需要修正的小问题
在state_recycler_view的长按事件里,你错误地调用了district_recycler_view.findViewHolderForAdapterPosition(position),这会导致空指针异常(因为此时district_recycler_view可能不可见或者没有对应位置的ViewHolder)。如果是要处理州的长按操作,应该改成针对state_recycler_view的逻辑:
@Override public void onLongClick(View view, int position) { // 获取选中的州数据 State selectedState = state_list.get(position); // 根据需求调整后续操作,比如填充到district输入框? // district.setText(selectedState.getSTName()); dist_list.clear(); district_recycler_view.setVisibility(View.GONE); }
排查小技巧
在onResponse方法里先打印服务器返回的response内容,这样你就能清楚看到服务器到底返回了什么,方便快速定位问题:
@Override public void onResponse(String response) { Log.d("ServerResponse", "返回内容:" + response); // 再进行后续解析逻辑 }
内容的提问来源于stack exchange,提问作者Vincent Rabha

