使用Volley向服务器发送数据未存入数据库问题排查
问题排查与解决方案
我帮你梳理出几个导致数据无法存入数据库的核心问题,咱们逐一解决:
1. Volley GET请求的参数传递方式错误
Volley的StringRequest使用Request.Method.GET时,getParams()方法不会被执行——GET请求的参数需要直接拼接在URL末尾,或者更推荐改用POST请求(更适合传递JSON这类复杂数据)。你的代码里试图通过getParams()传参,这部分参数根本没发到服务器。
2. 本地服务器地址错误(模拟器专属问题)
在Android模拟器中,localhost指向的是模拟器自身的系统,而不是你的电脑服务器。你需要把URL改成:
private static final String url="http://10.0.2.2/test/addpost.php";
(如果是Genymotion模拟器,用10.0.3.2;或者直接用你电脑的局域网IP,比如192.168.x.x)
3. 前后端数据格式不匹配
你的PHP代码期望接收name、price、id三个独立参数,但Android端传递的是jsonarray参数,两边完全不对接。同时你的PHP代码是处理单个数据插入,但Android端是要批量插入列表里的多个商品,所以需要调整前后端的逻辑:
- 后端:修改PHP代码,接收JSON数组,然后循环插入每条数据
- 前端:确保传递的JSON数组是正确的列表项集合
4. 列表数据获取逻辑错误
你循环里的facultyAdapter.getJSONObject()看起来每次都获取同一个对象?应该根据索引i获取对应位置的商品数据,否则你的JSONArray里的数据是重复或错误的。
修改后的代码示例
Android端(cart.java)
主要改动:改用POST请求、修正服务器地址、修复JSON数组构建逻辑:
public class cart extends AppCompatActivity { Button Add; // 修正服务器地址 private static final String url="http://10.0.2.2/test/addpost.php"; Faculty items; JSONArray myarray; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_cart); Add=findViewById(R.id.btn_basket_pay); dbHandler dbh = new dbHandler(this); dbh.open(); items=new Faculty(); myarray = new JSONArray(); RecyclerView recyclerView = findViewById(R.id.rec); final FacultyAdapter facultyAdapter = new FacultyAdapter(this,dbh.display()); recyclerView.setLayoutManager(new LinearLayoutManager(this,LinearLayoutManager.VERTICAL,false)); recyclerView.setAdapter(facultyAdapter); dbh.close(); // 修复JSON数组构建:获取对应索引的item for (int i = 0; i < facultyAdapter.getItemCount(); i++) { try { // 假设你的FacultyAdapter有getItem方法返回对应位置的Faculty对象 Faculty item = facultyAdapter.getItem(i); JSONObject jsonItem = new JSONObject(); jsonItem.put("id", item.getId()); // 替换成你实际的get方法 jsonItem.put("name", item.getName()); jsonItem.put("price", item.getPrice()); myarray.put(jsonItem); } catch (JSONException e) { e.printStackTrace(); } } Log.d("JSONArray : ", myarray.toString()); Add.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { RequestQueue queue = Volley.newRequestQueue(getApplicationContext()); // 改用POST请求 StringRequest stringRequest=new StringRequest(Request.Method.POST, url, new Response.Listener<String>() { @Override public void onResponse(String response) { Log.d("onResponse", "服务器响应:" + response); Toast.makeText(cart.this,"数据提交成功",Toast.LENGTH_SHORT).show(); } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { Log.e("onErrorResponse", "请求失败:", error); Toast.makeText(cart.this,"请求失败,请检查网络",Toast.LENGTH_SHORT).show(); } }){ @Override public Map<String,String> getParams(){ Map<String,String> params=new HashMap<>(); params.put("jsonarray",myarray.toString()); return params; } // 告诉服务器我们传递的是表单数据 @Override public String getBodyContentType() { return "application/x-www-form-urlencoded; charset=UTF-8"; } }; queue.add(stringRequest); } }); } }
PHP端(addpost.php)
修改为接收JSON数组并批量插入:
<?php if($_SERVER['REQUEST_METHOD']=='POST'){ require_once('dbConnect.php'); $response = array(); // 获取前端传递的JSON数组 $jsonArray = json_decode($_POST['jsonarray'], true); if(!empty($jsonArray)){ mysqli_begin_transaction($cnn); // 开启事务,确保批量插入的原子性 try { foreach($jsonArray as $item){ // 注意:这里要做参数过滤,防止SQL注入! $id = mysqli_real_escape_string($cnn, $item['id']); $name = mysqli_real_escape_string($cnn, $item['name']); $price = mysqli_real_escape_string($cnn, $item['price']); $sql = "INSERT INTO tblcart (id,name,price) VALUES ('$id','$name','$price')"; if(!mysqli_query($cnn,$sql)){ throw new Exception("插入失败:".mysqli_error($cnn)); } } mysqli_commit($cnn); $response = "批量插入成功,共".count($jsonArray)."条数据"; } catch (Exception $e) { mysqli_rollback($cnn); $response = "错误:".$e->getMessage(); } }else{ $response = "没有接收到有效数据"; } echo $response; } ?>
额外注意事项
- 确保你的电脑和模拟器在同一局域网(如果用局域网IP的话)
- 一定要做SQL注入防护:上面的PHP代码用了
mysqli_real_escape_string,更推荐用预处理语句 - 查看Volley的错误日志:在
onErrorResponse里打印完整的错误信息,方便排查网络或服务器问题
内容的提问来源于stack exchange,提问作者user12247057
相关产品推荐
相关产品推荐

