使用Akka HTTP(正式名称为Spray)的GET请求的查询参数

使用Akka HTTP(正式名称为Spray)的GET请求的查询参数,akka,spray,akka-http,Akka,Spray,Akka Http,Akka HTTP(正式名称为Spray)的一个特性是它能够自动地将json中的数据来回封送和解封送到case类中,等等。我已经成功地使其正常工作 目前,我正在尝试创建一个HTTP客户端,该客户端使用查询参数执行GET请求。当前代码如下所示: val httpResponse: Future[HttpResponse] = Http().singleRequest(HttpRequest( uri = s"""http://${config.getString("http.serve

Akka HTTP(正式名称为Spray)的一个特性是它能够自动地将json中的数据来回封送和解封送到case类中,等等。我已经成功地使其正常工作

目前,我正在尝试创建一个HTTP客户端,该客户端使用查询参数执行GET请求。当前代码如下所示:

val httpResponse: Future[HttpResponse] =
  Http().singleRequest(HttpRequest(
    uri = s"""http://${config.getString("http.serverHost")}:${config.getInt("http.port")}/""" +
          s"query?seq=${seq}" +
          s"&max-mismatches=${maxMismatches}" +
          s"&pam-policy=${pamPolicy}"))
val params = Map("foo" -> "bar", "hello" -> "world")
HttpRequest(Uri(hostAndPath).withQuery(params))
嗯,那可不太好看。如果我能传入一个包含查询参数的case类,并让Akka-HTTP自动生成查询参数,就像对json一样,那就太好了。(另外,Akka HTTP的服务器端有一种优雅的方式来解析GET查询参数,因此人们会认为它也有一种优雅的方式来生成它们。)

我想做如下事情:

val httpResponse: Future[HttpResponse] =
  Http().singleRequest(HttpRequest(
    uri = s"""http://${config.getString("http.serverHost")}:${config.getInt("http.port")}/query""",
    entity = QueryParams(seq = seq, maxMismatches = maxMismatches, pamPolicy = pamPolicy)))
只是,上述方法实际上不起作用

我想要的东西是否可以通过Akka HTTP实现?还是我只需要用传统的方式做事?也就是说,显式地生成查询参数,就像我在上面的第一个代码块中所做的那样


(我知道,如果我把它从GET改为POST,我可能会让它更像我希望的那样工作,因为这样我就可以将POST请求的内容从case类自动转换为json,但我真的不想在这里这么做。)

显然,这可以通过改变Akka HTTP的扩展功能来实现,但对于您所需要的(只是构建查询字符串的一种更整洁的方式),您可以通过一些scala乐趣来实现:

type QueryParams = Map[String, String]

object QueryParams {

  def apply(tuples: (String, String)*): QueryParams = Map(tuples:_*)
}

implicit class QueryParamExtensions(q: QueryParams) {

  def toQueryString = "?"+q.map{
    case (key,value) => s"$key=$value" //Need to do URL escaping here?
  }.mkString("&")
}

implicit class StringQueryExtensions(url: String) {
  def withParams(q: QueryParams) =
    url + q.toQueryString
}

val params = QueryParams(
  "abc" -> "def",
  "xyz" -> "qrs"
)

params.toQueryString // gives ?abc=def&xyz=qrs

"http://www.google.com".withParams(params) // gives http://www.google.com?abc=def&xyz=qrs

您可以利用
Uri
类来做您想做的事情。它提供了多种方法,可以使用
withQuery
方法将一组参数获取到查询字符串中。例如,您可以这样做:

val httpResponse: Future[HttpResponse] =
  Http().singleRequest(HttpRequest(
    uri = s"""http://${config.getString("http.serverHost")}:${config.getInt("http.port")}/""" +
          s"query?seq=${seq}" +
          s"&max-mismatches=${maxMismatches}" +
          s"&pam-policy=${pamPolicy}"))
val params = Map("foo" -> "bar", "hello" -> "world")
HttpRequest(Uri(hostAndPath).withQuery(params))


使用此方法的好处是,转义将使用此方法自动完成。对于Akka http 2.4.8,这似乎需要
查询
包装:
。withQuery(查询(参数))
这应该在documentation@coolboyjules确切地这个答案很好,但遗憾的是,在登陆这里之前,人们不得不在互联网上搜索这么多。这属于文档。在我的待办事项列表上-因为文档的代码是开源的。它现在是文档的一部分:),链接到这里的一个具体示例