You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android用Volley传数组至服务器时首元素值变为0的解决办法

Android Volley提交ArrayList到服务器时首个元素值异常为0的问题

问题概述

在Android开发中,使用Volley发起POST请求向服务器提交包含sr_id和admission_id的ArrayList数据。Android端日志显示数组内所有数值均正确,但服务器端接收时,仅第一个元素的值被设为0。使用Postman调用同一API则无此异常。

相关截图说明

  • 服务器端数据:接收的列表中第一个元素值为0,其余元素正常
  • Android端数据:本地日志输出的数组内所有元素值均符合预期
  • 请求参数日志:显示Android端构造的参数格式与Postman提交的格式存在差异

核心代码

public class AttendenceShowStdList extends AppCompatActivity {

    ActivityAttendenceShowStdListBinding AttendenceShowStdList;

    ArrayList<AttStdListModel> userlist = new ArrayList<>();
    ArrayList<AllStdListsrIdAdmIdModel> list= new ArrayList<>();
    ArrayList<AllStdListModel> stdlist = new ArrayList<>();

    AttStdListAdapter adapter;
    private DatePickerDialog datePickerDialog;
    private String date,clid,sectionId,yrId,instId,usid,usType,attdate;

    SharedPreferences sharedPreferences_teach;//staff shareprefferece for profile fetch

    private static final String SHARED_PREF_NAME_TEACH="myprefteach";
    private static final String Key_USID_TEACH = "techusid";
    private static final String Key_INSTID_TEACH = "techinstid";
    private static final String Key_USTYPE_TEACH = "techustype";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        AttendenceShowStdList= ActivityAttendenceShowStdListBinding.inflate(getLayoutInflater());
        setContentView(AttendenceShowStdList.getRoot());

        sharedPreferences_teach =getSharedPreferences(SHARED_PREF_NAME_TEACH, Context.MODE_PRIVATE);
        instId=sharedPreferences_teach.getString(Key_INSTID_TEACH,null);
        usid=sharedPreferences_teach.getString(Key_USID_TEACH,null);
        usType=sharedPreferences_teach.getString(Key_USTYPE_TEACH,null);

        //getting data from TakeAttendenceAdapter cardview
        clid=getIntent().getExtras().getString("ClassId");
        sectionId=getIntent().getExtras().getString("sectionId");
        Log.d("cliddd",clid);
        yrId=getIntent().getExtras().getString("YearId");


        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        date = sdf.format(new Date());
        Log.d("dttt",date);


        userlist = (ArrayList<AttStdListModel>) getModel(false);
        adapter = new AttStdListAdapter(this,userlist);
        AttendenceShowStdList.rvstdlist.setAdapter(adapter);
        AttendenceShowStdList.rvstdlist.setLayoutManager(new LinearLayoutManager(getApplicationContext(), LinearLayoutManager.VERTICAL, false));

        getData();


