// Compile in sbt // Run in sbt>run get https://raw.githubusercontent.com/nraychaudhuri/scalainaction/master/ chap02/breakable.scala // // The command line in sbt is // >run (post | get | delete | options) -d <request parameters comma separated -h <headers comma separated> <url> // at minimum you should specify action(post, get, delete, options) and url import java.security.cert.X509Certificate import javax.net.ssl._ import org.apache.http.client.entity.UrlEncodedFormEntity import org.apache.http.client.methods._ import org.apache.http.conn.scheme.Scheme import org.apache.http.conn.ssl.{SSLSocketFactory, X509HostnameVerifier} import org.apache.http.impl.client._ import org.apache.http.message._ object RestClient extends App { /*解析参数*/ def parseArgs(args: Array[String]): Map[String, List[String]] = { def nameValuePair(paramName: String) = { def values(commaSeperatedValues: String) = commaSeperatedValues.split(",").toList val index = args.indexWhere(_ == paramName) (paramName, if (index == -1) Nil else values(args(index + 1))) } Map(nameValuePair("-d"), nameValuePair("-h")) } def splitByEqual(nameValue: String): Array[String] = nameValue.split(‘=‘) def headers = for (nameValue <- params("-h")) yield { def tokens = splitByEqual(nameValue) new BasicHeader(tokens(0), tokens(1)) } def formEntity = { def toJavaList(scalaList: List[BasicNameValuePair]) = { java.util.Arrays.asList(scalaList.toArray: _*) } def formParams = for (nameValue <- params("-d")) yield { def tokens = splitByEqual(nameValue) new BasicNameValuePair(tokens(0), tokens(1)) } def formEntity = new UrlEncodedFormEntity(toJavaList(formParams), "UTF-8") formEntity } def handlePostRequest() = { val httppost = new HttpPost(url) headers.foreach { httppost.addHeader(_) } httppost.setEntity(formEntity) val responseBody = httpClient.execute(httppost, new BasicResponseHandler()) println(responseBody) } def handleGetRequest() = { val query = params("-d").mkString("&") val httpget = new HttpGet(s"$url?$query") headers.foreach { httpget.addHeader(_) } val responseBody = httpClient.execute(httpget, new BasicResponseHandler()) println(responseBody) } def handleDeleteRequest() = { val httpDelete = new HttpDelete(url) val httpResponse = httpClient.execute(httpDelete) println(httpResponse.getStatusLine) } def handleOptionsRequest() = { val httpOptions = new HttpOptions(url) headers.foreach { httpOptions.addHeader(_) } val httpResponse = httpClient.execute(httpOptions) println(httpOptions.getAllowedMethods(httpResponse)) } /*require 函数用于抛出异常*/ require(args.size >= 2, "at minimum you should specify action(post, get, " + "delete, options) and url") val command = args.head val params = parseArgs(args) val url = args.last /** SNI(Server Name Indication) 问题 * 针对https服务器会使用SNI选择证书进行发送,但是本例不支持SNI(如一些Android系统), * 在SSL/TLS握手期间,服务器无法根据客户端选择,哪种SNI证书发送,因此需要让其验证时为True */ val xtm = new X509TrustManager { override def getAcceptedIssuers: Array[X509Certificate] = null override def checkClientTrusted(p1: Array[X509Certificate], p2: String): Unit = {} override def checkServerTrusted(p1: Array[X509Certificate], p2: String): Unit = {} } val hostnameVerifier = new X509HostnameVerifier { override def verify(p1: String, p2: SSLSocket): Unit = {} override def verify(p1: String, p2: X509Certificate): Unit = {} override def verify(p1: String, p2: Array[String], p3: Array[String]): Unit = {} override def verify(p1: String, p2: SSLSession): Boolean = true } //TLS1.0与SSL3.0基本上没有太大的差别,可粗略理解为TLS是SSL的继承者,但它们使用的是相同的SSLContext val ctx = SSLContext.getInstance("TLS") //使用TrustManager来初始化该上下文,TrustManager只是被SSL的Socket所使用 ctx.init(null, Array(xtm), null) //创建SSLSocketFactory var socketFactory = new SSLSocketFactory(ctx) socketFactory.setHostnameVerifier(hostnameVerifier) val httpClient = new DefaultHttpClient() httpClient.getConnectionManager.getSchemeRegistry .register(new Scheme("https", socketFactory, 443)) command match { case "post" => handlePostRequest() case "get" => handleGetRequest() case "delete" => handleDeleteRequest() case "options" => handleOptionsRequest() } }
OK,在控制台指定参数
post https://raw.githubusercontent.com/nraychaudhuri/scalainaction/master/chap02/breakable.scala
时间: 2024-10-28 06:26:34