Akka-http:接受和内容类型处理

Wil*_* Am 13 scala akka akka-http

我正在尝试Akka-http,希望有人可以解释以下问题:

  1. 如何根据请求中的accept:标头创建不同的路由?例如,我想要一个代码路径来处理"json",一个代码来处理"xml"请求(如果缺少头,则默认为"json")

  2. 如果我不希望推断出contentType,我该如何指定它?例如,在下面的代码中,我尝试通过compactPrint()运行json,但这会将其更改为字符串,因此为"text/plain".我想覆盖它并告诉客户端它仍然是json.

我的代码是这样的;

...
path("api") {
          get {
              complete {
                getStuff.map[ToResponseMarshallable] {
                  case Right(r) if r.isEmpty => List[String]().toJson.compactPrint
                  case Right(r) => r.toJson.compactPrint
                  case Left(e) => BadRequest -> e
                }
              }
          }
        }
...
Run Code Online (Sandbox Code Playgroud)

这种情况下的响应是text/plain,因为compactPrint创建了一个字符串.批评非常欢迎.;)

S.K*_*hik 9

您可以按如下方式定义内容类型,

complete {
           HttpResponse(entity = HttpEntity(ContentType(MediaTypes.`application/json`), """{"id":"1"}"""))
         }
Run Code Online (Sandbox Code Playgroud)

您可以创建自定义指令,

  def handleReq(json: String) = {
    (get & extract(_.request.acceptedMediaRanges)) {
      r =>
        val encoding: MediaRange =
          r.intersect(myEncodings).headOption
            .getOrElse(MediaTypes.`application/json`)
        complete {
          // check conditions here
         // HttpResponse(entity = HttpEntity(encoding.specimen, json)) //
        }
    }
  }
Run Code Online (Sandbox Code Playgroud)

并在路由中使用该指令

val route = path("api"){ handleReq(json) }
Run Code Online (Sandbox Code Playgroud)