[英]How to make akka-http to forward a GET request to a POST request and change attributes?
I am handing a get request using akka-http and I want to forward to the same host but changing the following parameters:我正在使用 akka-http 处理获取请求,并且我想转发到同一主机但更改以下参数:
8080
to 8081
8080
更改为8081
I consulted this page and this answer .我查阅了这个页面和这个答案。 I am extracting the request using
extract(_.request) { request =>
and then creating a redirect(
with the StatusCodes.MovedPermanently
.我正在使用
extract(_.request) { request =>
,然后使用StatusCodes.MovedPermanently
创建redirect(
。
val routes: Route = {
get {
(path(IntNumber) & parameterSeq) { (adId: Int, params: Seq[(String, String)]) =>
// handling requests as: "http://localhost:8080/2?c=5&b=2", make sure to use the request between quotes
println(s"The ad ID: $adId contains the parameters: ${params.map(paramString).mkString(", ")}")
val bid = getBid(adId, params)
println(s"bid request: ${bid.toJson.prettyPrint}")
// HOW TO REDIRECT TO ANOTHER PORT, CHANGE THE METHOD FROM GET TO POST, AND SEND A JSON PAYLOAD?
val newRequest = HttpRequest(
HttpMethods.POST,
uri = "/",
entity = HttpEntity(ContentTypes.`application/json`, bid.toJson.toString)
)
redirect(
newRequest
.uri
.withHost("localhost")
.withPort(8082),
StatusCodes.MovedPermanently
)
// complete(StatusCodes.OK)
} ~ pathEndOrSingleSlash {
complete(StatusCodes.BadRequest)
} ~ {
complete(StatusCodes.Forbidden)
}
}
}
But when I send a get to the akka-http application $ http GET "localhost:8080/3?b=5&c=10&d=19&c=10"
the server on the port 8082
does not answer.但是,当我向 akka-http 应用程序发送 get
$ http GET "localhost:8080/3?b=5&c=10&d=19&c=10"
时,端口8082
上的服务器没有响应。
$ http GET "localhost:8080/3?b=5&c=10&d=19&c=10"
HTTP/1.1 301 Moved Permanently
Content-Length: 92
Content-Type: text/html; charset=UTF-8
Date: Fri, 19 Feb 2021 15:49:21 GMT
Location: //localhost:8082/
Server: akka-http/10.2.2
This and all future requests should be directed to <a href="//localhost:8082/">this URI</a>.
To test if the server is working I can send POST
requests and I receive the answer:要测试服务器是否正常工作,我可以发送
POST
请求并收到答案:
$ http POST localhost:8082 < src/main/resources/bidders-request-10.json
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Date: Fri, 19 Feb 2021 15:51:02 GMT
Server: Apache-Coyote/1.1
Transfer-Encoding: chunked
{
"bid": 0,
"content": "b:$price$",
"id": "10"
}
So, I solved by creating an actor that executes a Http().singleRequest(HttpRequest(uri = "https://akka.io"))
like this example .所以,我通过创建一个执行
Http().singleRequest(HttpRequest(uri = "https://akka.io"))
的参与者来解决这个例子。 the working solution that I have is:我拥有的工作解决方案是:
import akka.actor.{Actor, ActorLogging, ActorSystem, Props}
import akka.http.scaladsl.Http
import akka.http.scaladsl.model._
import akka.util.ByteString
import spray.json._
import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport
object MyselfClient {
def main(args: Array[String]): Unit = {
val system = ActorSystem("AuctionClientSystem")
val auctionClientActor = system.actorOf(Props[AuctionClientActor], "auctionClientActor")
auctionClientActor ! BidRequest(1, Bid(2, List(("c", "5"), ("b", "2"))))
}
}
case class BidRequest(requestId: Int, bid: Bid)
class AuctionClientActor extends Actor with ActorLogging
with BidJsonProtocol with SprayJsonSupport {
import akka.pattern.pipe
import context.dispatcher
implicit val system = context.system
val http = Http(system)
def receive = {
case bidRequest@BidRequest(requestId, bid) =>
println(s"received bid request: $bidRequest")
val content = bidRequest.bid.toJson.toString
.replace("[[", "{")
.replace("]]", "}")
.replace("\",\"", "\": \"")
.replace("[", "")
.replace("]", "")
println(content)
// create the request
val httpRequest = HttpRequest(
HttpMethods.POST,
uri = Uri("http://localhost:8081"),
entity = HttpEntity(
ContentTypes.`application/json`,
content
// """{"id": 10, "attributes" : { "a": "1", "b": "0" }}""".stripMargin
)
)
// send the request
http.singleRequest(httpRequest).pipeTo(self)
case HttpResponse(StatusCodes.OK, headers, entity, _) =>
entity.dataBytes.runFold(ByteString(""))(_ ++ _).foreach { body =>
println("Got response, body: " + body.utf8String)
}
case resp@HttpResponse(code, _, _, _) =>
println("Request failed, response code: " + code)
resp.discardEntityBytes()
}
}
I just could not figure out how to make Spray JSON not use [
and ]
.我只是不知道如何使 Spray JSON 不使用
[
和]
。 Then I am doing that nasty conversation using .replace("[[", "{")
.然后我正在使用
.replace("[[", "{")
进行那个讨厌的对话。 However, the solution is already working.但是,该解决方案已经奏效。 The Spray JSON I am looking for a better way to convert it.
喷雾 JSON 我正在寻找一种更好的转换方法。 I guess there is another form to create the case class to not have
[
and ]
.我想还有另一种形式可以创建没有
[
和]
的案例 class 。
import spray.json._
case class Bid(id: Int, attributes: List[(String, String)])
trait BidJsonProtocol extends DefaultJsonProtocol {
implicit val bidFormat = jsonFormat2(Bid)
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.