簡體   English   中英

Jackson Scala模塊:序列化枚舉失敗

[英]Jackson scala module: serialize Enumeration fails

有人可以解釋一下為什么這行不通嗎? 我在Jackson上使用Scala模塊。

我的依賴項是"com.fasterxml.jackson.module" %% "jackson-module-scala" % "2.1.3"

我的序列化器是:

import org.bson.types.ObjectId
import com.fasterxml.jackson.databind.module.SimpleModule
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.scala.DefaultScalaModule

object CustomSerializer {

  val objectMapper = new ObjectMapper()

  val module = new SimpleModule("CustomSerializer")
  module.addSerializer(classOf[Throwable], new ThrowableSerializer)
  module.addSerializer(classOf[ObjectId], new ObjectIdSerializer)
  module.addDeserializer(classOf[ObjectId], new ObjectIdDeserializer)
  val scalaModule = DefaultScalaModule

  objectMapper.registerModule(scalaModule)
  objectMapper.registerModule(module)

  def serialize(obj: AnyRef): String = {
    objectMapper.writeValueAsString(obj)
  }

}

沒什么好看的,我只是將Scala模塊添加到默認的序列化器+一些MongoDB ObjectId類的序列化器。


這是我的簡單測試代碼:

@JsonIgnoreProperties(ignoreUnknown = true)
case class Relationship(
                         @Key("_id") id: ObjectId = new ObjectId,
                         fromUserId: ObjectId,
                         fromUserConfiguration: RelationshipConfiguration = new RelationshipConfiguration,
                         toUserId: ObjectId,
                         toUserConfiguration: RelationshipConfiguration = new RelationshipConfiguration,
                        status: RelationshipStatus.Value,
                         ) extends IdentifiableModel[Relationship] {

  ... some methods here
}

    case class SimpleCaseClass(string: String)
    case class SimpleCaseClassWithEnum(string: String,status: RelationshipStatus.Value)

    println(
      CustomSerializer.serialize( SimpleCaseClass("someString") )
    )
    println(
      CustomSerializer.serialize( SimpleCaseClassWithEnum("someString",RelationshipStatus.ACCEPTED) )
    )

    println(
      CustomSerializer.serialize(
        Relationship(
          fromUserId = new ObjectId("510f9398ed5080cb1265c8c2"),
          toUserId = new ObjectId("510f9398ed5080cb1265c8c2"),
          status = RelationshipStatus.ACCEPTED
        )
      )
    )

產生輸出:

{"string":"someString"}
{"string":"someString","status":{"enumClass":"models.RelationshipStatus","value":"ACCEPTED"}}
[21:35:58] ERROR application - 

! @6e03dp6pp - Internal server error, for (GET) [/me] ->

