squbs-6. 序列化和反序列化

原文地址:Marshalling and Unmarshalling

概览

序列化和反序列化同时在客户端和服务端使用。在服务端,它用于映射进来的请求至Scala或Java对象来输出相应。相似的,在客户端,它将用于序列化对象来传出HTTP请求和从进来的相应中反序列化它。这里有多种内容格式来序列化和反序列化,常见的有JSON和XML。

Akka HTTP 提供序列化/反序列化功能在 Scala marshalling/unmarshallingJava marshalling/unmarshalling中阐述。同样的,有为Akka HTTP提供其他开源的序列化和反序列化,可用于不同格式和使用不同对象的序列化反序列实现。

squbs为手动序列化/反序列化提供JAVA API,以及添加在 Scala/Java 跨语言环境中工作工具。手动访问解析器和反解析器对于基于流的应用是有用的,在某些工作需要在流阶段完成。他同时对测试解析器配置式有用的,来保证实现正确的格式。

这篇文章讨论squbs提供的解析器和反解析器,你可以使用工具来手动调用这些解析器和反解析器。这个文档不再 作为 Akka HTTP路由DSL的一部分来阐述解析器和反解析器的作用。请查看Akka HTTP 路由 DSL ScalaJava 中的解析指令(包括在这篇文章中提供的)来使用解析器。

依赖

在你的 build.sbt 或scala构建文件中加入以下依赖:

"org.squbs" %% "squbs-ext" % squbsVersion

用法

JacksonMapperSupport

JacksonMapperSupport提供基于当前流行的Jackson类库的JSON解析器和泛解析器。它允许全局的和单独的Jackson ObjectMapper配置。
更多关于ObjectMapper的配置细节请参见Jackson Data Binding documentation

Scala
import org.squbs.marshallers.json.JacksonMapperSupport._

自动和手动解析器都将在这个包中隐式的使用这个解释器。下面这个代码的例子展示了通过ObjectMapper配置DefaultScalaModule的不同方式。

import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.scala.DefaultScalaModule
import org.squbs.marshallers.json.JacksonMapperSupport

/* To use DefaultScalaModule for all classes.
 */

JacksonMapperSupport.setDefaultMapper(
  new ObjectMapper().registerModule(DefaultScalaModule))


/* To register a 'DefaultScalaModule' for marshalling a
 * specific class, overrides global configuration for
 * this class.
 */

JacksonMapperSupport.register[MyScalaClass](
  new ObjectMapper().registerModule(DefaultScalaModule))
Java

解析器和反解析器可以从JacksonMapperSupportmarshallerunmarshaller方法中获取,将类的实例类型传递来序列化/反序列化如下:

import akka.http.javadsl.marshalling.Marshaller;
import akka.http.javadsl.model.HttpEntity;
import akka.http.javadsl.model.RequestEntity;
import akka.http.javadsl.unmarshalling.Unmarshaller;

import static org.squbs.marshallers.json.JacksonMapperSupport.*;

Marshaller<MyClass, RequestEntity> myMarshaller =
    marshaller(MyClass.class);

Unmarshaller<HttpEntity, MyClass> myUnmarshaller =
    unmarshaller(MyClass.class);

在本文中的讨论中,这些解析器可以作为Akka HTTP Routing DSL 的一部分或 invoking marshalling/unmarshalling的一部分使用。

下面的例子通过 ObjectMapper配置 DefaultScalaModule

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.module.scala.DefaultScalaModule;
import org.squbs.marshallers.json.JacksonMapperSupport;

/* Globally registers the 'DefaultScalaModule'.
 */
 
JacksonMapperSupport.setDefaultMapper(
  new ObjectMapper().registerModule(new DefaultScalaModule()));


/* This example below registers the 'DefaultScalaModule'
 * just for 'MyClass'
 */

JacksonMapperSupport.register(MyClass.class
  new ObjectMapper().registerModule(new DefaultScalaModule()));

XLangJsonSupport

XLangJsonSupport通过委托序列化和反序列化加入跨语言支持:

  • Json4s for Scala classes
  • Jackson for Java classes

这些通常是每个语言首选的解析器,无需更多的配置,他们即支持特定语言约定。他们同样对不同的约定通常有更好的优化。

然而,这个使用Json4s或Jackson的决定取决于用户序列化/反序列化传入的对象的类型。如果你有一个混合对象层次结构,你可能需要配置序列化/反序列化工具来支持不同的约定,如下所示:

  • Scala case class 引用Java Beans. 如果顶级对象是一个 Scala case class。 Json4s将被选择。然而它不知道如何序列化/反序列化 Java Beans。一个自定义的序列化需要加入到Json4来处理Java Bean。

  • Java Beans引用 Scala case class。如果顶级对象是Java Bean,Jackson将被选择。Jackson默认不支持如何序列化/反序列化这些 case class。你需要注册 DefaultScalaModule至Jackson ObjectMapper 来处理这些情况。

一个通用的序列化/反序列化混合语言对象层次结构的准则:除非Json4s优化是首选的,配置Jackson处理Scala更简单,只需要向ObjectMapper注册DefaultScalaModule

JacksonMapperSupport,它支持每种类型的解析器和反解析器配置。它允许配置Json4s 和 Jackson。

Scala

你只需要导入 XLangJsonSupport._来暴露它在解析器和反解析器使用Scala代码范围内的隐藏成员。

自动和手动解析器将隐式使用这个包提供的解析器。下面提供配置XLangJsonSupport的例子:

