美文网首页squbsScala In Action
squbs-6. 序列化和反序列化

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

作者: 吕亦行 | 来源:发表于2017-01-23 20:04 被阅读185次

    原文地址: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);
    

    相关文章

      网友评论

        本文标题:squbs-6. 序列化和反序列化

        本文链接:https://www.haomeiwen.com/subject/yjsabttx.html