play.api.UnexpectedException: Unexpected exception[RuntimeException: Cannot resolve type alias Value in models.RelationshipStatus]
    at play.core.ReloadableApplication$$anonfun$get$1$$anonfun$1.apply(ApplicationProvider.scala:142) ~[play_2.10.jar:2.1.0]
    at play.core.ReloadableApplication$$anonfun$get$1$$anonfun$1.apply(ApplicationProvider.scala:106) ~[play_2.10.jar:2.1.0]
    at scala.Option.map(Option.scala:145) ~[scala-library.jar:na]
    at play.core.ReloadableApplication$$anonfun$get$1.apply(ApplicationProvider.scala:106) ~[play_2.10.jar:2.1.0]
    at play.core.ReloadableApplication$$anonfun$get$1.apply(ApplicationProvider.scala:104) ~[play_2.10.jar:2.1.0]
    at scala.util.Either$RightProjection.flatMap(Either.scala:523) [scala-library.jar:na]
    at play.core.ReloadableApplication.get(ApplicationProvider.scala:104) ~[play_2.10.jar:2.1.0]
    at play.core.server.Server$class.sendHandler$1(Server.scala:56) [play_2.10.jar:2.1.0]
    at play.core.server.Server$$anonfun$getHandlerFor$4.apply(Server.scala:88) [play_2.10.jar:2.1.0]
    at play.core.server.Server$$anonfun$getHandlerFor$4.apply(Server.scala:87) [play_2.10.jar:2.1.0]
    at scala.util.Either$RightProjection.flatMap(Either.scala:523) [scala-library.jar:na]
    at play.core.server.Server$class.getHandlerFor(Server.scala:87) [play_2.10.jar:2.1.0]
    at play.core.server.NettyServer.getHandlerFor(NettyServer.scala:34) [play_2.10.jar:2.1.0]
    at play.core.server.netty.PlayDefaultUpstreamHandler.messageReceived(PlayDefaultUpstreamHandler.scala:103) [play_2.10.jar:2.1.0]
    at org.jboss.netty.channel.SimpleChannelUpstreamHandler.handleUpstream(SimpleChannelUpstreamHandler.java:75) [netty.jar:na]
    at org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:565) [netty.jar:na]
    at org.jboss.netty.channel.DefaultChannelPipeline$DefaultChannelHandlerContext.sendUpstream(DefaultChannelPipeline.java:793) [netty.jar:na]
    at org.jboss.netty.handler.codec.http.HttpContentDecoder.messageReceived(HttpContentDecoder.java:104) [netty.jar:na]
    at org.jboss.netty.channel.SimpleChannelUpstreamHandler.handleUpstream(SimpleChannelUpstreamHandler.java:75) [netty.jar:na]
    at org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:565) [netty.jar:na]
    at org.jboss.netty.channel.DefaultChannelPipeline$DefaultChannelHandlerContext.sendUpstream(DefaultChannelPipeline.java:793) [netty.jar:na]
    at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:296) [netty.jar:na]
    at org.jboss.netty.handler.codec.frame.FrameDecoder.unfoldAndFireMessageReceived(FrameDecoder.java:455) [netty.jar:na]
    at org.jboss.netty.handler.codec.replay.ReplayingDecoder.callDecode(ReplayingDecoder.java:538) [netty.jar:na]
    at org.jboss.netty.handler.codec.replay.ReplayingDecoder.messageReceived(ReplayingDecoder.java:437) [netty.jar:na]
    at org.jboss.netty.channel.SimpleChannelUpstreamHandler.handleUpstream(SimpleChannelUpstreamHandler.java:75) [netty.jar:na]
    at org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:565) [netty.jar:na]
    at org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:560) [netty.jar:na]
    at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:268) [netty.jar:na]
    at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:255) [netty.jar:na]
    at org.jboss.netty.channel.socket.nio.NioWorker.read(NioWorker.java:84) [netty.jar:na]
    at org.jboss.netty.channel.socket.nio.AbstractNioWorker.processSelectedKeys(AbstractNioWorker.java:472) [netty.jar:na]
    at org.jboss.netty.channel.socket.nio.AbstractNioWorker.run(AbstractNioWorker.java:333) [netty.jar:na]
    at org.jboss.netty.channel.socket.nio.NioWorker.run(NioWorker.java:35) [netty.jar:na]
    at org.jboss.netty.util.ThreadRenamingRunnable.run(ThreadRenamingRunnable.java:102) [netty.jar:na]
    at org.jboss.netty.util.internal.DeadLockProofWorker$1.run(DeadLockProofWorker.java:42) [netty.jar:na]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110) [na:1.7.0_01]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603) [na:1.7.0_01]
    at java.lang.Thread.run(Thread.java:722) [na:1.7.0_01]