import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.paramnames.ParameterNamesModule
import org.json4s.{DefaultFormats, jackson, native}
import org.squbs.marshallers.json.XLangJsonSupport

/* The following configures the default settings
 * for 'XLangJsonSupport'
 */

// Adds ParameterNamesModule to Jackson
XLangJsonSupport.setDefaultMapper(
  new ObjectMapper().registerModule(new ParameterNamesModule())
  
// Tells Json4s to use native serialization
XLangJsonSupport.setDefaultSerialization(native.Serialization)

// Adds MySerializer to the serializers used by Json4s
XLangJsonSupport.setDefaultFormats(DefaultFormats + MySerializer)


/* The following configures XLangJsonSupport for specific class.
 * Namely, it configures for 'MyClass' and 'MyOtherClass'.
 */

// Use ParameterNamesModule for mashal/unmarshal MyClass
XLangJsonSupport.register[MyClass](new ParameterNamesModule()))

// Use Json4s Jackson serialization for MyOtherClass
XLangJsonSupport.register[MyOtherClass](jackson.Serialization)

// Use MySerializer Json4s serializer for MyOtherClass
XLangJsonSupport.register[MyOtherClass](DefaultFormats + MySerializer)
Java

解析器和反解析器可以从XLangJsonSupport中的 marshallerunmarshaller方法中获取,传递类实例的类型来序列化/反序列化,如下:

import akka.http.javadsl.marshalling.Marshaller;
import akka.http.javadsl.model.HttpEntity;
import akka.http.javadsl.model.RequestEntity;
import akka.http.javadsl.unmarshalling.Unmarshaller;

import static org.squbs.marshallers.json.XLangJsonSupport.*;

Marshaller<MyClass, RequestEntity> myMarshaller =
    marshaller(MyClass.class);

Unmarshaller<HttpEntity, MyClass> myUnmarshaller =
    unmarshaller(MyClass.class);

在本文讨论中,这些解析器和反解析器可以作为 Akka HTTP Routing DSL 的一部分或invoking marshalling/unmarshalling的一部分使用,如下:

下面提供配置XLangJsonSupport的例子:

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.module.paramnames.ParameterNamesModule;
import org.squbs.marshallers.json.XLangJsonSupport;

/* Global XLangJsonSupport Configuration.
 */

// Adds ParameterNamesModule to Jackson
XLangJsonSupport.setDefaultMapper(
  new ObjectMapper().registerModule(new ParameterNamesModule());
  
// Tells Json4s to use native serialization
XLangJsonSupport.setDefaultSerialization(XLangJsonSupport.nativeSerialization());

// Adds MySerializer and MyOtherSerializer (varargs) to the serializers used by Json4s
XLangJsonSupport.addDefaultSerializers(new MySerializer(), new MyOtherSerializer());


/* Per-class configuration of 'XLangJsonSupport'.
 * In this case we show configuring 'MyClass' and 'MyOtherClass'
 */

// Use ParameterNamesModule for mashal/unmarshal MyClass
XLangJsonSupport.register(MyClass.class, new ParameterNamesModule()));

// Use Json4s Jackson serialization for MyOtherClass
XLangJsonSupport.register(MyOtherClass.class, XLangJsonSupport.jacksonSerialization());

// Adds MySerializer and MyOtherSerializer (varargs) to the serializers used by Json4s for MyOtherClass
XLangJsonSupport.addSerializers(MyOtherClass.class, new MySerializer(), new MyOtherSerializer());

调用序列化/反序列化

除了使用解析器和反解析器作为Akka HTTP Routing DSL的一部分,手动调用序列化/反序列化常常用在服务端和客户端的流和测试中。

Scala

Akka提供 Scala DSL 来实现序列化和反序列化。它的使用例子可以如下所示:

import akka.actor.ActorSystem
import akka.http.scaladsl.marshalling.Marshal
import akka.http.scaladsl.model.MessageEntity
import akka.http.scaladsl.unmarshalling.Unmarshal
import akka.stream.ActorMaterializer

// We need the ActorSystem and Materializer to marshal/unmarshal
implicit val system = ActorSystem()
implicit val mat = ActorMaterializer()

// Also need the implicit marshallers provided by this import
import org.squbs.marshallers.json.XLangJsonSupport._

// Just call Marshal or Unmarshal as follows:
Marshal(myObject).to[MessageEntity]
Unmarshal(entity).to[MyType]
Java

用Akka HTTP's JavaDSL中定义的MarshallerUnmarshallerMarshalUnmarshal工具类来手动序列化和反序列化对象。例子如下:

import akka.actor.ActorSystem;
import akka.http.javadsl.model.RequestEntity;
import akka.stream.ActorMaterializer;
import akka.stream.Materializer;

import org.squbs.marshallers.MarshalUnmarshal;

// We're using JacksonMapperSupport here.
// But XLangJsonSupport works the same.
import static org.squbs.marshallers.json.JacksonMapperSupport.*;

// Base infrastructure, and the 'mu' MarshalUnmarshal. 
private final ActorSystem system = ActorSystem.create();
private final Materializer mat = ActorMaterializer.create(system);
private final MarshalUnmarshal mu = new MarshalUnmarshal(system.dispatcher(), mat);

// Call 'apply' passing marshaller or unmarshaller as follows, using marshaller
// and unmarshaller methods from 'import static JacksonMapperSupport.*;':
CompletionStage<RequestEntity> mf = mu.apply(marshaller(MyClass.class), myObject);
CompletionStage<MyClass> uf = mu.apply(unmarshaller(MyClass.class), entity);
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342

推荐阅读更多精彩内容