如何在编组期间将 org.bson.types.ObjectId 转换为字符串?
How to convert org.bson.types.ObjectId to String during marshalling?
看来我必须写一个 serializer/deserializer 来解决这个问题,但不确定如何解决。我看到几个使用 liftweb 框架的例子,但并非没有。关于如何让它工作的任何帮助?
注册模型
package model
import spray.json._
import spray.json.DefaultJsonProtocol._
import spray.httpx.SprayJsonSupport
import com.mongodb.casbah.Imports._
import org.bson.types.ObjectId
import com.mongodb.DBObject
import com.mongodb.casbah.commons.{MongoDBList, MongoDBObject}
case class Registration(
system: String,
identity: String,
id: Option[String] = None)
object RegistrationJsonProtocol extends DefaultJsonProtocol {
implicit val adsRegistrationFormat = jsonFormat3(Registration)
}
object RegistrationMap {
def toBson(registration: Registration): DBObject = {
MongoDBObject(
"system" -> registration.system,
"identity" -> registration.identity,
"_id" -> new ObjectId(registration.id.getOrElse(new ObjectId().toString))
)
}
def fromBson(o: DBObject): Registration = {
Registration(
system = o.as[String]("system"),
identity = o.as[String]("identity"),
id = Some(o.as[String]("_id"))
)
}
}
来自 RegistrationsRoutes 的代码片段 class
val route: Route = {
withService("registrations") { service =>
import model.RegistrationJsonProtocol._
postRegistration {
entity(as[Registration]) { registration =>
val future = (service ? PostRegistrationMessage(registration)).mapTo[Registration]
onComplete(future) {
case Success(result) =>
log.debug(s"result: ${result}")
complete(result)
case Failure(e) =>
log.error(s"Error: ${e.toString}")
complete(StatusCodes.InternalServerError, Message(ApiMessages.UnknownException))
}
}
}
}
}
处理完成(结果)语句时出现以下错误
13:08:17.538 [microservice-system-akka.actor.default-dispatcher-5] DEBUG akka.actor.ActorSystemImpl - result: Registration(system1,identity1,Some(54bd48110364eb78f7b84ce3))
13:08:17.643 [microservice-system-akka.actor.default-dispatcher-5] ERROR akka.actor.RepointableActorRef - Error during processing of request HttpRequest(POST,http://localhost:8878/api/v1/registrations,List(Accept-Language: en-US, en;q=0.8, es;q=0.6, te;q=0.4, Accept-Encoding: gzip, deflate, DNT: 1, Content-Type: application/json, Origin: chrome-extension://hgmloofddffdnphfgcellkdfbfbjeloo, User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.99 Safari/537.36, Content-Length: 165, Connection: keep-alive, Host: localhost:8878),HttpEntity(application/json,{"system":"system1", "identity":"identity1"),HTTP/1.1)
java.lang.ClassCastException: org.bson.types.ObjectId cannot be cast to java.lang.String
at spray.json.BasicFormats$StringJsonFormat$.write(BasicFormats.scala:119) ~[spray-json_2.10-1.2.6.jar:na]
at spray.json.PimpedAny.toJson(package.scala:39) ~[spray-json_2.10-1.2.6.jar:na]
at spray.json.StandardFormats$OptionFormat.write(StandardFormats.scala:34) ~[spray-json_2.10-1.2.6.jar:na]
at spray.json.StandardFormats$OptionFormat.write(StandardFormats.scala:32) ~[spray-json_2.10-1.2.6.jar:na]
at spray.json.ProductFormats$class.productElement2Field(ProductFormats.scala:36) ~[spray-json_2.10-1.2.6.jar:na]
at com.ericsson.admcore.model.ADSRegistrationJsonProtocol$.productElement2Field(ADSRegistration.scala:20) ~[classes/:na]
at spray.json.ProductFormatsInstances$$anon.write(ProductFormatsInstances.scala:155) ~[spray-json_2.10-1.2.6.jar:na]
at spray.json.ProductFormatsInstances$$anon.write(ProductFormatsInstances.scala:146) ~[spray-json_2.10-1.2.6.jar:na]
at spray.httpx.SprayJsonSupport$$anonfun$sprayJsonMarshaller.apply(SprayJsonSupport.scala:43) ~[spray-httpx_2.10-1.3.1.jar:na]
at spray.httpx.SprayJsonSupport$$anonfun$sprayJsonMarshaller.apply(SprayJsonSupport.scala:42) ~[spray-httpx_2.10-1.3.1.jar:na]
at spray.httpx.marshalling.Marshaller$MarshallerDelegation$$anonfun$apply.apply(Marshaller.scala:58) ~[spray-httpx_2.10-1.3.1.jar:na]
at spray.httpx.marshalling.Marshaller$MarshallerDelegation$$anonfun$apply.apply(Marshaller.scala:58) ~[spray-httpx_2.10-1.3.1.jar:na]
at spray.httpx.marshalling.Marshaller$MarshallerDelegation$$anonfun$apply.apply(Marshaller.scala:61) ~[spray-httpx_2.10-1.3.1.jar:na]
at spray.httpx.marshalling.Marshaller$MarshallerDelegation$$anonfun$apply.apply(Marshaller.scala:60) ~[spray-httpx_2.10-1.3.1.jar:na]
at spray.httpx.marshalling.Marshaller$$anon.apply(Marshaller.scala:47) ~[spray-httpx_2.10-1.3.1.jar:na]
at spray.httpx.marshalling.BasicToResponseMarshallers$$anon.apply(BasicToResponseMarshallers.scala:35) ~[spray-httpx_2.10-1.3.1.jar:na]
at spray.httpx.marshalling.BasicToResponseMarshallers$$anon.apply(BasicToResponseMarshallers.scala:22) ~[spray-httpx_2.10-1.3.1.jar:na]
at spray.httpx.marshalling.ToResponseMarshaller$$anonfun$compose.apply(Marshaller.scala:69) ~[spray-httpx_2.10-1.3.1.jar:na]
at spray.httpx.marshalling.ToResponseMarshaller$$anonfun$compose.apply(Marshaller.scala:69) ~[spray-httpx_2.10-1.3.1.jar:na]
at spray.httpx.marshalling.ToResponseMarshaller$$anon.apply(Marshaller.scala:81) ~[spray-httpx_2.10-1.3.1.jar:na]
at spray.httpx.marshalling.ToResponseMarshallable$$anon.marshal(Marshaller.scala:141) ~[spray-httpx_2.10-1.3.1.jar:na]
at spray.httpx.marshalling.ToResponseMarshallable$$anon.apply(Marshaller.scala:145) ~[spray-httpx_2.10-1.3.1.jar:na]
at spray.httpx.marshalling.ToResponseMarshallable$$anon.apply(Marshaller.scala:144) ~[spray-httpx_2.10-1.3.1.jar:na]
at spray.routing.RequestContext.complete(RequestContext.scala:237) ~[spray-routing_2.10-1.3.1.jar:na]
at spray.routing.directives.RouteDirectives$$anonfun$complete$$anon.apply(RouteDirectives.scala:49) ~[spray-routing_2.10-1.3.1.jar:na]
at spray.routing.directives.RouteDirectives$$anonfun$complete$$anon.apply(RouteDirectives.scala:48) ~[spray-routing_2.10-1.3.1.jar:na]
at spray.routing.directives.OnCompleteFutureMagnet$$anon$$anonfun$happly$$anonfun$apply.apply(FutureDirectives.scala:63) ~[spray-routing_2.10-1.3.1.jar:na]
at spray.routing.directives.OnCompleteFutureMagnet$$anon$$anonfun$happly$$anonfun$apply.apply(FutureDirectives.scala:62) ~[spray-routing_2.10-1.3.1.jar:na]
at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:32) ~[scala-library.jar:na]
at scala.concurrent.impl.ExecutionContextImpl$$anon.exec(ExecutionContextImpl.scala:107) ~[scala-library.jar:na]
at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260) [scala-library.jar:na]
at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339) [scala-library.jar:na]
at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979) [scala-library.jar:na]
at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107) [scala-library.jar:na]
我无法对此进行测试,但我认为问题在于 fromBson
方法中的以下行(尽管我无法从您的代码中看出该方法是如何调用的):
id = Some(o.as[String]("_id"))
将此更改为
id = Some(o.as[ObjectId]("_id").toString)
序列化错误应该消失了。
是的,尝试像下面这样的字符串:
ObjectId.toString() 将 return ObjectId() 的字符串表示形式。此字符串值的格式为 ObjectId(...).
例子
以下示例调用 ObjectId() 上的 toString() 方法:
ObjectId("507c7f79bcf86cd7994f6c0e").toString()
参考:
https://docs.mongodb.com/manual/reference/method/ObjectId.toString/
看来我必须写一个 serializer/deserializer 来解决这个问题,但不确定如何解决。我看到几个使用 liftweb 框架的例子,但并非没有。关于如何让它工作的任何帮助?
注册模型
package model
import spray.json._
import spray.json.DefaultJsonProtocol._
import spray.httpx.SprayJsonSupport
import com.mongodb.casbah.Imports._
import org.bson.types.ObjectId
import com.mongodb.DBObject
import com.mongodb.casbah.commons.{MongoDBList, MongoDBObject}
case class Registration(
system: String,
identity: String,
id: Option[String] = None)
object RegistrationJsonProtocol extends DefaultJsonProtocol {
implicit val adsRegistrationFormat = jsonFormat3(Registration)
}
object RegistrationMap {
def toBson(registration: Registration): DBObject = {
MongoDBObject(
"system" -> registration.system,
"identity" -> registration.identity,
"_id" -> new ObjectId(registration.id.getOrElse(new ObjectId().toString))
)
}
def fromBson(o: DBObject): Registration = {
Registration(
system = o.as[String]("system"),
identity = o.as[String]("identity"),
id = Some(o.as[String]("_id"))
)
}
}
来自 RegistrationsRoutes 的代码片段 class
val route: Route = {
withService("registrations") { service =>
import model.RegistrationJsonProtocol._
postRegistration {
entity(as[Registration]) { registration =>
val future = (service ? PostRegistrationMessage(registration)).mapTo[Registration]
onComplete(future) {
case Success(result) =>
log.debug(s"result: ${result}")
complete(result)
case Failure(e) =>
log.error(s"Error: ${e.toString}")
complete(StatusCodes.InternalServerError, Message(ApiMessages.UnknownException))
}
}
}
}
}
处理完成(结果)语句时出现以下错误
13:08:17.538 [microservice-system-akka.actor.default-dispatcher-5] DEBUG akka.actor.ActorSystemImpl - result: Registration(system1,identity1,Some(54bd48110364eb78f7b84ce3))
13:08:17.643 [microservice-system-akka.actor.default-dispatcher-5] ERROR akka.actor.RepointableActorRef - Error during processing of request HttpRequest(POST,http://localhost:8878/api/v1/registrations,List(Accept-Language: en-US, en;q=0.8, es;q=0.6, te;q=0.4, Accept-Encoding: gzip, deflate, DNT: 1, Content-Type: application/json, Origin: chrome-extension://hgmloofddffdnphfgcellkdfbfbjeloo, User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.99 Safari/537.36, Content-Length: 165, Connection: keep-alive, Host: localhost:8878),HttpEntity(application/json,{"system":"system1", "identity":"identity1"),HTTP/1.1)
java.lang.ClassCastException: org.bson.types.ObjectId cannot be cast to java.lang.String
at spray.json.BasicFormats$StringJsonFormat$.write(BasicFormats.scala:119) ~[spray-json_2.10-1.2.6.jar:na]
at spray.json.PimpedAny.toJson(package.scala:39) ~[spray-json_2.10-1.2.6.jar:na]
at spray.json.StandardFormats$OptionFormat.write(StandardFormats.scala:34) ~[spray-json_2.10-1.2.6.jar:na]
at spray.json.StandardFormats$OptionFormat.write(StandardFormats.scala:32) ~[spray-json_2.10-1.2.6.jar:na]
at spray.json.ProductFormats$class.productElement2Field(ProductFormats.scala:36) ~[spray-json_2.10-1.2.6.jar:na]
at com.ericsson.admcore.model.ADSRegistrationJsonProtocol$.productElement2Field(ADSRegistration.scala:20) ~[classes/:na]
at spray.json.ProductFormatsInstances$$anon.write(ProductFormatsInstances.scala:155) ~[spray-json_2.10-1.2.6.jar:na]
at spray.json.ProductFormatsInstances$$anon.write(ProductFormatsInstances.scala:146) ~[spray-json_2.10-1.2.6.jar:na]
at spray.httpx.SprayJsonSupport$$anonfun$sprayJsonMarshaller.apply(SprayJsonSupport.scala:43) ~[spray-httpx_2.10-1.3.1.jar:na]
at spray.httpx.SprayJsonSupport$$anonfun$sprayJsonMarshaller.apply(SprayJsonSupport.scala:42) ~[spray-httpx_2.10-1.3.1.jar:na]
at spray.httpx.marshalling.Marshaller$MarshallerDelegation$$anonfun$apply.apply(Marshaller.scala:58) ~[spray-httpx_2.10-1.3.1.jar:na]
at spray.httpx.marshalling.Marshaller$MarshallerDelegation$$anonfun$apply.apply(Marshaller.scala:58) ~[spray-httpx_2.10-1.3.1.jar:na]
at spray.httpx.marshalling.Marshaller$MarshallerDelegation$$anonfun$apply.apply(Marshaller.scala:61) ~[spray-httpx_2.10-1.3.1.jar:na]
at spray.httpx.marshalling.Marshaller$MarshallerDelegation$$anonfun$apply.apply(Marshaller.scala:60) ~[spray-httpx_2.10-1.3.1.jar:na]
at spray.httpx.marshalling.Marshaller$$anon.apply(Marshaller.scala:47) ~[spray-httpx_2.10-1.3.1.jar:na]
at spray.httpx.marshalling.BasicToResponseMarshallers$$anon.apply(BasicToResponseMarshallers.scala:35) ~[spray-httpx_2.10-1.3.1.jar:na]
at spray.httpx.marshalling.BasicToResponseMarshallers$$anon.apply(BasicToResponseMarshallers.scala:22) ~[spray-httpx_2.10-1.3.1.jar:na]
at spray.httpx.marshalling.ToResponseMarshaller$$anonfun$compose.apply(Marshaller.scala:69) ~[spray-httpx_2.10-1.3.1.jar:na]
at spray.httpx.marshalling.ToResponseMarshaller$$anonfun$compose.apply(Marshaller.scala:69) ~[spray-httpx_2.10-1.3.1.jar:na]
at spray.httpx.marshalling.ToResponseMarshaller$$anon.apply(Marshaller.scala:81) ~[spray-httpx_2.10-1.3.1.jar:na]
at spray.httpx.marshalling.ToResponseMarshallable$$anon.marshal(Marshaller.scala:141) ~[spray-httpx_2.10-1.3.1.jar:na]
at spray.httpx.marshalling.ToResponseMarshallable$$anon.apply(Marshaller.scala:145) ~[spray-httpx_2.10-1.3.1.jar:na]
at spray.httpx.marshalling.ToResponseMarshallable$$anon.apply(Marshaller.scala:144) ~[spray-httpx_2.10-1.3.1.jar:na]
at spray.routing.RequestContext.complete(RequestContext.scala:237) ~[spray-routing_2.10-1.3.1.jar:na]
at spray.routing.directives.RouteDirectives$$anonfun$complete$$anon.apply(RouteDirectives.scala:49) ~[spray-routing_2.10-1.3.1.jar:na]
at spray.routing.directives.RouteDirectives$$anonfun$complete$$anon.apply(RouteDirectives.scala:48) ~[spray-routing_2.10-1.3.1.jar:na]
at spray.routing.directives.OnCompleteFutureMagnet$$anon$$anonfun$happly$$anonfun$apply.apply(FutureDirectives.scala:63) ~[spray-routing_2.10-1.3.1.jar:na]
at spray.routing.directives.OnCompleteFutureMagnet$$anon$$anonfun$happly$$anonfun$apply.apply(FutureDirectives.scala:62) ~[spray-routing_2.10-1.3.1.jar:na]
at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:32) ~[scala-library.jar:na]
at scala.concurrent.impl.ExecutionContextImpl$$anon.exec(ExecutionContextImpl.scala:107) ~[scala-library.jar:na]
at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260) [scala-library.jar:na]
at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339) [scala-library.jar:na]
at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979) [scala-library.jar:na]
at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107) [scala-library.jar:na]
我无法对此进行测试,但我认为问题在于 fromBson
方法中的以下行(尽管我无法从您的代码中看出该方法是如何调用的):
id = Some(o.as[String]("_id"))
将此更改为
id = Some(o.as[ObjectId]("_id").toString)
序列化错误应该消失了。
是的,尝试像下面这样的字符串:
ObjectId.toString() 将 return ObjectId() 的字符串表示形式。此字符串值的格式为 ObjectId(...).
例子 以下示例调用 ObjectId() 上的 toString() 方法:
ObjectId("507c7f79bcf86cd7994f6c0e").toString()
参考: https://docs.mongodb.com/manual/reference/method/ObjectId.toString/