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

如何基于Android客户端用户名从MySQL数据库获取指定消息

解决方案:筛选用户专属消息并验证用户有效性

好的,我来帮你一步步搞定这个需求。咱们分两个核心部分来实现:只展示当前用户作为发送方/接收方的消息,以及验证发起请求的用户名是否存在,同时调整你的PHP和Android代码适配需求。

一、修改PHP后端:验证用户+筛选消息

首先,你的现有PHP查询没有添加用户筛选条件,而且需要先验证用户名是否存在于users表中。这里我们用预处理语句来避免SQL注入,同时保证安全性。

1. 完整PHP代码示例

<?php
// 假设你已经建立了MySQL连接($conn变量)
$conn = new mysqli("localhost", "db_username", "db_password", "db_name");
if ($conn->connect_error) {
    die(json_encode(["error" => "Database connection failed"]));
}

// 接收Android端传递的用户名(POST方式更安全)
if (!isset($_POST['username'])) {
    echo json_encode(["error" => "Username parameter missing"]);
    exit;
}
$username = $_POST['username'];

// 第一步:验证用户名是否存在于users表
$checkUserStmt = $conn->prepare("SELECT id FROM users WHERE username = ?");
$checkUserStmt->bind_param("s", $username);
$checkUserStmt->execute();
$userResult = $checkUserStmt->get_result();

if ($userResult->num_rows === 0) {
    // 用户不存在,返回错误信息
    echo json_encode(["error" => "User does not exist"]);
    $checkUserStmt->close();
    $conn->close();
    exit;
}

// 获取当前用户的ID
$user = $userResult->fetch_assoc();
$currentUserId = $user['id'];
$checkUserStmt->close();

// 第二步:查询当前用户作为发送方或接收方的消息
// 注意:假设你的messages表有msg_fk_sender_id(发送方ID)和msg_fk_receiver_id(接收方ID)字段
// 如果你的字段名不同,请自行替换
$msgStmt = $conn->prepare("
    SELECT u.username, m.message 
    FROM messages m
    JOIN users u ON m.msg_fk_sender_id = u.id
    WHERE m.msg_fk_sender_id = ? OR m.msg_fk_receiver_id = ?
");
$msgStmt->bind_param("ii", $currentUserId, $currentUserId);
$msgStmt->execute();
$msgResult = $msgStmt->get_result();

// 整理消息数据为JSON格式
$messages = [];
while ($row = $msgResult->fetch_assoc()) {
    $messages[] = $row;
}

echo json_encode($messages);

// 关闭连接和语句
$msgStmt->close();
$conn->close();
?>

关键说明:

  • 用prepare+bind_param实现预处理,彻底避免SQL注入风险。
  • 先验证用户存在性,不存在则返回明确的错误提示,避免无效查询。
  • 查询时通过OR条件筛选出当前用户是发送方或接收方的所有消息,同时关联users表获取发送方的用户名。

二、修改Android客户端:传递用户名+处理响应

你的现有Android代码用的是GET请求,无法传递用户名参数,需要改成POST请求,同时处理后端返回的错误信息。

1. 修改downloadJSON方法(发送POST请求)

首先,你需要获取当前登录的用户名(比如从SharedPreferences、登录页面Intent传递,这里提供一个示例方法):

// 替换成你实际获取当前用户名的方式
private String getCurrentUsername() {
    // 示例:从SharedPreferences读取登录用户信息
    SharedPreferences prefs = getSharedPreferences("UserSession", MODE_PRIVATE);
    return prefs.getString("current_username", "");
}

然后修改doInBackground方法,发送POST请求并传递用户名:

@Override
protected String doInBackground(Void... voids) {
    try {
        URL url = new URL(urlWebService);
        HttpURLConnection con = (HttpURLConnection) url.openConnection();
        // 设置请求方式为POST
        con.setRequestMethod("POST");
        con.setDoOutput(true);
        con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");

        // 构造POST参数,编码避免乱码
        String username = getCurrentUsername();
        String postData = "username=" + URLEncoder.encode(username, "UTF-8");

        // 写入参数到请求体
        OutputStream os = con.getOutputStream();
        os.write(postData.getBytes());
        os.flush();
        os.close();

        // 读取后端响应
        StringBuilder sb = new StringBuilder();
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(con.getInputStream()));
        String json;
        while ((json = bufferedReader.readLine()) != null) {
            sb.append(json + "\n");
        }
        return sb.toString().trim();
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    }
}

2. 修改loadIntoListView方法(处理错误+展示消息)

需要判断后端返回的是错误信息还是消息列表,给用户明确反馈:

private void loadIntoListView(String json) throws JSONException {
    if (json == null) {
        Toast.makeText(this, "Failed to connect to server", Toast.LENGTH_SHORT).show();
        return;
    }

    // 先检查是否是错误响应(JSON对象格式)
    try {
        JSONObject errorResponse = new JSONObject(json);
        if (errorResponse.has("error")) {
            Toast.makeText(this, errorResponse.getString("error"), Toast.LENGTH_SHORT).show();
            return;
        }
    } catch (JSONException e) {
        // 不是JSON对象,说明是消息数组,继续处理
    }

    // 解析消息数组并展示到ListView
    JSONArray jsonArray = new JSONArray(json);
    String[] messageList = new String[jsonArray.length()];
    for (int i = 0; i < jsonArray.length(); i++) {
        JSONObject obj = jsonArray.getJSONObject(i);
        messageList[i] = obj.getString("username") + ": " + obj.getString("message");
    }
    ArrayAdapter<String> arrayAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, messageList);
    listView.setAdapter(arrayAdapter);
}

额外注意事项:

  • 确保你的AndroidManifest.xml中添加了网络权限:
    <uses-permission android:name="android.permission.INTERNET" />
    
  • AsyncTask在Android 11及以上版本已被废弃,长期来看建议改用Coroutines、Volley或Retrofit来实现网络请求,不过上面的代码可以在当前版本正常运行。

三、数据库表结构确认

确保你的messages表包含以下关键字段(如果字段名不同,自行调整PHP和Android代码中的对应名称):

  • msg_fk_sender_id:发送方用户ID(外键关联users.id)
  • msg_fk_receiver_id:接收方用户ID(外键关联users.id)
  • message:消息内容

内容的提问来源于stack exchange,提问作者Andry Jhonas

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 08:09:09