简体   繁体   English

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

[英]How do you use PathMatcher with pathPrefix to redirect a path url to /index.html in akka-http 10?

I'm using akka-http 10.0.10, and have the following file (I extracted it to single file to narrow down imports slightly, but the issue is the same):我正在使用 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))
}

This results in the error:这导致错误:

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

Original ref for this is https://stackoverflow.com/a/42886042/3096687 .对此的原始参考是https://stackoverflow.com/a/42886042/3096687

I think the main reason behind this error is because of the magnet pattern.If you use pathPrefix(pathMatcher)(indxRoute(dir)) then the (indxRoute(dir)) block is mistaken as the implicit argument of pathPrefix .我认为这个错误背后的主要原因是磁铁模式。如果你使用pathPrefix(pathMatcher)(indxRoute(dir))那么(indxRoute(dir))块被误认为是pathPrefix的隐式参数。 pathPrefix returns a directive of type Directive[T] and Directive class does not take any implicit parameters and hence the error. pathPrefix返回类型为Directive[T]的指令,并且Directive类不采用任何隐式参数,因此出现错误。

The possible solutions could be:可能的解决方案可能是:

using tapply method使用tapply方法

tapply method is a special method present in Directive class. tapply方法是Directive类中的一种特殊方法。 tapply calls the inner route with a tuple of extracted values of type T as shown in below sample of code: tapply使用T类型提取值的元组调用内部路由,如下面的代码示例所示:

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

Alternative Approach替代方法

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

Use this function to get Directive and use this directive to construct route as shown below:使用此函数获取指令并使用此指令构建路由,如下所示:

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

This solution works because routeAsDir(matcher) returns Directive[Unit] or Directive0 to which the apply method is called with the inner routes.此解决方案有效,因为routeAsDir(matcher)返回Directive[Unit]Directive0 ,使用内部路由调用 apply 方法。

Let me know if this helps!让我知道这是否有帮助!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM