我如何从 finagle 客户端发出带有参数的请求?
How I can make a request with params from finagle client?
我正在开始使用 Finagle 服务器 (twitter/finagle):
import com.twitter.finagle.{Http, Service}
import com.twitter.util.{Await, Future}
import java.net.InetSocketAddress
import org.jboss.netty.handler.codec.http._
object Server extends App {
val service = new Service[HttpRequest, HttpResponse] {
def apply(req: HttpRequest): Future[HttpResponse] =
Future.value(new DefaultHttpResponse(
req.getProtocolVersion, HttpResponseStatus.OK))
}
val server = Http.serve(":8080", service)
Await.ready(server)
}
客户(twitter/finagle):
import com.twitter.finagle.{Http, Service}
import com.twitter.util.{Await, Future}
import java.net.InetSocketAddress
import org.jboss.netty.handler.codec.http._
object Client extends App {
val client: Service[HttpRequest, HttpResponse] =
Http.newService("localhost:8080")
val request = new DefaultHttpRequest(
HttpVersion.HTTP_1_1, HttpMethod.GET, "/")
val response: Future[HttpResponse] = client(request)
response onSuccess { resp: HttpResponse =>
println("GET success: " + resp)
}
Await.ready(response)
}
如何从客户端向服务器发送类似Map("data_id" -> 5)
的数据?我在服务器的什么地方收到它?我必须向服务器添加回调吗?
我搜索没找到。如果你能给我一个link和一个例子就足够了。
Finagle 是一个非常精简的库。这意味着您必须自己处理大部分 "magic"。
为了使用来自客户端的参数发出请求,我使用了这些辅助方法:
def buildUri(base: String, path: String, params: Map[String, String] = Map.empty): String = {
val p = if (params.isEmpty) ""
else params map { case (k,v) => urlEncode(k) + "=" + urlEncode(v) } mkString ("?", "&", "")
base + path + p
}
def urlEncode(url: String): String = URLEncoder.encode(url, "UTF-8")
然后我这样称呼它:
val url = buildUri(baseAddress, path, defaultParams ++ params)
val req = RequestBuilder().url(url).setHeader("Accept", "*/*").buildGet
client(req)
至于服务器你必须做基本相同的事情并手动解析参数。使用 java.net.URI
甚至 org.jboss.netty.handler.codec.http.QueryStringDecoder
.
当然你也可以使用URI
和QueryStringEncoder
来编码,而不是使用我的辅助方法。
就是说,如果您想在更高级别上这样做,您可以使用 Finagle 之上的这些库之一:
- https://github.com/fwbrasil/zoot
- http://finatra.info/(这仅适用于服务器部分)
我正在开始使用 Finagle 服务器 (twitter/finagle):
import com.twitter.finagle.{Http, Service}
import com.twitter.util.{Await, Future}
import java.net.InetSocketAddress
import org.jboss.netty.handler.codec.http._
object Server extends App {
val service = new Service[HttpRequest, HttpResponse] {
def apply(req: HttpRequest): Future[HttpResponse] =
Future.value(new DefaultHttpResponse(
req.getProtocolVersion, HttpResponseStatus.OK))
}
val server = Http.serve(":8080", service)
Await.ready(server)
}
客户(twitter/finagle):
import com.twitter.finagle.{Http, Service}
import com.twitter.util.{Await, Future}
import java.net.InetSocketAddress
import org.jboss.netty.handler.codec.http._
object Client extends App {
val client: Service[HttpRequest, HttpResponse] =
Http.newService("localhost:8080")
val request = new DefaultHttpRequest(
HttpVersion.HTTP_1_1, HttpMethod.GET, "/")
val response: Future[HttpResponse] = client(request)
response onSuccess { resp: HttpResponse =>
println("GET success: " + resp)
}
Await.ready(response)
}
如何从客户端向服务器发送类似Map("data_id" -> 5)
的数据?我在服务器的什么地方收到它?我必须向服务器添加回调吗?
我搜索没找到。如果你能给我一个link和一个例子就足够了。
Finagle 是一个非常精简的库。这意味着您必须自己处理大部分 "magic"。
为了使用来自客户端的参数发出请求,我使用了这些辅助方法:
def buildUri(base: String, path: String, params: Map[String, String] = Map.empty): String = {
val p = if (params.isEmpty) ""
else params map { case (k,v) => urlEncode(k) + "=" + urlEncode(v) } mkString ("?", "&", "")
base + path + p
}
def urlEncode(url: String): String = URLEncoder.encode(url, "UTF-8")
然后我这样称呼它:
val url = buildUri(baseAddress, path, defaultParams ++ params)
val req = RequestBuilder().url(url).setHeader("Accept", "*/*").buildGet
client(req)
至于服务器你必须做基本相同的事情并手动解析参数。使用 java.net.URI
甚至 org.jboss.netty.handler.codec.http.QueryStringDecoder
.
当然你也可以使用URI
和QueryStringEncoder
来编码,而不是使用我的辅助方法。
就是说,如果您想在更高级别上这样做,您可以使用 Finagle 之上的这些库之一:
- https://github.com/fwbrasil/zoot
- http://finatra.info/(这仅适用于服务器部分)