        //toolbar
        setSupportActionBar(AttendenceShowStdList.toolbar);
        Objects.requireNonNull(getSupportActionBar()).setDisplayShowHomeEnabled(true);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);

        AttendenceShowStdList.submit.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                submitAttendence();
            }
        });
    }

    private List<AttStdListModel> getModel(boolean isSelect){
        List<AttStdListModel> list = new ArrayList<>();
        for(int i = 0; i < list.size(); i++){
            AttStdListModel model = new AttStdListModel();
            model.setSelected(isSelect);
            model.setAdmi_id(String.valueOf(list.get(i)));
            list.add(model);
        }
        return list;
    }


    private void getData() {
        RequestQueue queue = Volley.newRequestQueue(getApplicationContext());
        String url1="https://comzent.in/wonderschoolerp/apis/teacher/get_studteachers_att.php";


        StringRequest request = new StringRequest(Request.Method.POST, url1, new com.android.volley.Response.Listener<String>() {
            @SuppressLint("NotifyDataSetChanged")
            @Override
            public void onResponse(String response) {
                try {
                    JSONObject respObj = new JSONObject(response);
                    JSONArray jsonArray5=respObj.getJSONArray("studatt_details");

                    Log.d("std details",jsonArray5.toString());
                    for(int i=0;i<jsonArray5.length();i++){
                        JSONObject jsonObject=jsonArray5.getJSONObject(i);
                        String sr_id=jsonObject.optString("sr_id");
                        String admi_id=jsonObject.optString("admi_id");
                        String stud_name=jsonObject.optString("stud_name");
                        String stud_phone=jsonObject.optString("stud_phone");
                        String stud_email=jsonObject.optString("stud_email");
                        String attd_status=jsonObject.optString("attd_status");
                        String attd_reason=jsonObject.optString("attd_reason");

                        userlist.add(new AttStdListModel(sr_id,admi_id,stud_name,stud_phone,stud_email,
                                attd_status,attd_reason));
                        Log.d("s", String.valueOf(userlist));
                        list.add(new AllStdListsrIdAdmIdModel(sr_id,admi_id,stud_name,stud_phone,stud_email,
                                attd_status,attd_reason));
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
                adapter=new AttStdListAdapter(getApplicationContext(),userlist);
                AttendenceShowStdList.rvstdlist.setAdapter(adapter);
                adapter.notifyDataSetChanged();
            }
        }, new com.android.volley.Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                Toast.makeText(getApplicationContext(), "Fail to get response = " + error, Toast.LENGTH_SHORT).show();
            }
        }) {
            @Override
            protected Map<String, String> getParams() {
                Map<String, String> params = new HashMap<String, String>();

                params.put("get_studattd","1");
                params.put("us_id",usid);
                params.put("inst_id",instId);
                params.put("class_id",clid);
                params.put("sec_id",sectionId);
                params.put("ay_id",yrId);
                params.put("stud_attend_date",date);

                return params;
            }
        };
        queue.add(request);
    }

    //submit attendence
    private void submitAttendence() {
        RequestQueue queue = Volley.newRequestQueue(getApplicationContext());
        String url1="https://comzent.in/wonderschoolerp/apis/teacher/take_studteacher_att.php";

        StringRequest request = new StringRequest(Request.Method.POST, url1, new com.android.volley.Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
                try {
                    JSONObject respObj = new JSONObject(response);
                    String msg=respObj.getString("message");
                    Toast.makeText(AttendenceShowStdList.this, msg, Toast.LENGTH_LONG).show();
                    Log.d("response msg",msg);
                    if(msg.equals("Attendance Generated Successfully..!")){
                        finish();
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        }, new com.android.volley.Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                Toast.makeText(getApplicationContext(), "Fail to get response = " + error, Toast.LENGTH_LONG).show();
                Log.d("error msg", String.valueOf(error));
            }
        }) {
            @Override
            protected Map<String, String> getParams() {
                Map<String, String> params = new HashMap<String, String>();

                ArrayList<String> allstdsrid = new ArrayList<String>();
                for(int i=0; i < list.size(); i++) {
                    allstdsrid.add(String.valueOf(list.get(i).getSr_id()));
                }
                params.put("sr_id", String.valueOf(allstdsrid));
                Log.d("params", String.valueOf(params));
                Log.d("allstudentsrid", String.valueOf(allstdsrid));

                ArrayList<String> allstdadmid = new ArrayList<String>();
                for(int i=0; i < list.size(); i++) {
                    allstdadmid.add(list.get(i).getAdmi_id());
                    params.put("admission_id", String.valueOf(allstdadmid));
                }
                Log.d("allstudentsadmid", String.valueOf(allstdadmid));

                ///selected student list
                ArrayList<String> attstd = new ArrayList<String>();
                for (int i = 0; i < AttStdListAdapter.userlist.size(); i++) {
                    if (AttStdListAdapter.userlist.get(i).getSelected()) {
                        attstd.add(AttStdListAdapter.userlist.get(i).getAdmi_id());
                    }
                }

                params.put("student_attend_submit","1");
                params.put("class_id",clid);
                params.put("sec_id",sectionId);
                params.put("ay_id",yrId);
                params.put("att_status", String.valueOf(attstd));
                Log.d("params", String.valueOf(params));
                params.put("stud_attend_date",date);
                params.put("inst_id",instId);
                params.put("us_id",usid);
                params.put("us_type",usType);

                return params;
            }
        };
        queue.add(request);
    }

    //toolbar back to home
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
        if(item.getItemId()==android.R.id.home){
            finish();
        }
        return super.onOptionsItemSelected(item);
    }
}