Caused by: java.lang.RuntimeException: Cannot resolve type alias Value in models.RelationshipStatus
    at org.scalastuff.scalabeans.sig.ScalaTypeCompiler.resolveTypeAlias(ScalaTypeCompiler.scala:202) ~[jackson-module-scala_2.10-2.1.3.jar:na]
    at org.scalastuff.scalabeans.sig.ScalaTypeCompiler.getTypeDecl$1(ScalaTypeCompiler.scala:159) ~[jackson-module-scala_2.10-2.1.3.jar:na]
    at org.scalastuff.scalabeans.sig.ScalaTypeCompiler.resolveScalaType(ScalaTypeCompiler.scala:167) ~[jackson-module-scala_2.10-2.1.3.jar:na]
    at org.scalastuff.scalabeans.sig.ScalaTypeCompiler$$anonfun$3.apply(ScalaTypeCompiler.scala:146) ~[jackson-module-scala_2.10-2.1.3.jar:na]
    at org.scalastuff.scalabeans.sig.ScalaTypeCompiler$$anonfun$3.apply(ScalaTypeCompiler.scala:145) ~[jackson-module-scala_2.10-2.1.3.jar:na]
    at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244) ~[scala-library.jar:na]
    at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244) ~[scala-library.jar:na]
    at scala.collection.mutable.ResizableArray$class.foreach(ResizableArray.scala:59) ~[scala-library.jar:na]
    at scala.collection.mutable.ArrayBuffer.foreach(ArrayBuffer.scala:47) ~[scala-library.jar:na]
    at scala.collection.TraversableLike$class.map(TraversableLike.scala:244) ~[scala-library.jar:na]
    at scala.collection.AbstractTraversable.map(Traversable.scala:105) ~[scala-library.jar:na]
    at org.scalastuff.scalabeans.sig.ScalaTypeCompiler.compile(ScalaTypeCompiler.scala:145) ~[jackson-module-scala_2.10-2.1.3.jar:na]
    at org.scalastuff.scalabeans.sig.ScalaTypeCompiler$$anonfun$1$$anonfun$apply$2.apply(ScalaTypeCompiler.scala:51) ~[jackson-module-scala_2.10-2.1.3.jar:na]
    at org.scalastuff.scalabeans.sig.ScalaTypeCompiler$$anonfun$1$$anonfun$apply$2.apply(ScalaTypeCompiler.scala:48) ~[jackson-module-scala_2.10-2.1.3.jar:na]
    at scala.Option$WithFilter.map(Option.scala:206) ~[scala-library.jar:na]
    at org.scalastuff.scalabeans.sig.ScalaTypeCompiler$$anonfun$1.apply(ScalaTypeCompiler.scala:48) ~[jackson-module-scala_2.10-2.1.3.jar:na]
    at org.scalastuff.scalabeans.sig.ScalaTypeCompiler$$anonfun$1.apply(ScalaTypeCompiler.scala:47) ~[jackson-module-scala_2.10-2.1.3.jar:na]
    at scala.Option.flatMap(Option.scala:170) ~[scala-library.jar:na]
    at org.scalastuff.scalabeans.sig.ScalaTypeCompiler$.classInfoOf(ScalaTypeCompiler.scala:47) ~[jackson-module-scala_2.10-2.1.3.jar:na]
    at org.scalastuff.scalabeans.PropertyDescriptor$$anonfun$4.apply(PropertyDescriptor.scala:225) ~[jackson-module-scala_2.10-2.1.3.jar:na]
    at org.scalastuff.scalabeans.PropertyDescriptor$$anonfun$4.apply(PropertyDescriptor.scala:224) ~[jackson-module-scala_2.10-2.1.3.jar:na]
    at scala.Option.flatMap(Option.scala:170) ~[scala-library.jar:na]
    at org.scalastuff.scalabeans.PropertyDescriptor$.apply(PropertyDescriptor.scala:224) ~[jackson-module-scala_2.10-2.1.3.jar:na]
    at com.fasterxml.jackson.module.scala.util.SmarterBeanIntrospector$.com$fasterxml$jackson$module$scala$util$SmarterBeanIntrospector$$createPropertyDescriptor$1(ScalaBeansUtil.scala:68) ~[jackson-module-scala_2.10-2.1.3.jar:na]
    at com.fasterxml.jackson.module.scala.util.SmarterBeanIntrospector$$anonfun$5$$anonfun$apply$5.apply(ScalaBeansUtil.scala:103) ~[jackson-module-scala_2.10-2.1.3.jar:na]
    at com.fasterxml.jackson.module.scala.util.SmarterBeanIntrospector$$anonfun$5$$anonfun$apply$5.apply(ScalaBeansUtil.scala:94) ~[jackson-module-scala_2.10-2.1.3.jar:na]
    at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244) ~[scala-library.jar:na]
    at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244) ~[scala-library.jar:na]
    at scala.collection.IndexedSeqOptimized$class.foreach(IndexedSeqOptimized.scala:33) ~[scala-library.jar:na]
    at scala.collection.mutable.ArrayOps$ofRef.foreach(ArrayOps.scala:105) ~[scala-library.jar:na]
    at scala.collection.TraversableLike$class.map(TraversableLike.scala:244) ~[scala-library.jar:na]
    at scala.collection.mutable.ArrayOps$ofRef.map(ArrayOps.scala:105) ~[scala-library.jar:na]
    at com.fasterxml.jackson.module.scala.util.SmarterBeanIntrospector$$anonfun$5.apply(ScalaBeansUtil.scala:94) ~[jackson-module-scala_2.10-2.1.3.jar:na]
    at com.fasterxml.jackson.module.scala.util.SmarterBeanIntrospector$$anonfun$5.apply(ScalaBeansUtil.scala:93) ~[jackson-module-scala_2.10-2.1.3.jar:na]
    at scala.collection.TraversableLike$$anonfun$flatMap$1.apply(TraversableLike.scala:251) ~[scala-library.jar:na]
    at scala.collection.TraversableLike$$anonfun$flatMap$1.apply(TraversableLike.scala:251) ~[scala-library.jar:na]
    at scala.collection.immutable.List.foreach(List.scala:309) ~[scala-library.jar:na]
    at scala.collection.TraversableLike$class.flatMap(TraversableLike.scala:251) ~[scala-library.jar:na]
    at scala.collection.AbstractTraversable.flatMap(Traversable.scala:105) ~[scala-library.jar:na]
    at com.fasterxml.jackson.module.scala.util.SmarterBeanIntrospector$.apply(ScalaBeansUtil.scala:93) ~[jackson-module-scala_2.10-2.1.3.jar:na]
    at com.fasterxml.jackson.module.scala.util.ScalaBeansUtil$.propertiesOf(ScalaBeansUtil.scala:166) ~[jackson-module-scala_2.10-2.1.3.jar:na]
    at com.fasterxml.jackson.module.scala.deser.CaseClassAnnotationIntrospector$.findConstructorParamName(CaseClassDeserializerModule.scala:51) ~[jackson-module-scala_2.10-2.1.3.jar:na]
    at com.fasterxml.jackson.module.scala.deser.CaseClassAnnotationIntrospector$.findDeserializationName(CaseClassDeserializerModule.scala:41) ~[jackson-module-scala_2.10-2.1.3.jar:na]
    at com.fasterxml.jackson.databind.AnnotationIntrospector.findNameForDeserialization(AnnotationIntrospector.java:915) ~[jackson-databind-2.1.2.jar:2.1.2]
    at com.fasterxml.jackson.databind.introspect.AnnotationIntrospectorPair.findNameForDeserialization(AnnotationIntrospectorPair.java:606) ~[jackson-databind-2.1.2.jar:2.1.2]
    at com.fasterxml.jackson.databind.introspect.POJOPropertiesCollector._addCreators(POJOPropertiesCollector.java:405) ~[jackson-databind-2.1.2.jar:2.1.2]
    at com.fasterxml.jackson.databind.introspect.POJOPropertiesCollector.collect(POJOPropertiesCollector.java:233) ~[jackson-databind-2.1.2.jar:2.1.2]
    at com.fasterxml.jackson.databind.introspect.BasicClassIntrospector.collectProperties(BasicClassIntrospector.java:142) ~[jackson-databind-2.1.2.jar:2.1.2]
    at com.fasterxml.jackson.databind.introspect.BasicClassIntrospector.forSerialization(BasicClassIntrospector.java:68) ~[jackson-databind-2.1.2.jar:2.1.2]
    at com.fasterxml.jackson.databind.introspect.BasicClassIntrospector.forSerialization(BasicClassIntrospector.java:11) ~[jackson-databind-2.1.2.jar:2.1.2]
    at com.fasterxml.jackson.databind.SerializationConfig.introspect(SerializationConfig.java:490) ~[jackson-databind-2.1.2.jar:2.1.2]
    at com.fasterxml.jackson.databind.ser.BeanSerializerFactory.createSerializer(BeanSerializerFactory.java:131) ~[jackson-databind-2.1.2.jar:2.1.2]
    at com.fasterxml.jackson.databind.ser.SerializerFactory.createSerializer(SerializerFactory.java:53) ~[jackson-databind-2.1.2.jar:2.1.2]
    at com.fasterxml.jackson.databind.SerializerProvider._createUntypedSerializer(SerializerProvider.java:935) ~[jackson-databind-2.1.2.jar:2.1.2]
    at com.fasterxml.jackson.databind.SerializerProvider._createAndCacheUntypedSerializer(SerializerProvider.java:892) ~[jackson-databind-2.1.2.jar:2.1.2]
    at com.fasterxml.jackson.databind.SerializerProvider.findValueSerializer(SerializerProvider.java:429) ~[jackson-databind-2.1.2.jar:2.1.2]
    at com.fasterxml.jackson.databind.SerializerProvider.findTypedValueSerializer(SerializerProvider.java:520) ~[jackson-databind-2.1.2.jar:2.1.2]
    at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:99) ~[jackson-databind-2.1.2.jar:2.1.2]
    at com.fasterxml.jackson.databind.ObjectMapper._configAndWriteValue(ObjectMapper.java:2627) ~[jackson-databind-2.1.2.jar:2.1.2]
    at com.fasterxml.jackson.databind.ObjectMapper.writeValueAsString(ObjectMapper.java:2119) ~[jackson-databind-2.1.2.jar:2.1.2]
    at utils.CustomSerializer$.serialize(CustomSerializer.scala:24) ~[na:na]
    at Global$.onStart(Global.scala:36) ~[na:na]
    at play.api.GlobalPlugin.onStart(GlobalSettings.scala:175) ~[play_2.10.jar:2.1.0]
    at play.api.Play$$anonfun$start$1$$anonfun$apply$mcV$sp$1.apply(Play.scala:63) ~[play_2.10.jar:2.1.0]
    at play.api.Play$$anonfun$start$1$$anonfun$apply$mcV$sp$1.apply(Play.scala:63) ~[play_2.10.jar:2.1.0]
    at scala.collection.immutable.List.foreach(List.scala:309) ~[scala-library.jar:na]
    at play.api.Play$$anonfun$start$1.apply$mcV$sp(Play.scala:63) ~[play_2.10.jar:2.1.0]
    at play.api.Play$$anonfun$start$1.apply(Play.scala:63) ~[play_2.10.jar:2.1.0]
    at play.api.Play$$anonfun$start$1.apply(Play.scala:63) ~[play_2.10.jar:2.1.0]
    at play.utils.Threads$.withContextClassLoader(Threads.scala:18) ~[play_2.10.jar:2.1.0]
    at play.api.Play$.start(Play.scala:62) ~[play_2.10.jar:2.1.0]
    at play.core.ReloadableApplication$$anonfun$get$1$$anonfun$1.apply(ApplicationProvider.scala:133) ~[play_2.10.jar:2.1.0]
    ... 38 common frames omitted

