草庐IT

java - 如何为 Java 库中没有应用方法的对象编写 JSON 格式?

coder 2023-08-29 原文

我已经在这个特定问题上停留了大约一个星期了,我想我会把它作为一个问题写在这里,以理清我的想法并获得一些指导。

所以我有这个案例类有一个 java.sql.Timestamp领域:

案例类 Request(id: Option[Int], requestDate: Timestamp)

我想将其转换为 JsObject

val q = Query(Requests).list // This is Slick, a database access lib for Scala
  printList(q)    
  Ok(Json.toJson(q))   // and this is where I run into trouble

“未找到类型 List[models.Request] 的 Json 反序列化器。尝试为此类型实现隐式 Writes 或 Format。”好的,这是有道理的。

所以跟随Play documentation here , 我尝试写一个格式...

implicit val requestFormat = Json.format[Request]  // need Timestamp deserializer
implicit val timestampFormat = (
      (__ \ "time").format[Long]   // error 1
)(Timestamp.apply, unlift(Timestamp.unapply))  // error 2

错误 1

Description Resource Path Location Type overloaded method value format with alternatives:   

(w: play.api.libs.json.Writes[Long])(implicit r: play.api.libs.json.Reads[Long])play.api.libs.json.OFormat[Long] 
<and>   
(r: play.api.libs.json.Reads[Long])(implicit w: play.api.libs.json.Writes[Long])play.api.libs.json.OFormat[Long] 
<and>   
(implicit f: play.api.libs.json.Format[Long])play.api.libs.json.OFormat[Long]  
cannot be applied to (<error>, <error>)

显然像这样导入(参见 documentation“ctrl+F 导入”)让我陷入麻烦:

import play.api.libs.json._    // so I change this to import only Format and fine
import play.api.libs.functional.syntax._
import play.api.libs.json.Json
import play.api.libs.json.Json._  

现在重载错误消失了,我遇到了更多麻烦:not found: value __ I imported .../functional.syntax._ already just like it在文档中说! This guy遇到了同样的问题,但导入为他修复了它!所以为什么?!我认为这可能只是 Eclipse 的问题,并尝试 play run 无论如何......没有任何改变。美好的。编译器永远是对的。

导入play.api.lib.json.JsPath,将__改为JsPath,wallah:

错误2

值应用不是对象 java.sql.Timestamp 的成员
值 unapply 不是对象 java.sql.Timestamp 的成员


我也尝试改变策略并为此编写一个 Write 而不是 Format,没有花哨的新组合器 (__) 功能,方法是遵循 original blog post the official docs are based on/copy-pasted from :

// I change the imports above to use Writes instead of Format
 implicit val timestampFormat = new Writes1681909005(  // ERROR 3
    def writes(t: Timestamp): JsValue = { // ERROR 4 def is underlined
      Json.obj(
          /* Returns the number of milliseconds since 
           January 1, 1970, 00:00:00 GMT represented by this Timestamp object. */
              "time" -> t.getTime() 
      )
    }
  )

错误 3:trait Writes 是抽象的,无法实例化

错误 4:简单表达式的非法开始

此时我已经无计可施了,所以我只是回到我的剩余思维堆栈并报告我的第一段代码



我非常感谢任何能让我摆脱编码苦难的人

最佳答案

它不一定是您需要的applyunapply 功能。它是 a) 一个在给定参数的情况下构造您需要的任何类型的函数,以及 b) 一个将该类型的实例转换为值元组(通常与输入参数匹配)的函数。

Scala 案例类免费提供的applyunapply 函数恰好可以执行此操作,因此使用它们很方便。但您始终可以自己编写。

通常你可以像这样使用匿名函数来做到这一点:

import java.sql.Timestamp
import play.api.libs.functional.syntax._
import play.api.libs.json._

implicit val timestampFormat: Format1681909005 = (
  (__ \ "time").format[Long]
)((long: Long) => new Timestamp(long), (ts: Timestamp) => (ts.getTime))

但是!在这种情况下,您违反了 API 的限制,该限制阻止您编写这样的格式,只有一个值。 here 根据 this answer 解释了此限制。

对您来说,一种可行的方法是这种看起来更复杂的 hack:

import java.sql.Timestamp
import play.api.libs.functional.syntax._
import play.api.libs.json._

