如何使用 akka-http 将 html 文件正确地作为正确的内容提供给浏览器?

how to serve a html file correctly as correct content to a browser with akka-http?

我正在查看 akka-http 文档,找到如何使用 HttpResponses 为低级服务器 api 提供 html 内容。但是,我找不到任何关于如何提供 html-content 的好例子,这些内容应该在浏览器中正确表示。我发现并且可以开始工作的唯一事情是当它提供如下所示的 String 内容时。我找到了一个例子:

imports akka.http.scaladsl.marshallers.xml.ScalaXmlSupport._

但我看不到 scaladsl 包含编组器(它包含编组)

import akka.http.scaladsl.Http
import akka.stream.ActorMaterializer
import akka.http.scaladsl.server.Directives._
import akka.actor.ActorSystem

object HttpAkka extends App{

   implicit val system = ActorSystem()
   implicit val materializer = ActorMaterializer()
   implicit val ec = system.dispatcher

   val route = get {
       pathEndOrSingleSlash {
           complete("<h1>Hello</h1>")
       }
   }

  Http().bindAndHandle(route, "localhost", 8080)

}

在这里找到了一个相关问题

我没有完全理解 link 中的答案,但尝试了以下方法(我最终成功了..):

complete {
    HttpResponse(entity=HttpEntity(ContentTypes.`text/html(UTF-8)`, "<h1>Say Hello</h1>"))
}

以及:

complete {
    respondWithHeader (RawHeader("Content-Type", "text/html(UFT-8"))
      "<h1> Say hello</h1>"
    } 

处理此问题的最佳方法可能是使用 ScalaXmlSupport 构建一个 NodeSeq 编组器,它将内容类型正确设置为 text/html。为此,您首先需要添加一个新的依赖项,因为默认情况下不包含 ScalaXmlSupport。假设你使用的是sbt,那么需要添加的依赖如下:

"com.typesafe.akka" %% "akka-http-xml-experimental" % "2.4.2"

然后,您可以像这样设置一条路由到 return Scala NodeSeq,当 akka 设置内容类型时,它将被标记为 text/html

implicit val system = ActorSystem()
import system.dispatcher
implicit val mater = ActorMaterializer()
implicit val htmlMarshaller = ScalaXmlSupport.nodeSeqMarshaller(MediaTypes.`text/html` )

val route = {
  (get & path("foo")){
    val resp = 
      <html>
        <body>
          <h1>This is a test</h1>
        </body>
      </html>

    complete(resp)
  }
}

Http().bindAndHandle(route, "localhost", 8080

获得 text/htmltext/xml 的技巧是在 ScalaXmlSupport 上使用 nodeSeqMarshaller 方法,传入 MediaTypes.text/html 作为媒体类型。如果您只是导入 ScalaXmlSupport._,那么范围内的默认编组器会将内容类型设置为 text/xml.