“你的身体?”颜盈也强忍着心中的震惊,她没亲身体会过,但是也能清楚地知道被麒麟血弄在身上的感觉有多可怕,这个男人居然硬生生的承受下来,看着沐俗了麒麟血之后刘皓的身体,看上去外表明明没有明显的变化,可是却偏偏给颜盈一种更为刚猛,火热的感觉,让她心里都出现了一丝丝涟漪。

Akka(34): Http:Unmarshalling,from Json


  Unmarshalling是Akka-http内把网上可传输格式的数据转变成程序高级结构话数据的过程,比如把Json数据转换成某个自定义类型的实例。按具体流程来说就是先把Json转换成可传输格式数据如:MessageEntity,HttpRequest,HttpReponse等,然后再转换成程序高级结构数据如classXX实例。Unmarshalling对一个A类实例到B类实例的转换是通过Unmarshaller[A,B]来实现的:

trait Unmarshaller[-A, B] extends akka.http.javadsl.unmarshalling.Unmarshaller[A, B] {...}
object Unmarshaller
  extends GenericUnmarshallers
  with PredefinedFromEntityUnmarshallers
  with PredefinedFromStringUnmarshallers {

  // format: OFF

  //#unmarshaller-creation
  /**
   * Creates an `Unmarshaller` from the given function.
   */
  def apply[A, B](f: ExecutionContext ⇒ A ⇒ Future[B]): Unmarshaller[A, B] =
    withMaterializer(ec => _ => f(ec))
...}

从Unmarshaller的构建函数apply可以估计它的作用应该与函数A=>Future[B]很相似。A代表网上可传输类型如MessageEntity、HttpRequest,B代表某种程序高级数据类型。因为A到B的转换是non-blocking的,所以可以立即返回Future类型结果。Akka-http按被转换对象类型分类命名了下面这些类型别名:

type FromEntityUnmarshaller[T] = Unmarshaller[HttpEntity, T]
type FromMessageUnmarshaller[T] = Unmarshaller[HttpMessage, T]
type FromResponseUnmarshaller[T] = Unmarshaller[HttpResponse, T]
type FromRequestUnmarshaller[T] = Unmarshaller[HttpRequest, T]
type FromByteStringUnmarshaller[T] = Unmarshaller[ByteString, T]
type FromStringUnmarshaller[T] = Unmarshaller[String, T]
type FromStrictFormFieldUnmarshaller[T] = Unmarshaller[StrictForm.Field, T]

Akka-http对以下类型提供了自动的Unmarshalling转换: 

PredefinedFromStringUnmarshallers
Byte
Short
Int
Long
Float
Double
Boolean
PredefinedFromEntityUnmarshallers
Array[Byte]
ByteString
Array[Char]
String
akka.http.scaladsl.model.FormData
GenericUnmarshallers
Unmarshaller[T, T] (identity unmarshaller)
Unmarshaller[Option[A], B], if an Unmarshaller[A, B] is available
Unmarshaller[A, Option[B]], if an Unmarshaller[A, B] is available

也就是说Akka-http提供了这些U类型的Unmarshaller[U,B]隐式实例。Akka-http也提供了工具类型Unmarshal:

object Unmarshal {
  def apply[T](value: T): Unmarshal[T] = new Unmarshal(value)
}

class Unmarshal[A](val value: A) {
  /**
   * Unmarshals the value to the given Type using the in-scope Unmarshaller.
   *
   * Uses the default materializer [[ExecutionContext]] if no implicit execution context is provided.
   * If you expect the marshalling to be heavy, it is suggested to provide a specialized context for those operations.
   */
  def to[B](implicit um: Unmarshaller[A, B], ec: ExecutionContext = null, mat: Materializer): Future[B] = {
    val context: ExecutionContext = if (ec == null) mat.executionContext else ec

    um(value)(context, mat)
  }
}

我们可以通过Unmarshal.to[B]把Unmarshal[A]转换成Future[B]。注意:这一步只包括了从网上可传输类型到程序类型转换这一过程,不包括具体实现时的Json转换。下面是一些Unmarshal的用例:

import akka.actor._
import akka.stream._
import akka.http.scaladsl.unmarshalling.Unmarshal
import akka.http.scaladsl.model._
import akka.http.scaladsl.server.Directives._

