1

公平的警告,我是 Scala 的新手,所以我可能会在这里遗漏一些简单的东西。

我有这个代码,效果很好

import java.net.InetSocketAddress

import com.twitter.finagle.builder.Server
import com.twitter.finagle.builder.ServerBuilder
import com.twitter.finagle.http.Http
import com.twitter.finagle.http.Request
import com.twitter.finagle.http.RichHttp
import java.util.logging.Logger
import com.typesafe.config.ConfigFactory
import org.jboss.netty.buffer.ChannelBuffers.copiedBuffer
import org.jboss.netty.util.CharsetUtil.UTF_8
import com.twitter.finagle.Service
import com.twitter.finagle.http.Response
import com.twitter.util.Future
import com.twitter.finagle.http.service.RoutingService
import org.jboss.netty.handler.codec.http.HttpResponse
import org.jboss.netty.handler.codec.http.HttpRequest
import com.twitter.finagle.SimpleFilter

object TestServer extends App {

    val myService = new Service[Request, Response] {
                def apply(request: Request) = {
                    // If you throw an exception here, the filter will catch it.
                    // throw new RuntimeException("s")
                    Future {
                        val response = Response()
                                response.setContent(copiedBuffer("Hello World", UTF_8))
                                response
                    }
                }
            }

            val routingService = RoutingService.byPath {
                case "/" => myService
            }

    val server: Server = ServerBuilder()
            .codec(RichHttp[Request](Http()))
            .bindTo(new InetSocketAddress(8080))
            .name("httpserver")
            .build(routingService)

    println("Server is up.")

    class Authorize extends SimpleFilter[HttpRequest, HttpResponse] {
        def apply(request: HttpRequest, continue: Service[HttpRequest, HttpResponse]) = {
            println("filtered")
            continue(request)
    }
}

}

但我想将该授权过滤器添加到我的服务中。如果我添加这个:

val authorize = new Authorize
val aService: Service[HttpRequest, HttpResponse] = authorize andThen myService

我得到一个编译错误:

[error]  found   : com.twitter.finagle.Service[com.twitter.finagle.http.Request,com.twitter.finagle.http.Response]
[error]  required: com.twitter.finagle.Service[org.jboss.netty.handler.codec.http.HttpRequest,org.jboss.netty.handler.codec.http.HttpResponse]

如果我将服务更改为 Service[HttpRequest, HttpResponse] 类型,我将无法使用它作为 routingService。

[error]  found   : com.twitter.finagle.Service[org.jboss.netty.handler.codec.http.HttpRequest,org.jboss.netty.handler.codec.http.HttpResponse]
[error]  required: com.twitter.finagle.Service[?,com.twitter.finagle.http.Response]

由于这些类型错误,我很难让路由服务与过滤器一起使用。

谢谢!

编辑:

我只是想在下面添加一个使用@Septem 答案的代码示例,将其用于过滤器:

class Authorize extends Filter[Request, Response, Request, Response] {
        def apply(request: Request, continue: Service[Request, Response]) = {
            println("filtered")
            continue(request)
        }
    }

我对 finagle 和 scala 还有些模糊-但我想这里发生的事情是我使用的 SimpleFilter 已经假设了某种类型的服务,

4

1 回答 1

3

为什么您在服务和过滤器中使用不同的请求和响应类型?

您的服务正在使用来自 finagle 的请求和响应:

val myService = new Service[Request, Response] 

但是您的过滤器正在使用来自 netty 的请求和响应:

class Authorize extends SimpleFilter[HttpRequest, HttpResponse]

我认为这是编译错误的原因,你必须选择一个满足你需要的,并坚持下去。

- 编辑 -

那么我认为你应该基于Filter而不是SimpleFilter实现你的过滤器

abstract class Filter[-ReqIn, +RepOut, +ReqOut, -RepIn] extends ((ReqIn, Service[ReqOut, RepIn]) => Future[RepOut])

抽象类过滤器允许您转换请求/响应类型

查看文档了解详细信息

于 2013-08-09T03:12:22.653 回答