因此,只有第三個序列化失敗。

我的枚舉是基本的:

object RelationshipStatus extends Enumeration {
  val PENDING = Value("PENDING")
  val ACCEPTED = Value("ACCEPTED")
  val REJECTED = Value("REJECTED")
  val IGNORED = Value("IGNORED")
}

任何想法??? 我沒有在枚舉中定義任何類型別名,那么為什么會出現此錯誤? 為什么在第三次嘗試中而不是在第二次嘗試中具有相同的枚舉?

順便說一句,可能有:

{"string":"someString","status":"ACCEPTED"}

代替:

{"string":"someString","status":{"enumClass":"models.RelationshipStatus","value":"ACCEPTED"}}

您有兩個不同的問題:

  1. 為什么此代碼引發異常?

    我不知道,除了說scalabeans (Jackson Scala模塊的2.1系列所依賴的一個庫)看起來好像在枚舉方面遇到了麻煩,可能特別是在Scala 2.10中。 我將在相關的github問題中跟蹤此缺陷。

  2. 枚舉序列化時是否可以不必傳達其類型?

    還沒。 為何在相關的github問題中詳細說明; 要點在於,由於Enumerations的Value類型只是類型別名而不是類型,因此在Java擦除下,每個Enumeration派生類的每個值都具有相同的運行時類型。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM