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

如何在Scala Play应用中转换TypeScript传入的Uint8Array对象

如何在Scala Play应用中解析TypeScript发送的Uint8Array对象?

场景说明

TypeScript应用通过HTTP POST请求向Scala Play应用发送包含Uint8Array的对象,示例代码如下:

{stuff: new Uint8Array([0, 1, 2])}

原代码及报错

最初尝试用Play默认的JSON读取器解析,控制器代码如下:

case class StuffData(stuff: List[Byte])

implicit val reads: Reads[StuffData] = Json.reads[StuffData]

def processStuff  = Action.async(parse.json[StuffData]) { request =>
  val stuffData = request.body
  println(stuffData)
}

执行后Play返回如下错误:

For request 'POST /send-stuff'
[Json validation error List((obj.key,List(JsonValidationError(List(error.expected.jsarray),WrappedArray()))))]

解决方案

要在Scala端获取与JavaScript端完全一致的字节数组(逐字节保持原顺序),需自定义JSON读取器,代码如下:

case class StuffData(stuff: List[Byte])

implicit val stuffReader = new Reads[StuffData] {
  def reads(js: JsValue): JsResult[StuffData] = {
    JsSuccess(StuffData(
      (js \ "stuff").as[Map[String, Int]].toList.sortBy(_._1.toInt).map(_._2.toByte)
    ))
  }
}

def processStuff  = Action.async(parse.json[StuffData]) { request =>
  val stuffData = request.body
  println(stuffData)
}

解析逻辑说明

  • JavaScript的Uint8Array序列化为JSON时,会转换为以索引为键、字节值为值的对象结构(而非数组),因此默认的数组读取器无法识别
  • 自定义读取器先将该对象转为Map[String, Int],再按索引键的数值排序,最后将Int值转为Byte(由于Uint8Array的取值范围是0-255,转换为Byte不会丢失信息),最终得到与原Uint8Array顺序一致的List[Byte]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 12:20:50