有人可以解释一下为什么这不起作用? 我和杰克逊一起使用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
因此只有第3次序列化失败。
我的枚举是基本的:
object RelationshipStatus extends Enumeration {
val PENDING = Value("PENDING")
val ACCEPTED = Value("ACCEPTED")
val REJECTED = Value("REJECTED")
val IGNORED = Value("IGNORED")
}
任何想法??? 我没有在我的枚举中定义任何类型的别名,为什么会出现这个错误?为什么在第3次尝试而不是在第2次具有相同的枚举?
顺便说一句,是否有可能:
{"string":"someString","status":"ACCEPTED"}
而不是:
{"string":"someString","status":{"enumClass":"models.RelationshipStatus","value":"ACCEPTED"}}
答案 0 :(得分:1)
您有两个不同的问题:
为什么这段代码会抛出异常?
我不知道,除了说scalabeans
,杰克逊Scala模块的2.1系列所依赖的库,看起来它在Enumerations上有问题,可能特别是在Scala 2.10下。我会在related github issue。
枚举是否可以在序列化时不必传达其类型?
还没有。详细说明为何relevant github issue;要点是因为Enumerations的Value类型只是类型别名而不是类型,所以每个Enumeration派生类的每个值在Java擦除下都具有相同的运行时类型。