首页 \ 问答 \ Scala Play - 如何格式化JSON转换的泛型(Scala Play - How to format Generics for JSON conversion)

Scala Play - 如何格式化JSON转换的泛型(Scala Play - How to format Generics for JSON conversion)

我正在学习越来越多关于Scala和那个漂亮的游戏框架。 但是有一些事情让我烦恼,我无法开始工作。

例如,我喜欢将Generics用于某种集合。 但是我需要将它们存储在JSON中的数据库中。 有这个很酷的自动转换的东西,但它不适用于泛型,我没有尝试过: - /

好的,具体而言,代码优先:

case class InventorySlot(id: Long, item: Option[Item])

object InventorySlot {
  implicit val fmt = Json.format[InventorySlot]
}


case class Inventory[T <: Item](slots: Vector[InventorySlot]) {
  def length = slots.length

  def items: Vector[T] = slots.map(slot => slot.item).flatten.asInstanceOf[Vector[T]]

  def item(id: Long): Option[T] = {
    slots.find(_.id == id) match {
      case Some(slot: InventorySlot) =>
        Some(slot.item.asInstanceOf[T])
      case None =>
        Logger.warn(s"slot with id $id not found")
        None
    }
  }
}

object Inventory {
  implicit val fmt = Json.format[Inventory]
}

Item是可以放入该库存的不同项目的基本抽象类。 没关系。 但有时我想要一个库存,只适用于ItemType A,我们称之为AItem 。 所以我想用这样的东西创建我的库存: val myInventory = Inventory[AItem]("content of vector here") ,当我调用myInventory.item(2) ,我想要在插槽2中获取该项目,并且它应该是AItem类型的对象,而不仅仅是Item 。 (这就是我在这里使用泛型的原因)

所以问题

显然, Inventory的隐式格式不起作用。 Item ,以及所有特殊项目,我可以在下面发布它的代码, InventorySlot应该工作。

编译时的错误是:

Error:(34, 34) Play 2 Compiler: 
 C:\depot\mars\mainline\server\app\models\Test.scala:34: class Inventory takes type parameters
   implicit val fmt = Json.format[Inventory]
                                  ^

我试着明确写出读写,比如

implicit val fmt = (
  (__ \ "slots").format[Vector[InventorySlot]]
  )(Inventory.apply, unlift(Inventory.unapply))

甚至没有在我的IDE中工作,我找不到问题。 我很困惑。 我不知道我的错误在哪里,或者我做错了什么,或者我错过了什么。

任何帮助将不胜感激。

我很无奈,我甚至考虑过为所有可能的库存类型做一个类,比如

case class AItemInventory(protected var slots: Vector[InventorySlot]) extends Inventory[AItem](slots)

object AItemInventory {
  implicit val fmt = Json.format[AItemInventory]
}

哪个有效。 没问题,一切都很好。 所以......我不明白。 如果它看起来完全相同,只是硬编码,为什么这个工作?

附录

项目格式化程序,工作原理:

implicit val itemFormat = new Format[Item] {
  override def reads(json: JsValue): JsResult[Item] = {
    (json \ "itemType").as[ItemType] match {
      case ItemType.AITEM => fmtAItem.reads(json)
    }
  }

  override def writes(item: Item): JsValue = item match {
    case subItem: AItem => fmtAItem.writes(subItem)
    case _ => JsNumber(item.itemType.id)
  }
}

I am learning more and more about Scala and that nice playframework. But there are some things that bother me and that I can't get to work.

I like using Generics for some kind of collections, for example. But I need those to be stored in our database, in JSON. There is this cool auto conversion thing, but it does not work for generics, in no way I have tried :-/

Okay, to be concrete, code first:

case class InventorySlot(id: Long, item: Option[Item])

object InventorySlot {
  implicit val fmt = Json.format[InventorySlot]
}


case class Inventory[T <: Item](slots: Vector[InventorySlot]) {
  def length = slots.length

  def items: Vector[T] = slots.map(slot => slot.item).flatten.asInstanceOf[Vector[T]]

  def item(id: Long): Option[T] = {
    slots.find(_.id == id) match {
      case Some(slot: InventorySlot) =>
        Some(slot.item.asInstanceOf[T])
      case None =>
        Logger.warn(s"slot with id $id not found")
        None
    }
  }
}

object Inventory {
  implicit val fmt = Json.format[Inventory]
}

Item is a basic abstract class of different items that can be put in that inventory. It doesn't matter. But sometimes I want to have an inventory, that just works for ItemType A, lets call it AItem. So I want to create my inventory with something like this: val myInventory = Inventory[AItem]("content of vector here") and when I call myInventory.item(2), then I want to get the item in slot 2, and it should be an object of type AItem, not just Item. (That's the reason why I am using generics here)

So the problem

