加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

scala – 在Sangria中编组嵌套的自定义对象

发布时间:2020-12-16 18:14:39 所属栏目:安全 来源:网络整理
导读:我有以下输入对象: val BusinessInputType = InputObjectType[BusinessInput]("BusinessInput",List( InputField("userId",StringType),InputField("name",InputField("address",OptionInputType(StringType)),InputField("phonenumber",InputField("email"
我有以下输入对象:

val BusinessInputType = InputObjectType[BusinessInput]("BusinessInput",List(
    InputField("userId",StringType),InputField("name",InputField("address",OptionInputType(StringType)),InputField("phonenumber",InputField("email",InputField("hours",ListInputType(BusinessHoursInputType))

  ))


 val BusinessHoursInputType = InputObjectType[BusinessHoursInput]("hours",List(
    InputField("weekDay",IntType),InputField("startTime",InputField("endTime",StringType)
  ))

以下是定制编组定义的模型:

case class BusinessInput(userId: String,name: String,address: Option[String],phonenumber: Option[String],email: Option[String],hours: Seq[BusinessHoursInput])

object BusinessInput {

  implicit val manual = new FromInput[BusinessInput] {
    val marshaller = CoercedScalaResultMarshaller.default

    def fromResult(node: marshaller.Node) = {
      val ad = node.asInstanceOf[Map[String,Any]]

      System.out.println(ad)
      BusinessInput(
        userId = ad("userId").asInstanceOf[String],name = ad("name").asInstanceOf[String],address = ad.get("address").flatMap(_.asInstanceOf[Option[String]]),phonenumber = ad.get("phonenumber").flatMap(_.asInstanceOf[Option[String]]),email = ad.get("email").flatMap(_.asInstanceOf[Option[String]]),hours = ad("hours").asInstanceOf[Seq[BusinessHoursInput]]

      )
    }
  }
}



case class BusinessHoursInput(weekDay: Int,startTime: Time,endTime: Time)

object BusinessHoursInput {

  implicit val manual = new FromInput[BusinessHoursInput] {
    val marshaller = CoercedScalaResultMarshaller.default
    def fromResult(node: marshaller.Node) = {
      val ad = node.asInstanceOf[Map[String,Any]]
      System.out.println("HEY")

      BusinessHoursInput(
        weekDay = ad("weekDay").asInstanceOf[Int],startTime = Time.valueOf(ad("startTime").asInstanceOf[String]),endTime = Time.valueOf(ad("endTime").asInstanceOf[String])
      )
    }
  }


}

我的问题是,当我有一个具有自定义编组的嵌套InputObject时,我没有看到在编组BusinessInput之前调用BusinessHoursInput的编组.我注意到这一点,因为在“BusinessInput”中“ad”的print语句之前,“Hey”的print语句从未执行过.当我尝试在DB中插入BusinessInput的hours字段时,这会导致后来出现问题,因为它无法将其转换为BusinessHoursInput对象.在Sangria中,是否无法在父对象编组之前自定义Marshal嵌套对象?

解决方法

您可能正在使用BusinessInput作为参数类型.实际的隐式查找发生在Argument定义时,仅适用于BusinessInput类型.

由于FromInput是基于类型类的反序列化,因此需要显式定义嵌??套对象的反序列化之间的依赖关系.例如,您可以像这样重写反序列化器:

case类BusinessInput(userId:String,name:String,address:Option [String],phonenumber:Option [String],email:Option [String],hours:Seq [BusinessHoursInput])

object BusinessInput {
  implicit def manual(implicit hoursFromInput: FromInput[BusinessHoursInput]) = new FromInput[BusinessInput] {
    val marshaller = CoercedScalaResultMarshaller.default

    def fromResult(node: marshaller.Node) = {
      val ad = node.asInstanceOf[Map[String,Any]]

      BusinessInput(
        userId = ad("userId").asInstanceOf[String],hours = hoursFromInput.fromResult(ad("hours").asInstanceOf[Seq[hoursFromInput.marshaller.Node]])
      )
    }
  }
}

在这个版本中,我利用现有的FromInput [BusinessHoursInput]从原始输入反序列化BusinessHoursInput.

另外,作为替代方案,您可以通过利用现有的基于JSON的反序列化器来完全避免定义手动FromInput反序列化器.例如,在大多数情况下,circe的自动推导工作正常.您只需要这两个导入(在您定义参数的文件中):

import sangria.marshalling.circe._
import io.circe.generic.auto._

这些导入将适当的FromInput实例放入范围.这些实例利用了circe自己的反序列化机制.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读