【问题标题】:Traits not implemented in finagle service特征未在 finagle 服务中实现
【发布时间】:2015-04-28 07:10:51
【问题描述】:

我有一个简单的 finagle 服务如下:

import com.twitter.finagle.{Http,Service}
import com.twitter.util.{Await, Future}
import java.net.InetSocketAddress
import org.jboss.netty.handler.codec.http._
import org.jboss.netty.buffer.ChannelBuffers.copiedBuffer
import org.jboss.netty.util.CharsetUtil
import net.liftweb.json._
import com.twitter.finagle.http.{Request,Response,RichHttp}
import com.twitter.finagle.builder.ServerBuilder

case class Add(num1:Int, num2:Int)
case class Result(result:Int)  

trait Transformer[R1,T,U,R2] {
  def extractPayload(r:R1):T
  def responsePayload(u:U):R2
}

object Transformer{
  implicit object AddPayloadTransformer 
        extends Transformer[HttpRequest,Add,Result,HttpResponse]{
   implicit val formats = DefaultFormats

   def extractPayload(r:HttpRequest):Add = {
        val body = r.getContent
    val length = body.readableBytes()
    val bytes = new Array[Byte](length)
    body.getBytes(body.readerIndex(),bytes,0,length)
    val bodyStr = new String(bytes)
    parse(bodyStr).extract[Add]
    }

   def responsePayload(u:Result):HttpResponse = {   
    val result = u.result
    val response = Response(HttpVersion.HTTP_1_1,
                HttpResponseStatus.OK)
        response.setContentTypeJson()       
        response.setContentString(
          s"""
            {
            "result": $result
            }
           """)
        response.httpResponse
   }   
  }
}

object AdditionServer extends App with Transformer[HttpRequest,Add,Result,HttpResponse]{
 private def add(add:Add):Result = Result(add.num1 + add.num2) 

 private def additionHandler(req:HttpRequest): HttpResponse = {
     val addPayload = extractPayload(req)
     val result = add(addPayload)
     responsePayload(result)    
 }   

 val service = new Service[HttpRequest,HttpResponse] {
     def apply(req: HttpRequest): Future[HttpResponse] = 
    {
       Future.value(additionHandler(req))
    }
 }

  val server = Http.serve(":8080", service)
  Await.ready(server)
  println("Started service")                
}

当我尝试编译它时,我得到以下异常:

AdditionService.scala:49: object creation impossible, since:
[error] it has 2 unimplemented members.
[error] /** As seen from object AdditionServer, the missing signatures are as follows.
[error]  *  For convenience, these are usable as stub implementations.
[error]  */
[error]   def extractPayload(r: org.jboss.netty.handler.codec.http.HttpRequest): Add = ???
[error]   def responsePayload(u: Result): org.jboss.netty.handler.codec.http.HttpResponse = ???
[error] object AdditionServer extends App with Transformer[HttpRequest,Add,Result,HttpResponse]{
[error]        ^
[error] one error found
[error] (compile:compileIncremental) Compilation failed

据我所知,我正在使用它们的正确签名来实现这些特征。

谁能指出这里可能出了什么问题。

谢谢

【问题讨论】:

    标签: scala typeclass traits finagle


    【解决方案1】:

    AdditionServer 是扩展Transformer 的对象。在您的代码中,该对象既没有定义extractPayload 也没有定义responsePayload,因此您得到了编译错误。

    你应该将你的方法定义从 trait 伴侣对象移动到 AdditionServer

    object AdditionServer extends App with
    Transformer[HttpRequest,Add,Result,HttpResponse] {
    
    import Transformer._
    
    def extractPayload(r:HttpRequest):Add = {
            val body = r.getContent
        val length = body.readableBytes()
        val bytes = new Array[Byte](length)
        body.getBytes(body.readerIndex(),bytes,0,length)
        val bodyStr = new String(bytes)
        parse(bodyStr).extract[Add]
    }
    
    def responsePayload(u:Result):HttpResponse = {   
        val result = u.result
        val response = Response(HttpVersion.HTTP_1_1,
                HttpResponseStatus.OK)
            response.setContentTypeJson()       
            response.setContentString(
              s"""
                {
                "result": $result
                }
               """)
            response.httpResponse
       }   
    }
    

    如果您希望在伴随对象中定义您的方法,您可以从AdditionServer 引用它们:

    object Transformer{
      implicit object AddPayloadTransformer 
      extends Transformer[HttpRequest,Add,Result,HttpResponse]{
       implicit val formats = DefaultFormats
    
       def extractPayload(r:HttpRequest):Add = {
            val body = r.getContent
            val length = body.readableBytes()
            val bytes = new Array[Byte](length)
            body.getBytes(body.readerIndex(),bytes,0,length)
            val bodyStr = new String(bytes)
            parse(bodyStr).extract[Add]
        }
    
       def responsePayload(u:Result):HttpResponse = {   
            val result = u.result
            val response = Response(HttpVersion.HTTP_1_1,
                HttpResponseStatus.OK)
            response.setContentTypeJson()       
            response.setContentString(
              s"""
                {
                "result": $result
                }
               """)
            response.httpResponse
       }   
      }
    }
    
    object AdditionServer extends App with
    Transformer[HttpRequest,Add,Result,HttpResponse]{
    
       def extractPayload(r:HttpRequest):Add = Transformer.extractPayload(r)
    
       def responsePayload(u:Result):HttpResponse = Transformer.responsePayload(u)
    
      ...
      ...
    

    【讨论】:

    • 谢谢。这里的问题是有效负载打包/解包是我想单独隔离为类型类的东西。在 AdditionServer 中移动实现违背了这个目的。
    • 您可以将这些方法保留在伴生对象中,并在AdditionServer 下定义一个代理接口。检查我的编辑。
    猜你喜欢
    • 1970-01-01
    • 2011-09-28
    • 1970-01-01
    • 2020-08-15
    • 2021-08-20
    • 1970-01-01
    • 2019-12-08
    • 2021-11-14
    • 1970-01-01
    相关资源
    最近更新 更多