The implicit format for Inventory does not work, obviously. Item does, also with all special items, I can post the code for it below, and InventorySlot should work as well.

The error when compiling is:

Error:(34, 34) Play 2 Compiler: 
 C:\depot\mars\mainline\server\app\models\Test.scala:34: class Inventory takes type parameters
   implicit val fmt = Json.format[Inventory]
                                  ^

I tried to write the read and write explicitly, like

implicit val fmt = (
  (__ \ "slots").format[Vector[InventorySlot]]
  )(Inventory.apply, unlift(Inventory.unapply))

wich is not even working in my IDE, and I can't find the problem. I am confused. I don't know where my error lies, or if I am doing something wrong, or if I just miss something.

Any help will be appreciated.

I am so helpless, I even have considered doing a class for all possible inventory types, like

case class AItemInventory(protected var slots: Vector[InventorySlot]) extends Inventory[AItem](slots)

object AItemInventory {
  implicit val fmt = Json.format[AItemInventory]
}

wich works. No problems, everything fine. So... I don't understand. Why is this working if it seems to be exactly the same, just hardcoded?

Appendix

The item formatter, wich works:

implicit val itemFormat = new Format[Item] {
  override def reads(json: JsValue): JsResult[Item] = {
    (json \ "itemType").as[ItemType] match {
      case ItemType.AITEM => fmtAItem.reads(json)
    }
  }

  override def writes(item: Item): JsValue = item match {
    case subItem: AItem => fmtAItem.writes(subItem)
    case _ => JsNumber(item.itemType.id)
  }
}

原文:https://stackoverflow.com/questions/31135563
更新时间:2022-11-26 20:11

最满意答案

只是为了澄清,标签(至少是内置的JIRA标签)是全球实体,因此它们可以附加到任何项目中的任何问题。

至于你的问题 - 不,没有公共REST端点来获取/更改/添加标签给JIRA。


Just to clarify, labels (at least the built-in JIRA ones) are global entities so they can be attached to any Issue in any Project.

As to your question - no, there's no public REST endpoint to get/change/add labels to JIRA.

相关问答

