Akka-http自定义404页面

Akka-http custom 404 page

我想在 akka-http(高级 DSL)中创建自定义 404 页面。这基本上意味着:

  1. Return 来自我的静态文件夹的页面(例如 resources/www/404.html)
  2. 将结果代码设置为ResultCodes.NOT_FOUND

到目前为止我尝试了什么:

  1. getFromResource - 我可以 return 实体,但我不知道如何覆盖响应的 HTTP 结果代码,因此我可以将其设置为“404”。
  2. complete() - 我可以 return 正确的代码,但我需要手动阅读 html 页面,并从头开始构建 HttpResponse。终于成功了,就是有点麻烦

我错过了什么吗?有没有更简单的方法 return 页面和自定义结果代码?

静态页面可以return编辑为 HttpResponseentity

假设你有一些形式的函数

def someFunctionThatCanFail() : Try[HttpResponse] = ???

如果出现故障,您将希望使用静态页面。您首先需要创建一个基于静态页面的 Source

import akka.stream.scaladsl._
import akka.http.scaladsl.model.HttpEntity.Chunked

def createStaticSource(fileName : String) = 
  FileIO
    .fromPath(Paths get fileName)
    .map(ChunkStreamPart.apply)

def createChunkedSource(fileName : String) = 
  Chunked(ContentTypes.`text/html(UTF-8)`, createStaticSource(fileName))

然后可以将此源放在响应中:

def staticResponse = 
  HttpResponse(status = StatusCodes.NotFound,
               entity = createChunkedSource("resources/www/404.html"))

唯一剩下要做的就是 return 函数的结果(如果有效)或静态响应(如果失败):

val route = 
  get {
    complete(someFunctionThatCanFail() getOrElse staticResponse)
  }

为了扩展 Ramon 的出色回答,这也适用于 jar 文件:

 def createChunkedSource(fileName : String): Chunked = {
    def createStaticSource(fileName : String) : Source[ChunkStreamPart, Any] = {
      val classLoader = getClass.getClassLoader
      StreamConverters.fromInputStream(() => classLoader.getResourceAsStream(fileName)).map(ChunkStreamPart.apply)
    }
    Chunked(ContentTypes.`text/html(UTF-8)`, createStaticSource(fileName))
  }