Scala实现REST操作

// 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

Scala实现REST操作的相关文章

scala 基本类型和操作

基本类型和操作========================类型说明,与java一致值类型 范围 Byte 8位有符号补码整数(-27-27-1) Short 16位有符号补码整数(-215-215-1) Int 32位有符号补码整数(-231-231-1) Long 64位有符号补码整数(-263-263-1) Char 16位无符号Unicode字符(0-216-1) String 字符序列 Float 32位IEEE754单精度浮点数 Double 64位IEEE754单精度浮点数 Bo

Scala函数高级操作

字符串高级操作:***** 非常重要 将函数赋值给变量/值def sayHello(name:String): Unit = { println(s"Hello:$name")} object StringApp extends App { val s = "Hello:PK" val name = "PK" //println(s + name) println(s"Hello:$name") val team = &quo

scala的reduceRight操作?

怎样理解如下的结果? scala> val list = List(1,2,3,4,5) scala> list.reduceRight(_ - _) res26: Int = 3 执行过程如下: (1 - ( 2 - ( 3 - ( 4 - 5 )))) 官方文档说明: op(x_1, op(x_2, ..., op(x_{n-1}, x_n)...)) where x1, ..., xn are the elements of this mutable indexed sequence.

scala json相关操作

一.前言 目前准备编写一个scala项目基础类库,有这样一个需求,将String类型的Json转为Map或其他扩展对象. 二.几种方法探讨 1)scala自带的Json解析 scala 2.10(以上,其他版本不清楚)自带Json解析,scala.util.parsing.json.JSON 使用方法如下: val json = JSON.parseFull(string) 作为一个python,php转过来的同学,期待这句话的执行结果是一个Map(json),Map里面按照实际的字符串解析成一

Scala的XML操作

 8.  XML 8.1.     生成 Scala原生支持xml,就如同Java支持String一样,这就让生成xml和xhtml很简单优雅: val name = "james" val age = 10 val html = <html>name={name}, age="{age}"</html> toString // <html>name=james, age="10"</html>

Scala入门到精通——第十节 Scala类层次结构、Traits初步

本节主要内容 Scala类层次结构总览 Scala中原生类型的实现方式解析 Nothing.Null类型解析 Traits简介 Traits几种不同使用方式 1 Scala类层次结构 Scala中的类层次结构图如下: 来源:Programming in Scala 从上面的类层次结构图中可以看到,处于继承层次最顶层的是Any类,它是scala继承的根类,scala中所有的类都是它的子类 Any类中定义了下面几个方法: //==与!=被声明为final,它们不能被子类重写 final def ==

JVM 并发性: Java 和 Scala 并发性基础

处理器速度数十年来一直持续快速发展,并在世纪交替之际走到了终点.从那时起,处理器制造商更多地是通过增加核心来提高芯片性能,而不再通过增加时钟速率来提高芯片性能.多核系统现在成为了从手机到企业服务器等所有设备的标准,而这种趋势可能继续并有所加速.开发人员越来越需要在他们的应用程序代码中支持多个核心,这样才能满足性能需求. 在本系列文章中,您将了解一些针对 Java 和 Scala 语言的并发编程的新方法,包括 Java 如何将 Scala 和其他基于 JVM 的语言中已经探索出来的理念结合在一起.

Scala深入浅出实战经典《第84讲:Scala中List和ListBuffer设计实现思考》笔记

感觉视频时间比较短,不过对于上班狗来说还比较适合,地铁上听一遍,回来做笔记时可以再听一遍,啦啦啦... 第84讲:Scala中List和ListBuffer设计实现思考 Goal:从case class::[B]出发思考 List, ListBuffer的设计 Gains: 1) case calss ::[B] 中虽然用的是var(可变),但是有private[scala]的限制: 如果没有改限制,可以改变除首元素外的其他元素,对共享数据带来麻烦. 2)保证scala元素本身操作的高效性,外部

Spark中的各种action算子操作(java版)

在我看来,Spark编程中的action算子的作用就像一个触发器,用来触发之前的transformation算子.transformation操作具有懒加载的特性,你定义完操作之后并不会立即加载,只有当某个action的算子执行之后,前面所有的transformation算子才会全部执行.常用的action算子如下代码所列:(java版) package cn.spark.study.core; import java.util.Arrays; import java.util.List; im