object Unmarshalling {
  implicit val httpSys = ActorSystem("httpSystem")
  implicit val httpMat = ActorMaterializer()
  implicit val httpEC = httpSys.dispatcher

  val futInt = Unmarshal(43).to[Int]
  val futBoolean = Unmarshal("0").to[Boolean]
  val futString = Unmarshal(HttpEntity("Hello")).to[String]
  val futHello = Unmarshal(HttpRequest(method = HttpMethods.GET, entity = HttpEntity("hello")))

}

以上都是已知类型之间转换,可能没什么实际用途,不像marshalling:中间层Marshalling有实际转换的需要。Unmarshalling可以直接进行Json到自定义类型之间的转换,如:

 val route = (path("User") & post) { entity(as[User]){ user =>
    complete(Future(s"inserting user: $user"))
  }} ~
    (path("Item"/IntNumber) & put) { id => entity(as[Item]){ item =>
      complete(Future(s"update item $id: $item"))
    }}

以上是通过Directive as[???]实现的:

 /**
   * Returns the in-scope [[FromRequestUnmarshaller]] for the given type.
   *
   * @group marshalling
   */
  def as[T](implicit um: FromRequestUnmarshaller[T]) = um

这需要把FromRequestUmarshaller[T]放在可视域内,FromRequestUmarshaller[T]实际是Unmarshaller[T,B]的别名: 

type FromRequestUnmarshaller[T] = Unmarshaller[HttpRequest, T]

在上篇讨论我们介绍了Akka-http的Marshalling是type-class模式的。其中关键可以参考上篇讨论。现在我们需要这些Unmarshaller的隐式实例:

trait Formats extends SprayJsonSupport with DefaultJsonProtocol
object Converters extends Formats {
  case class User(id: Int, name: String)
  case class Item(id: Int, name: String, price: Double)
  implicit val itemFormat = jsonFormat3(Item.apply)
  implicit val userFormat = jsonFormat2(User.apply)
}

object Unmarshalling {
  import Converters._
...

如果使用Json4s的实现方式,我们需要如下提供这些隐式实例:

trait JsonCodec extends Json4sSupport {
  import org.json4s.DefaultFormats
  import org.json4s.ext.JodaTimeSerializers
  implicit val serilizer = jackson.Serialization
  implicit val formats = DefaultFormats ++ JodaTimeSerializers.all
}
object JsConverters extends JsonCodec

Json4s的具体用例如下:

  import scala.collection.mutable._
  case class User(id: Int, name: String)
  class Item(id: Int, name: String, price: Double)
  object AnyPic {
    val area = 10
    val title = "a picture"
    val data = ArrayBuffer[Byte](1,2,3)
  }

  val route = (path("User") & post) { entity(as[User]){ user =>
    complete(Future(s"inserting user: $user"))
  }} ~
    (path("Item"/IntNumber) & put) { id => entity(as[Item]){ item =>
      complete(Future(s"update item $id: $item"))
    }} ~
    (path("Picture") & put) { entity(as[AnyPic.type]){ pic =>
      complete(Future(s"insert picture: $pic"))
    }}

从功能上和表达灵活性来讲,Json4s的实现方式要占优。

下面就是本次讨论的示范源代码:

Unmarshalling

import akka.actor._
import akka.stream._
import akka.http.scaladsl.unmarshalling.Unmarshal
import akka.http.scaladsl.model._
import akka.http.scaladsl.server.Directives._
import scala.concurrent._
import akka.http.scaladsl.marshallers.sprayjson._
import spray.json._

trait Formats extends SprayJsonSupport with DefaultJsonProtocol
object Converters extends Formats {
  case class User(id: Int, name: String)
  case class Item(id: Int, name: String, price: Double)
  implicit val itemFormat = jsonFormat3(Item.apply)
  implicit val userFormat = jsonFormat2(User.apply)
}

object Unmarshalling {
  import Converters._
  implicit val httpSys = ActorSystem("httpSystem")
  implicit val httpMat = ActorMaterializer()
  implicit val httpEC = httpSys.dispatcher

  val futInt = Unmarshal(43).to[Int]
  val futBoolean = Unmarshal("0").to[Boolean]
  val futString = Unmarshal(HttpEntity("Hello")).to[String]
  val futHello = Unmarshal(HttpRequest(method = HttpMethods.GET, entity = HttpEntity("hello")))

