Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/svn/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Scala Play框架中将trait和对象解析为JSON_Json_Scala_Playframework - Fatal编程技术网

如何在Scala Play框架中将trait和对象解析为JSON

如何在Scala Play框架中将trait和对象解析为JSON,json,scala,playframework,Json,Scala,Playframework,目前我正在使用Play框架开发一个web应用程序,现在我正在开发一个JSON api。不幸的是,我在使用内置JSON库将对象解析为JSON时遇到问题。我们有以下特性,它定义了装运的类型和要使用的解析器。还有一个case类,它有一个ShipmentType,所以我们知道每个类型使用哪个解析器。还有一种方法可以将所有存储的货物作为列表返回 trait ShipmentType { def parser(list: List[String]): ShipmentTypeParser } ob

目前我正在使用Play框架开发一个web应用程序,现在我正在开发一个JSON api。不幸的是,我在使用内置JSON库将对象解析为JSON时遇到问题。我们有以下特性,它定义了装运的类型和要使用的解析器。还有一个case类,它有一个ShipmentType,所以我们知道每个类型使用哪个解析器。还有一种方法可以将所有存储的货物作为列表返回

trait ShipmentType {

  def parser(list: List[String]): ShipmentTypeParser

}

object ShipmentTypeA extends ShipmentType {

  def parser(list: List[String]) = new ShipmentTypeAParser(list)

}

object ShipmentTypeB extends ShipmentType {

  def parser(list: List[String]) = new ShipmentTypeBParser(list)

}

object ShipmentTypeC extends ShipmentType {

  def parser(list: List[String]) = new ShipmentTypeCParser(list)

}

case class Shipment(id: Long, name: String, date: Date, shipmentType: Type)
要编写此JSON,我使用以下隐式val:

import play.api.libs.json._
import play.api.libs.functional.syntax._

def findAll = Action {
    Ok(Json.toJson(Shipments.all))
}
implicit val shipmentWrites: Writes[Shipment] = (
    (JsPath \ "id").write[Option[Long]] and
    (JsPath \ "name").write[String] and
    (JsPath \ "date").write[Date] and
    (JsPath \ "shipmentType").write[ShipmentType]
)(unlift(Shipment.unapply))
接下来,我们需要一个额外的ShipmentType:

implicit val shipmentTypeWriter: Writes[ShipmentType] = ()
但是我遇到了一些问题,我似乎找不到一种方法来定义ShipmentType的编写器

根据Play Framework文档的另一页,我还尝试将它们定义如下:

implicit val shipmentWrites: Writes[Shipment] = Json.writes[Shipment]
implicit val shipmentTypeWrites: Writes[ShipmentType] =Json.writes[ShipmentType]
然而,这也失败了,因为我得到了错误,比如:“没有找到unapply函数”。 有人想知道如何实现这方面的编写器吗?最好是json格式的字符串。

我创建了一个工作示例:

并在scalatest中进行测试:

trait ShipmentTypeParser

class ShipmentTypeAParser(list: List[String]) extends ShipmentTypeParser

class ShipmentTypeBParser(list: List[String]) extends ShipmentTypeParser

object ShipmentTypeA extends ShipmentType {
  override def parser(list: List[String]) = new ShipmentTypeAParser(list)
}

object ShipmentTypeB extends ShipmentType {
  override def parser(list: List[String]) = new ShipmentTypeBParser(list)
}


object Models {


  implicit val shipmentTypeWrites = new Format[ShipmentType] {
    override def writes(shipmentType: ShipmentType): JsValue = 
        JsString(shipmentType.getClass.getName)


    override def reads(json: JsValue): JsResult[ShipmentType] = json match {
      case JsString(className) =>
        Try(Class.forName(className)) match {
          case Success(c) =>
            JsSuccess(c.getField("MODULE$").get(c).asInstanceOf[ShipmentType])
          case Failure(th) =>
            JsError(th.getMessage)
        }
      case _ =>
        JsError(json.toString)
    }
  }

  implicit val shipmentWrites: Format[Shipment] = Json.format[Shipment]
}

trait ShipmentType {
  def parser(list: List[String]): ShipmentTypeParser
}


case class Shipment(id: Long, name: String, date: Date, shipmentType: ShipmentType)
class JsonSpec extends FlatSpec with Matchers {
  "Shipment " should " be convert to json and from " in {
    import Models._
    val shipment = Shipment(3, "33", new Date(), ShipmentTypeA)
    val jsonShipment = Json.toJson(shipment)
    println(jsonShipment)
    val fromJson = Json.fromJson[Shipment](jsonShipment)
    fromJson match{
      case JsSuccess(shipmentFromJson,_) =>
        shipmentFromJson shouldBe shipment
      case _ =>
        fail(fromJson.toString)
    }
  }
}