gpt4 book ai didi

scala - 使用 Finagle 构建简单的 Scala SOAP 客户端

转载 作者:行者123 更新时间:2023-12-02 01:15:23 25 4
gpt4 key购买 nike

我正在努力使用 Twitter 的 Finagle 库来实现对 SOAP 服务器的 HTTP 请求。

下面的代码成功执行了第一个测试(使用java.net.URL),但我在第二个测试中遇到了困难(使用Finagle 客户端)。我做错了什么?

此外,我一直被拖入命令式的写作风格。如果你可以帮助我让 Finagle 更像“scala”,我会的非常感谢。

这里是:

import java.net.InetSocketAddress 
import scala.xml.{Elem, XML}
import org.jboss.netty.buffer.ChannelBuffers
import org.jboss.netty.util.CharsetUtil.UTF_8
import com.twitter.finagle.Service;
import com.twitter.finagle.builder.ClientBuilder;
import com.twitter.finagle.http.Http;
import org.jboss.netty.handler.codec.http._

class SoapClient {
private def error(msg: String) = {
println("SoapClient error: " + msg)
}

def wrap(xml: Elem): String = {
val buf = new StringBuilder
buf.append("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=
\"no\"?>\n")
buf.append("<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://
schemas.xmlsoap.org/soap/envelope/\">\n")
buf.append("<SOAP-ENV:Body>\n")
buf.append(xml.toString)
buf.append("\n</SOAP-ENV:Body>\n")
buf.append("</SOAP-ENV:Envelope>\n")
buf.toString
}

def sendWithJavaNetURL(host: String, req: Elem): Option[Elem] = {
val url = new java.net.URL(host)
val outs = wrap(req).getBytes
val conn =
url.openConnection.asInstanceOf[java.net.HttpURLConnection]
try {
conn.setRequestMethod("POST")
conn.setDoOutput(true)
conn.setRequestProperty("Content-Length", outs.length.toString)
conn.setRequestProperty("Content-Type", "text/xml")
conn.getOutputStream.write(outs)
conn.getOutputStream.close
Some(XML.load(conn.getInputStream))
}
catch {
case e: Exception => error("post: " + e)
error("post:" +
scala.io.Source.fromInputStream(conn.getErrorStream).mkString)
None
}
}

def sendWithFinagle(host: String, path: String, req: Elem) = {
val clientService: Service[HttpRequest, HttpResponse] =
ClientBuilder()
.codec(Http())
.hosts(new InetSocketAddress(host, 80))
.hostConnectionLimit(1)
.build()
val request: HttpRequest = new
DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.POST, "/")
val soapPacket: String = wrap(req)
request.setContent(ChannelBuffers.copiedBuffer(soapPacket, UTF_8))
request.setHeader("Content-Lenght", soapPacket.length())
request.setHeader("Content-Type", "text/xml")
request.setUri("path")
val client = clientService(request)
val response = client.get()
println(response)
}
}

object SoapTest {

def testWithJavaNetURL {
val host = "https://apitest.authorize.net/soap/v1/Service.asmx"
val req = <IsAlive xmlns="https://api.authorize.net/soap/v1/"/>
val cli = new SoapClient
println("##### Test with Java Net URL: request:\n" +
cli.wrap(req))
val resp = cli.sendWithJavaNetURL(host, req)
if (resp.isDefined) {
println("##### response:\n" + resp.get.toString)
}
}

def testWithFinagle {
val host = "apitest.authorize.net"
val path = "/soap/v1/Service.asmx"
val req = <IsAlive xmlns="https://api.authorize.net/soap/v1/"/>
val cli = new SoapClient
println("##### Test with Finagle: request:\n" + cli.wrap(req))
cli.sendWithFinagle(host, path, req)
}

def main(args: Array[String]) {
testWithJavaNetURL
testWithFinagle
}

最佳答案

Jean-Phillippe,来自 Finagles forum ,请提供 answer on github

这是完整的工作且经过良好更新的代码:

import java.net.InetSocketAddress
import scala.xml.{Elem, XML}
import org.jboss.netty.buffer.ChannelBuffers
import org.jboss.netty.util.CharsetUtil.UTF_8
import com.twitter.finagle.Service;
import com.twitter.finagle.builder.ClientBuilder;
import com.twitter.finagle.http.{Http, RequestBuilder};
import org.jboss.netty.handler.codec.http._
import org.jboss.netty.buffer.ChannelBuffers.wrappedBuffer
import java.net.URL
class SoapClient {
private def error(msg: String) = {
println("SoapClient error: " + msg)
}
def wrap(xml: Elem): String = {
val wrapper = <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Body>
{xml}
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
wrapper.toString
}
def sendWithJavaNetURL(host: String, req: Elem): Option[Elem] = {
val url = new java.net.URL(host)
val outs = wrap(req).getBytes
val conn =
url.openConnection.asInstanceOf[java.net.HttpURLConnection]
try {
conn.setRequestMethod("POST")
conn.setDoOutput(true)
conn.setRequestProperty("Content-Length", outs.length.toString)
conn.setRequestProperty("Content-Type", "text/xml")
conn.getOutputStream.write(outs)
conn.getOutputStream.close
Some(XML.load(conn.getInputStream))
}
catch {
case e: Exception => error("post: " + e)
error("post:" +
scala.io.Source.fromInputStream(conn.getErrorStream).mkString)
None
}
}
def sendWithFinagle(host: String, path: String, req: Elem) = {
val clientService: Service[HttpRequest, HttpResponse] =
ClientBuilder()
.codec(Http())
.hosts(new InetSocketAddress(host, 443))
.tls(host)
.hostConnectionLimit(1)
.build()
val payload = wrap(req).getBytes("UTF-8")
val request: HttpRequest = RequestBuilder().url(new URL("https", host, 443, path))
.setHeader("Content-Type", "text/xml")
.setHeader("Content-Length", payload.length.toString)
.buildPost(wrappedBuffer(payload))

val client = clientService(request)

for(response <- client) {
println(response)
println(response.getContent.toString("UTF-8"))
}
// val response = client.get()
}
}

object SoapTest {
def testWithJavaNetURL {
val host = "https://apitest.authorize.net/soap/v1/Service.asmx"
val req = <IsAlive xmlns="https://api.authorize.net/soap/v1/"/>
val cli = new SoapClient
println("##### Test with Java Net URL: request:\n" +
cli.wrap(req))
val resp = cli.sendWithJavaNetURL(host, req)
if (resp.isDefined) {
println("##### response:\n" + resp.get.toString)
}
}
def testWithFinagle {
val host = "apitest.authorize.net"
val path = "/soap/v1/Service.asmx"
val req = <IsAlive xmlns="https://api.authorize.net/soap/v1/"/>
val cli = new SoapClient
println("##### Test with Finagle: request:\n" + cli.wrap(req))
cli.sendWithFinagle(host, path, req)
}
def main(args: Array[String]) {
testWithJavaNetURL
testWithFinagle
}
}

SoapTest.main(Array[String]())

关于scala - 使用 Finagle 构建简单的 Scala SOAP 客户端,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9277514/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com