在akka-http 10中,如何使用带有路径前缀的PathMatcher将路径url重定向到/index. html?

lnlaulya  于 2022-11-06  发布在  其他
关注(0)|答案(1)|浏览(131)

我使用的是akka-http 10.0.10,并有以下文件(我将其解压缩到单个文件中,以稍微缩小导入范围,但问题是相同的):

import akka.http.scaladsl.model.StatusCodes
import akka.http.scaladsl.server._
import akka.http.scaladsl.server.Directives._

object RouteHelpers {

  def indexRoute(dir : String): Route =
    pathEndOrSingleSlash {
      getFromFile(dir + "/index.html")
    } ~
    getFromDirectory(dir)

  def routeAsDir[T](pathMatcher : PathMatcher[T], dir : String) : Route =
    pathPrefix(pathMatcher)(indexRoute(dir))
}

这将导致以下错误:

RouteHelpers.scala:15:28: akka.http.scaladsl.server.Directive[T] does not take parameters
[error]     pathPrefix(pathMatcher)(indexRoute(dir))

其原始引用为https://stackoverflow.com/a/42886042/3096687

sbdsn5lh

sbdsn5lh1#

我认为这个错误背后的主要原因是因为磁模式。如果你使用pathPrefix(pathMatcher)(indxRoute(dir)),那么(indxRoute(dir))块被误认为是pathPrefix的隐式参数。pathPrefix返回一个Directive[T]类型的指令,而Directive类不接受任何隐式参数,因此产生了这个错误。
可能的解决方案包括:

使用tapply方法

tapply方法是Directive类中存在的特殊方法。tapply使用T类型的提取值的元组调用内部路由,如以下代码示例所示:

def routeAsDir[T](pathMatcher: PathMatcher[T], dir: String): Route = {
  pathPrefix(pathMatcher).tapply(t => indexRoute(dir))
}

替代方法

def routeAsDir[T](pathMatcher: PathMatcher[T]): Directive[T] = pathPrefix(pathMatcher)

使用此函数获取Directive,并使用此指令构造路由,如下所示:

val matcher: PathMatcher[Unit] = "foo" / "bar"
val route: Route = routeAsDir(matcher) {
    indexRoute("foo/bar")
}

此解决方案之所以有效,是因为routeAsDir(matcher)返回Directive[Unit]Directive0,apply方法是通过内部路由调用到这些值的。
如果有帮助,请告诉我!

相关问题