更多
  • 您想要的所有信息都可以在这里找到: https://docs.atlassian.com/jira/REST/latest/ 请注意,您可以通过以下方式获取项目信息: https : //docs.atlassian.com/jira/REST/latest/#api/2/project a)至于sprint信息 - 你能用JQL获得所需的信息吗? 示例 - 您可以转到问题>搜索问题并使用基本搜索吗? 在这里,在“更多”选项下,您将看到可以指定要过滤的Sprint。 在添加/删除sprint时,您将看到UR ...
  • 使用解决; request.basic_auth 'username', 'password' request["Content-Type"] = "application/json" 代替: request["user"] = "" request["password"] = "" Resolved by using; request.basic_auth 'username', 'password' request["Content-Type"] = "app ...
  • 使用Basic Auth访问API时,用户名和密码不应该是GET参数。 有关在PHP中通过cURL使用基本身份验证的说明,请参阅此答案 。 如果您不使用HTTPS,则应考虑使用o Auth认证方法而不是基本身份验证。 When using Basic Auth to access the API, the username and password should not be GET parameters. See this answer for instructions on using basic au ...
  • 在我使用过的最有趣的API之一进行了大量研究和卷曲之后,我在这里找到了一些关于Atlassian知识库的非常有用的信息。 该文本的目标是多选自定义字段,但也适用于其他类型的自定义字段。 它清楚地提到JIRA的REST API不提供简单检索多选项自定义字段可用的所有选项的方法 。 因此,这里使用的方法被认为是一种解决方法。 所以我们可以使用 创建问题meta api( 这里 ) 或者编辑问题meta api( 这里 ) 在两个元api链接之后,来自create meta api的参数很简单,但是在编辑元api ...
  • 这是不完整的URL ,您需要提供version id 尝试使用此URL /api/2.0.alpha1/version/{id} 其中id是您的版本号 404(未找到) - 如果版本不存在或当前已通过身份验证的用户没有查看权限,则返回。 200(成功) - application / json 来源网址 This is incomplete URL, you need to give the version id Try to use this URL /api/2.0.alpha1/version/{i ...
  • 根据我所看到的,Atlassian JIRA中有一张票据用于您的体验: REST问题不再显示附件信息 。 在这个评论中甚至提到了Apache的JIRA案例。 引用另一个评论 : 附件在“问题视图”网页中可见,但在默认屏幕中隐藏字段时,在REST中不可见。 该错误已得到解决,但用户似乎并不喜欢它,并要求进行适当的修复 : 上述“解决方案”不是解决方案,而是针对此错误的解决方法。 适当的解决方案是让Atlassian修复此错误,以便始终在JSON中列出附件。 GUI设置不会影响REST API JSON输出 - ...
  • 只是为了澄清,标签(至少是内置的JIRA标签)是全球实体,因此它们可以附加到任何项目中的任何问题。 至于你的问题 - 不,没有公共REST端点来获取/更改/添加标签给JIRA。 Just to clarify, labels (at least the built-in JIRA ones) are global entities so they can be attached to any Issue in any Project. As to your question - no, there's no ...
  • 我们正在使用JIRA 6.0.7并且可以: /rest/api/2/groups/picker?maxResults=10000 这将显示所有组,最多10000结果。 响应是重要的部分,因为它显示了组的总数,如果您的值太小而无法显示所有结果,则可能需要您调整传递给它的maxResults查询参数: { "header":"Showing 5014 of 5014 matching groups", "total":5014, "groups":{ ... } ...
  • 获取JQL查询字符串的任何简单方法是使用问题搜索UI并查看顶部生成的URL并获取jql部分: 所以添加标签部分的部分是: %20AND%20labels%20in%20(build1%2C%20build2) 哪个是and labels in (build1, build2) 。 重要的是要注意使用&使REST API的事情JQL查询参数已经结束,这就是为什么你需要使用%20的空格编码字符然后使用AND关键字来构建你的JQL。 Any easy way to get the JQL Query Strin ...
  • 不要编码用户名和密码 - 卷曲已经处理了这个! curl -u "username:password" -X GET -H "Content-Type: application/json" https://jira.acme.com/rest/api/2/issue/KEY-666 如果您需要指定基本身份验证,请执行以下操作: curl -D- -X GET -H "Authorization: Basic usernamesndpasswordbase64 -H "Content-Type: appli ...

相关文章

更多

最新问答

更多
  • 您如何使用git diff文件,并将其应用于同一存储库的副本的本地分支?(How do you take a git diff file, and apply it to a local branch that is a copy of the same repository?)
  • 将长浮点值剪切为2个小数点并复制到字符数组(Cut Long Float Value to 2 decimal points and copy to Character Array)
  • OctoberCMS侧边栏不呈现(OctoberCMS Sidebar not rendering)
  • 页面加载后对象是否有资格进行垃圾回收?(Are objects eligible for garbage collection after the page loads?)
  • codeigniter中的语言不能按预期工作(language in codeigniter doesn' t work as expected)
  • 在计算机拍照在哪里进入
  • 使用cin.get()从c ++中的输入流中丢弃不需要的字符(Using cin.get() to discard unwanted characters from the input stream in c++)
  • No for循环将在for循环中运行。(No for loop will run inside for loop. Testing for primes)
  • 单页应用程序:页面重新加载(Single Page Application: page reload)
  • 在循环中选择具有相似模式的列名称(Selecting Column Name With Similar Pattern in a Loop)
  • System.StackOverflow错误(System.StackOverflow error)
  • KnockoutJS未在嵌套模板上应用beforeRemove和afterAdd(KnockoutJS not applying beforeRemove and afterAdd on nested templates)
  • 散列包括方法和/或嵌套属性(Hash include methods and/or nested attributes)
  • android - 如何避免使用Samsung RFS文件系统延迟/冻结?(android - how to avoid lag/freezes with Samsung RFS filesystem?)
  • TensorFlow:基于索引列表创建新张量(TensorFlow: Create a new tensor based on list of indices)
  • 企业安全培训的各项内容
  • 错误:RPC失败;(error: RPC failed; curl transfer closed with outstanding read data remaining)
  • C#类名中允许哪些字符?(What characters are allowed in C# class name?)
  • NumPy:将int64值存储在np.array中并使用dtype float64并将其转换回整数是否安全?(NumPy: Is it safe to store an int64 value in an np.array with dtype float64 and later convert it back to integer?)
  • 注销后如何隐藏导航portlet?(How to hide navigation portlet after logout?)
  • 将多个行和可变行移动到列(moving multiple and variable rows to columns)
  • 提交表单时忽略基础href,而不使用Javascript(ignore base href when submitting form, without using Javascript)
  • 对setOnInfoWindowClickListener的意图(Intent on setOnInfoWindowClickListener)
  • Angular $资源不会改变方法(Angular $resource doesn't change method)
  • 在Angular 5中不是一个函数(is not a function in Angular 5)
  • 如何配置Composite C1以将.m和桌面作为同一站点提供服务(How to configure Composite C1 to serve .m and desktop as the same site)
  • 不适用:悬停在悬停时:在元素之前[复制](Don't apply :hover when hovering on :before element [duplicate])
  • 常见的python rpc和cli接口(Common python rpc and cli interface)
  • Mysql DB单个字段匹配多个其他字段(Mysql DB single field matching to multiple other fields)
  • 产品页面上的Magento Up出售对齐问题(Magento Up sell alignment issue on the products page)