I use version 0.3.1, where the json support is already supported. There is a method asJson, which returns JValue. According to http://spray.io/documentation/1.2.2/spray-httpx/json4s-support/ there is an implicit Marshaller when using trait Json4sSupport. But when using spray as server, I need to provide ToResponseMarshaller.
I wonder now, whether I need to code my own, or it should be a part of json support in scala-activerecord. I am a bit inclined to the latter option.
What have I tried:
trait ActiveRecordToSprayJsonSupport extends Json4sSupport {
override implicit def json4sFormats: Formats = org.json4s.DefaultFormats
implicit def toToResponseMarashaller(implicit tMarshaller: Marshaller[ActiveRecord]): ToResponseMarshaller[ActiveRecord] = new ToResponseMarshaller[ActiveRecord] {
override def apply(value: ActiveRecord, ctx: ToResponseMarshallingContext): Unit = {
val mCtx = new MarshallingContext {
override def tryAccept(contentTypes: Seq[ContentType]): Option[ContentType] = ctx.tryAccept(contentTypes)
override def startChunkedMessage(entity: HttpEntity, ack: Option[Any], headers: Seq[HttpHeader])(implicit sender: ActorRef): ActorRef = ctx.startChunkedMessage(HttpResponse(entity = entity, headers = headers.toList), ack)
override def rejectMarshalling(supported: Seq[ContentType]): Unit = ctx.rejectMarshalling(supported)
override def marshalTo(entity: HttpEntity, headers: HttpHeader*): Unit = ctx.marshalTo(HttpResponse(entity = entity, headers = headers.toList))
override def handleError(error: Throwable): Unit = ctx.handleError(error)
}
tMarshaller(value, mCtx)
}
}
}
The models:
case class Product(name: String) extends ActiveRecord {
lazy val comments = hasMany[Comment]
}
object Product extends ActiveRecordCompanion[Product]
case class Comment(text: String) extends ActiveRecord {
}
object Comment extends ActiveRecordCompanion[Comment]
And the service:
trait ProductService extends HttpServiceActor with HttpService with ActiveRecordToSprayJsonSupport {
...
Product.find(id) match {
case Some(r: Product) => requestContext.complete(r)
case _ => requestContext.complete(StatusCodes.NotFound)
}
...
}
And here is what I have got:
org.json4s.package$MappingException: Can't find ScalaSig for class java.lang.Object
at org.json4s.reflect.ScalaSigReader$.findClass(ScalaSigReader.scala:42)
at org.json4s.reflect.ScalaSigReader$.org$json4s$reflect$ScalaSigReader$$read$1(ScalaSigReader.scala:36)
at org.json4s.reflect.ScalaSigReader$.org$json4s$reflect$ScalaSigReader$$read$1(ScalaSigReader.scala:36)
at org.json4s.reflect.ScalaSigReader$.readField(ScalaSigReader.scala:38)
at org.json4s.reflect.Reflector$ClassDescriptorBuilder$$anonfun$3.apply(Reflector.scala:66)
at org.json4s.reflect.Reflector$ClassDescriptorBuilder$$anonfun$3.apply(Reflector.scala:65)
at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:245)
at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:245)
at scala.collection.mutable.ResizableArray$class.foreach(ResizableArray.scala:59)
at scala.collection.mutable.ArrayBuffer.foreach(ArrayBuffer.scala:48)
at scala.collection.TraversableLike$class.map(TraversableLike.scala:245)
at scala.collection.AbstractTraversable.map(Traversable.scala:104)
at org.json4s.reflect.Reflector$ClassDescriptorBuilder.fields(Reflector.scala:65)
at org.json4s.reflect.Reflector$ClassDescriptorBuilder.fields(Reflector.scala:78)
at org.json4s.reflect.Reflector$ClassDescriptorBuilder.properties(Reflector.scala:82)
at org.json4s.reflect.Reflector$ClassDescriptorBuilder.result(Reflector.scala:158)
at org.json4s.reflect.Reflector$.createDescriptor(Reflector.scala:50)
at org.json4s.reflect.Reflector$$anonfun$describe$1.apply(Reflector.scala:44)
at org.json4s.reflect.Reflector$$anonfun$describe$1.apply(Reflector.scala:44)
at org.json4s.reflect.package$Memo.apply(package.scala:39)
at org.json4s.reflect.Reflector$.describe(Reflector.scala:44)
at org.json4s.Extraction$.decomposeObject$1(Extraction.scala:90)
at org.json4s.Extraction$.internalDecomposeWithBuilder(Extraction.scala:196)
at org.json4s.Extraction$.decomposeWithBuilder(Extraction.scala:67)
at org.json4s.native.Serialization$.write(Serialization.scala:43)
at org.json4s.native.Serialization$.write(Serialization.scala:37)
at spray.httpx.BaseJson4sSupport$$anonfun$json4sMarshaller$1.apply(BaseJson4sSupport.scala:26)
at spray.httpx.BaseJson4sSupport$$anonfun$json4sMarshaller$1.apply(BaseJson4sSupport.scala:26)
at spray.httpx.marshalling.Marshaller$MarshallerDelegation$$anonfun$apply$1.apply(Marshaller.scala:58)
at spray.httpx.marshalling.Marshaller$MarshallerDelegation$$anonfun$apply$1.apply(Marshaller.scala:58)
at spray.httpx.marshalling.Marshaller$MarshallerDelegation$$anonfun$apply$2.apply(Marshaller.scala:61)
at spray.httpx.marshalling.Marshaller$MarshallerDelegation$$anonfun$apply$2.apply(Marshaller.scala:60)
at spray.httpx.marshalling.Marshaller$$anon$2.apply(Marshaller.scala:47)
I use version 0.3.1, where the json support is already supported. There is a method
asJson, which returnsJValue. According to http://spray.io/documentation/1.2.2/spray-httpx/json4s-support/ there is an implicitMarshallerwhen using traitJson4sSupport. But when using spray as server, I need to provideToResponseMarshaller.I wonder now, whether I need to code my own, or it should be a part of json support in scala-activerecord. I am a bit inclined to the latter option.
What have I tried:
The models:
And the service:
And here is what I have got: