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

Android Studio中根据NIK自动获取数据库姓名的代码报错求助

问题描述

我是Android Studio新手,需要实现填写NIK字段后点击按钮,自动从数据库获取对应姓名的功能。目前编写Java代码时遇到问题,点击按钮出现错误:

java.lang.illegalStateException : Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 2 path $

以下是相关信息:

数据库结构

NIKNAMA
96296Farrasta
94878Alfian

应用视图

应用视图

相关代码

按钮点击事件代码

btnGet.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        NikKry = etNik.getText().toString();
        getNama();
    }
});
private void getNama(){
    APIRequestData armNama = RetroMaster.konekRetrofit().create(APIRequestData.class);
    Call<DataMaster> tampilNama = armNama.ardGetNama(NikKry);

    tampilNama.enqueue(new Callback<DataMaster>() {
        @Override
        public void onResponse(Call<DataMaster> call, Response<DataMaster> response) {
            if (response.isSuccessful()){
                etNama.setText(response.body().getNAMA());
            }
        }
        @Override
        public void onFailure(Call<DataMaster> call, Throwable t) {
            Toast.makeText(TambahActivity.this, "Gagal "+t.getMessage(), Toast.LENGTH_SHORT).show();
        }
    });
}

DataMaster实体类代码

package com.example.crudoracle.Model;
public class DataMaster {
    private String NIK;
    private String NAMA;
    
    public String getNIK() {
        return NIK;
    }
    public void setNIK(String NIK) {
        this.NIK = NIK;
    }
    public String getNAMA() {
        return NAMA;
    }
    public void setNAMA(String NAMA) {
        this.NAMA = NAMA;
    }
}

API请求代码

@FormUrlEncoded
@POST("getnama.php")
Call<DataMaster> ardGetNama(
        @Field("NIK") String NIK
);

PHP接口代码

<?php
include ("koneksi.php");
    $NIK = $_POST['NIK'];
    $query = "SELECT NAMA FROM MASTER_KRY WHERE NIK = '$NIK'";
    $eksekusi = oci_parse($conn, $query);
    $cek = oci_execute($eksekusi);
        $response = array();
        while($ambil = oci_fetch_object($eksekusi)){
            $F["NAMA"] = $ambil->NAMA;
            array_push($response, $F);
        }
echo json_encode($response);
oci_close($conn);
?>

Postman响应结果

[{"NAMA":"Alfian U"}]

问题原因及解决方法

原因分析

错误提示的核心是:Retrofit期望解析单个JSON对象,但服务器返回的是JSON数组。从Postman响应可见,接口返回的是[{"NAMA":"Alfian U"}],是包含单个对象的数组;而Android代码用Call<DataMaster>接收,期望的是单个DataMaster对象,类型不匹配导致报错。

解决方法

两种方案任选其一即可:

方案一:修改Android端代码适配数组响应

  1. 修改API请求接口:将返回类型改为Call<List<DataMaster>>
@FormUrlEncoded
@POST("getnama.php")
Call<List<DataMaster>> ardGetNama(
        @Field("NIK") String NIK
);
  1. 更新getNama()方法的回调逻辑:
private void getNama(){
    APIRequestData armNama = RetroMaster.konekRetrofit().create(APIRequestData.class);
    Call<List<DataMaster>> tampilNama = armNama.ardGetNama(NikKry);

    tampilNama.enqueue(new Callback<List<DataMaster>>() {
        @Override
        public void onResponse(Call<List<DataMaster>> call, Response<List<DataMaster>> response) {
            if (response.isSuccessful() && !response.body().isEmpty()){
                // 取数组第一个元素的姓名值
                etNama.setText(response.body().get(0).getNAMA());
            } else {
                Toast.makeText(TambahActivity.this, "未找到对应NIK的姓名", Toast.LENGTH_SHORT).show();
            }
        }
        @Override
        public void onFailure(Call<List<DataMaster>> call, Throwable t) {
            Toast.makeText(TambahActivity.this, "请求失败:"+t.getMessage(), Toast.LENGTH_SHORT).show();
        }
    });
}

方案二:修改PHP代码返回单个对象

因为业务上一个NIK对应唯一姓名,可直接返回单个对象而非数组:

<?php
include ("koneksi.php");
$NIK = $_POST['NIK'];
$query = "SELECT NAMA FROM MASTER_KRY WHERE NIK = '$NIK'";
$eksekusi = oci_parse($conn, $query);
$cek = oci_execute($eksekusi);

// 只获取第一条结果
$ambil = oci_fetch_object($eksekusi);
$response = array();
if($ambil){
    $response["NAMA"] = $ambil->NAMA;
}

echo json_encode($response);
oci_close($conn);
?>

修改后接口返回{"NAMA":"Alfian U"},Android端现有代码无需修改即可正常解析。

额外建议

你的PHP代码存在SQL注入风险,建议使用绑定变量的方式优化SQL执行:

$query = "SELECT NAMA FROM MASTER_KRY WHERE NIK = :nik";
$eksekusi = oci_parse($conn, $query);
oci_bind_by_name($eksekusi, ':nik', $NIK);
$cek = oci_execute($eksekusi);

内容的提问来源于stack exchange,提问作者Farrasta K S

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 16:45:25