Akka-http自定义404页面

时间:2017-02-20 15:54:35

标签: akka-http

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

  1. 从我的静态文件夹中返回一个页面(例如resources / www / 404.html)
  2. 将结果代码设置为ResultCodes.NOT_FOUND
  3. 到目前为止我尝试了什么:

    1. getFromResource - 我可以返回实体,但我无法弄清楚如何覆盖响应的HTTP结果代码,所以我可以将它设置为'404'。
    2. complete() - 我可以返回正确的代码,但我需要手动阅读html页面,并从头开始构建HttpResponse。它最终有效,但有点麻烦。
    3. 我错过了什么吗?有没有更简单的方法来返回页面并自定义结果代码?

2 个答案:

答案 0 :(得分:1)

静态页面可以作为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"))

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

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

答案 1 :(得分:0)

为了扩展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))
  }