2017-02-20 92 views
1

我想在akka-http(高級DSL)中創建一個定製的404頁面。這基本上意味着:Akka-http定製404頁面

  1. 返回從我的靜態文件夾頁(如資源/網絡/ 404.html)
  2. 將結果代碼ResultCodes.NOT_FOUND

我試過到目前爲止什麼:

  1. getFromResource - 我可以返回實體,但我無法弄清楚如何覆蓋響應的HTTP結果代碼,所以我可以將它設置爲'404'。
  2. complete() - 我可以返回正確的代碼,但我需要手動讀取html頁面,並從頭開始構建HttpResponse。它最終有效,但有點麻煩。

我錯過了什麼嗎?有沒有更簡單的方法來返回頁面並自定義結果代碼?

回答

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) 
    } 
+0

@WillIAm歡迎您。我同意這不像「單線」那麼簡單,但我不明白這是如何實現的。使用實體創建404響應與創建實體的400響應完全相同。模式中有足夠的分歧,我不認爲圖書館可以提高冗長度。我更新了答案,使其更像是一個util庫函數,至少你只需要編寫一次... –

+0

糟糕,我刪除了我以前的評論(但沒有什麼重要的東西,只是感謝和抱怨說這不是很簡單:)。順便說一句,你的代碼我得到一個編譯錯誤在線staticResponse = ...(期望Seq [HttpHeader],實際HttpEnttity.Chunked) –

+0

@WillIAm回答更新修復編譯錯誤。 –

0

要在拉蒙的出色答卷擴大,這個工作的jar文件裏面WEL l:

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)) 
    }