akka-http如何从请求中提取可变长度的查询参数列表
akka-http 提取不定长逗号分隔查询参数方案
场景说明
我们需要从形如 .../employees?city=london,ny,paris 的请求中提取城市列表,城市的数量不固定,且单个参数值用逗号分隔多个取值。
方案1:基础字符串分割实现(轻量,单次使用)
直接将查询参数作为普通字符串提取,自行做分割处理即可,示例代码如下:
import akka.http.scaladsl.server.Directives._ val employeeRoute = path("employees") { // 提取必传的city参数 parameter("city") { cityRaw => // 按逗号分割,同时去除每个值的前后空白、过滤空值 val cityList = cityRaw.split(",").map(_.trim).filter(_.nonEmpty).toList // 此处写后续业务逻辑处理cityList complete(s"查询城市为:${cityList.mkString("、")}") } }
如果需要支持city参数可选,调整为parameterOptional即可:
parameter("city".optional) { cityOpt => val cityList = cityOpt.map(_.split(",").map(_.trim).filter(_.nonEmpty).toList).getOrElse(Nil) // 业务逻辑 }
方案2:自定义参数提取器(高复用,适合多场景使用)
如果项目中多个接口都需要用到逗号分隔的列表参数,可以自定义反序列化器,一次定义全局使用:
import akka.http.scaladsl.unmarshalling.Unmarshaller import akka.http.scaladsl.server.Directives._ // 全局定义逗号分隔字符串转字符串列表的反序列化器 implicit val commaSplitter: Unmarshaller[String, List[String]] = Unmarshaller.strict { rawStr => rawStr.split(",").map(_.trim).filter(_.nonEmpty).toList } // 路由中直接使用,自动完成解析 val employeeRoute = path("employees") { parameter("city".as[List[String]]) { cityList => // 直接拿到解析完成的List[String]类型的城市列表 complete(s"共查询${cityList.size}个城市:$cityList") } }
边界情况处理
上述两种实现都默认过滤了空值,可兼容city=,,london,,shanghai,这类带多余逗号的异常传参场景,符合绝大多数业务需求。
内容的提问来源于stack exchange,提问作者Mandroid
相关产品推荐
相关产品推荐

