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

GRPC Node.js+MySQL服务端如何序列化Unit供Android客户端接收?

问题分析与解决方案

问题的核心在于服务端返回的数据结构与.proto定义不匹配,导致客户端无法正确解析Unit数据。结合你的代码细节,具体修正步骤如下:

1. 先确认.proto文件的核心定义

首先必须明确UnitFindResponse和Unit的字段类型,这是数据匹配的基础:

场景1:按ID查询应返回单个Unit对象

如果你的查询逻辑是根据ID获取单条数据,.proto应该定义为单个Unit字段:

syntax = "proto3";

message Unit {
  int32 id = 1;
  string name = 2;
}

message UnitFindResponse {
  string result = 1;
  Unit unit = 2; // 单个Unit对象
}

此时服务端的问题是返回了数组类型的unit(res.rows是数组),而不是单个对象。修改Node.js服务端代码:

find: ({request: {id}}, callback) => { 
  cn.executeQuery(`SELECT id, name FROM tb WHERE id=${id}`, (res) => {
    // 从查询结果数组中取出第一个元素(按ID查询应返回单条)
    const targetUnit = res.rows.length > 0 ? res.rows[0] : {};
    callback(null, {
      result: res.result,
      unit: targetUnit // 返回单个对象而非数组
    });
  });
}

场景2:需要返回多个Unit对象

如果业务逻辑允许返回多条数据,.proto需定义为重复字段:

message UnitFindResponse {
  string result = 1;
  repeated Unit unit = 2; // 数组类型的Unit
}

此时客户端代码需要修改为获取列表:

UnitServiceGrpc.UnitServiceBlockingStub stub = UnitServiceGrpc.newBlockingStub(mChannel);
UnitFindRequest request = UnitFindRequest.newBuilder().setId(id).build();
UnitFindResponse reply = stub.find(request);

// 改为获取列表而非单个对象
List<Unit> responseList = reply.getUnitList();
if (!responseList.isEmpty()) {
  Unit response = responseList.get(0); // 按需取第一个元素
}

2. 额外检查事项

  • 字段名一致性:确保服务端返回的对象字段名(id、name)与.proto中Unit的字段名完全匹配,大小写、拼写不能出错。
  • SQL注入风险:你的服务端代码直接拼接SQL参数id=${id}存在注入风险,建议使用参数化查询:
    cn.executeQuery(`SELECT id, name FROM tb WHERE id=?`, [id], (res) => {
      // 后续逻辑不变
    });
    

内容的提问来源于stack exchange,提问作者Luciano Coelho

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 18:22:24