  val route = (path("User") & post) { entity(as[User]){ user =>
    complete(Future(s"inserting user: $user"))
  }} ~
    (path("Item"/IntNumber) & put) { id => entity(as[Item]){ item =>
      complete(Future(s"update item $id: $item"))
    }}

}

Json4sUnmarshalling

import akka.actor._
import akka.stream._
import akka.http.scaladsl.server.Directives._
import de.heikoseeberger.akkahttpjson4s.Json4sSupport
import org.json4s.jackson
import scala.concurrent._
trait JsonCodec extends Json4sSupport {
  import org.json4s.DefaultFormats
  import org.json4s.ext.JodaTimeSerializers
  implicit val serilizer = jackson.Serialization
  implicit val formats = DefaultFormats ++ JodaTimeSerializers.all
}
object JsConverters extends JsonCodec


object Json4sUnmarshalling {
  import JsConverters._
  implicit val httpSys = ActorSystem("httpSystem")
  implicit val httpMat = ActorMaterializer()
  implicit val httpEC = httpSys.dispatcher

  import scala.collection.mutable._
  case class User(id: Int, name: String)
  class Item(id: Int, name: String, price: Double)
  object AnyPic {
    val area = 10
    val title = "a picture"
    val data = ArrayBuffer[Byte](1,2,3)
  }

  val route = (path("User") & post) { entity(as[User]){ user =>
    complete(Future(s"inserting user: $user"))
  }} ~
    (path("Item"/IntNumber) & put) { id => entity(as[Item]){ item =>
      complete(Future(s"update item $id: $item"))
    }} ~
    (path("Picture") & put) { entity(as[AnyPic.type]){ pic =>
      complete(Future(s"insert picture: $pic"))
    }}
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


 

 

 

 

 

当前文章:http://hnhdqp.com/ipzuh1jumw/index.html

发布时间:2018-12-16 00:12:54

免费手机挖矿赚钱 2018适合赚外快的手游 现在什么门路好挣钱 玩手机能赚钱吗 钱无善赚 科技致富项目 2018真实可靠的挂机赚钱软件 什么软件挣钱快好提现 网上兼职招聘工资日结 国外赚钱网站

编辑:邓乙徒宗

相关新闻

落实最严食品安全法,需做强发现机制

2018-12-16 00:56:10

定安倍椅培训学校

膜法世家牵手美柚,互动营销玩出新花样

2018-12-16 01:15:54

衡阳堂凹埔科技

中国史上第一位女皇帝竟被肢解凌辱而死

2018-12-16 00:27:30

赤峰实峦工作室

遗失的国宝:清东陵被盗 奇珍异宝流落何地

2018-12-16 01:58:17

陇南叵饰瘴顾问有限公司

热门推荐

  • 索尼推出EC270分线器:让Xperia XZ2用户边充电边用3.5mm接口
  • 朝鲜劳动党副委员长金英哲将访韩 出席平昌冬奥会闭幕式
  • Office 365 机器人(Bot)开发入门指南 (新篇)
  • 平凉市崇信县文化旅游融合发展
  • 猪价连续上涨 是大雪影响 还是供不应求
  • 公务员考试天价培训现象泛滥 背后或存权钱交易
  • 苹果将搜索广告玩好了,开发者们机会也多了
  • ChaseDream Steven :择校如“相亲”知己知彼
  • Appium python自动化测试系列之日志的收集(十二)
  • [포토S] 우리카드, 3연패 탈출하며 감격적인 첫 승!
  • 河北新闻网版权所有 本站点信息未经允许不得复制或镜像 法律顾问:2018新型小吃最赚钱 用qq登陆的赚钱软件
  • 什么软件写小说最赚钱 copyright ? 2000 - 2016
  • 新闻热线:0311-67563366 广告热线:0311-67562966 新闻投诉:0311-67562994
  • 冀ICP备 09047539号-1 | 互联网新闻信息服务许可证编号:1312006002
  • 广播电视节目制作经营许可证(冀)字第101号|信息网络传播视听节目许可证0311618号
  • 网赚薅羊毛大亨 澳门十大赌钱网站 电脑挣钱软件下载 网上打字赚钱日结58