implicit val rds: Reads1681909005 = (__ \ "time").read[Long].map{ long => new Timestamp(long) }
implicit val wrs: Writes1681909005 = (__ \ "time").write[Long].contramap{ (a: Timestamp) => a.getTime }
implicit val fmt: Format1681909005 = Format(rds, wrs)

// Test it...
val testTime = Json.obj("time" -> 123456789)
assert(testTime.as1681909005 == new Timestamp(123456789))

关于java - 如何为 Java 库中没有应用方法的对象编写 JSON 格式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17281291/

有关java - 如何为 Java 库中没有应用方法的对象编写 JSON 格式?的更多相关文章

  1. ruby - 如何使用 Nokogiri 的 xpath 和 at_xpath 方法 - 2

    我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div

  2. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  3. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

    类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

  4. ruby - Facter::Util::Uptime:Module 的未定义方法 get_uptime (NoMethodError) - 2

    我正在尝试设置一个puppet节点,但ruby​​gems似乎不正常。如果我通过它自己的二进制文件(/usr/lib/ruby/gems/1.8/gems/facter-1.5.8/bin/facter)在cli上运行facter,它工作正常,但如果我通过由ruby​​gems(/usr/bin/facter)安装的二进制文件,它抛出:/usr/lib/ruby/1.8/facter/uptime.rb:11:undefinedmethod`get_uptime'forFacter::Util::Uptime:Module(NoMethodError)from/usr/lib/ruby

  5. ruby-on-rails - 按天对 Mongoid 对象进行分组 - 2

    在控制台中反复尝试之后,我想到了这种方法,可以按发生日期对类似activerecord的(Mongoid)对象进行分组。我不确定这是完成此任务的最佳方法,但它确实有效。有没有人有更好的建议,或者这是一个很好的方法?#eventsisanarrayofactiverecord-likeobjectsthatincludeatimeattributeevents.map{|event|#converteventsarrayintoanarrayofhasheswiththedayofthemonthandtheevent{:number=>event.time.day,:event=>ev

  6. ruby - 将差异补丁应用于字符串/文件 - 2

    对于具有离线功能的智能手机应用程序,我正在为Xml文件创建单向文本同步。我希望我的服务器将增量/差异(例如GNU差异补丁)发送到目标设备。这是计划:Time=0Server:hasversion_1ofXmlfile(~800kiB)Client:hasversion_1ofXmlfile(~800kiB)Time=1Server:hasversion_1andversion_2ofXmlfile(each~800kiB)computesdeltaoftheseversions(=patch)(~10kiB)sendspatchtoClient(~10kiBtransferred)Cl

  7. Ruby 方法() 方法 - 2

    我想了解Ruby方法methods()是如何工作的。我尝试使用“ruby方法”在Google上搜索,但这不是我需要的。我也看过ruby​​-doc.org,但我没有找到这种方法。你能详细解释一下它是如何工作的或者给我一个链接吗?更新我用methods()方法做了实验,得到了这样的结果:'labrat'代码classFirstdeffirst_instance_mymethodenddefself.first_class_mymethodendendclassSecond使用类#returnsavailablemethodslistforclassandancestorsputsSeco

  8. ruby - 难道Lua没有和Ruby的method_missing相媲美的东西吗? - 2

    我好像记得Lua有类似Ruby的method_missing的东西。还是我记错了? 最佳答案 表的metatable的__index和__newindex可以用于与Ruby的method_missing相同的效果。 关于ruby-难道Lua没有和Ruby的method_missing相媲美的东西吗?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/7732154/

  9. ruby - 在 Ruby 中编写命令行实用程序 - 2

    我想用ruby​​编写一个小的命令行实用程序并将其作为gem分发。我知道安装后,Guard、Sass和Thor等某些gem可以从命令行自行运行。为了让gem像二进制文件一样可用,我需要在我的gemspec中指定什么。 最佳答案 Gem::Specification.newdo|s|...s.executable='name_of_executable'...endhttp://docs.rubygems.org/read/chapter/20 关于ruby-在Ruby中编写命令行实用程序

  10. ruby-on-rails - Rails 3.2.1 中 ActionMailer 中的未定义方法 'default_content_type=' - 2

    我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer

随机推荐