问题原因分析

  1. 参数格式错误:代码中直接将ArrayList通过String.valueOf()转为字符串(格式类似[123,456,789]),服务器端无法正确解析这种格式的字符串为数组,导致解析异常,首个元素被设为0。
  2. 重复覆盖参数:处理admission_id时,在循环内部重复调用params.put("admission_id", ...),每次循环都会覆盖同一个key的值,最终仅保留最后一次循环生成的数组字符串,进一步加剧了解析问题。

解决方案

方案1:按表单数组格式提交参数

如果服务器端期望接收表单数组(如PHP后端的$_POST['sr_id']数组格式),需逐个添加数组元素,使用key[]作为参数名:

@Override
protected Map<String, String> getParams() {
    Map<String, String> params = new HashMap<String, String>();

    // 提交sr_id数组
    for(int i=0; i < list.size(); i++) {
        params.put("sr_id[]", list.get(i).getSr_id());
    }

    // 提交admission_id数组
    for(int i=0; i < list.size(); i++) {
        params.put("admission_id[]", list.get(i).getAdmi_id());
    }

    // 提交att_status数组
    for(String admId : attstd) {
        params.put("att_status[]", admId);
    }

    // 其他固定参数
    params.put("student_attend_submit","1");
    params.put("class_id",clid);
    params.put("sec_id",sectionId);
    params.put("ay_id",yrId);
    params.put("stud_attend_date",date);
    params.put("inst_id",instId);
    params.put("us_id",usid);
    params.put("us_type",usType);

    return params;
}

方案2:将数组序列化为JSON字符串提交

如果服务器端支持解析JSON格式参数,可将数组转为JSON字符串后提交:

  1. 先引入Gson依赖(或使用原生JSONArray):
implementation 'com.google.code.gson:gson:2.10.1'
  1. 修改参数构造逻辑:
@Override
protected Map<String, String> getParams() {
    Map<String, String> params = new HashMap<String, String>();
    Gson gson = new Gson();

    ArrayList<String> allstdsrid = new ArrayList<String>();
    for(int i=0; i < list.size(); i++) {
        allstdsrid.add(list.get(i).getSr_id());
    }
    params.put("sr_id", gson.toJson(allstdsrid));

    ArrayList<String> allstdadmid = new ArrayList<String>();
    for(int i=0; i < list.size(); i++) {
        allstdadmid.add(list.get(i).getAdmi_id());
    }
    params.put("admission_id", gson.toJson(allstdadmid));

    ArrayList<String> attstd = new ArrayList<String>();
    for (int i = 0; i < AttStdListAdapter.userlist.size(); i++) {
        if (AttStdListAdapter.userlist.get(i).getSelected()) {
            attstd.add(AttStdListAdapter.userlist.get(i).getAdmi_id());
        }
    }
    params.put("att_status", gson.toJson(attstd));

    // 其他固定参数
    params.put("student_attend_submit","1");
    params.put("class_id",clid);
    params.put("sec_id",sectionId);
    params.put("ay_id",yrId);
    params.put("stud_attend_date",date);
    params.put("inst_id",instId);
    params.put("us_id",usid);
    params.put("us_type",usType);

    return params;
}

同时服务器端需要对应修改,将接收的字符串反序列化为数组处理。

内容的提问来源于stack exchange,提问作者Unnati Sovitkar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 04:20:15