【问题标题】:Hocon: Read an array of objects from a configuration fileHocon:从配置文件中读取对象数组
【发布时间】:2013-06-16 06:40:54
【问题描述】:

我创建了一个 Play 应用程序 (2.1),它使用 conf/application.conf 中的配置 Hocon format

我想在配置中添加一组项目。文件conf/application.conf 如下所示:

...
projects = [
  {name: "SO", url: "http://stackoverflow.com/"},
  {name: "google", url: "http://google.com"}
]

我尝试在我的 Scala 项目中读取此配置:

import scala.collection.JavaConversions._
case class Project(name: String, url: String)

val projectList: List[Project] =
  Play.maybeApplication.map{x =>
    val simpleConfig = x.configration.getObjectList("projects").map{y =>
      y.toList.map{z =>
        Project(z.get("name").toString, z.get("url").toString) // ?!? doesn't work

      ... 
   }}}}}}}}  // *arg*

这种方法似乎很复杂,我迷失在很多Options 中,而且我的 Eclipse IDE 无法给我任何关于类的提示。

有没有人举例说明如何从 Hocon 配置文件中读取对象数组? 或者我应该为此使用带有 JSON 解析器而不是 Hocon 的 JSON 文件?

【问题讨论】:

    标签: json scala configuration playframework playframework-2.1


    【解决方案1】:

    以下内容在 Play 2.1.2 中对我有用(虽然我的 play.Play 对象上没有 .maybeApplication,但我不确定你为什么这样做):

    import play.Play
    import scala.collection.JavaConversions._
    case class Project(name: String, url: String)
    
    val projectList: List[Project] = {
      val projs = Play.application.configuration.getConfigList("projects") map { p => 
        Project(p.getString("name"), p.getString("url")) }
      projs.toList
    }
    
    println(projectList)
    

    给出输出:

    List(Project(SO,http://stackoverflow.com/), Project(google,http://google.com))
    

    并没有太大的不同,尽管我也不会迷失在很多 Option 实例中(同样,与您似乎拥有的 API 不同)。

    更重要的是,getConfigList 似乎更适合您想要做的事情,因为它返回 List[play.Configuration],这使您能够在检索时指定类型,而不是诉诸强制转换或 .toString() 调用。

    【讨论】:

    • 谢谢,看起来容易多了。我将在几周后(...假期...)使用 Play 2.1.2 检查这个答案。
    【解决方案2】:

    你想用这部分y.toList.map{z =>来完成什么?如果你想要一个Project 的集合作为结果,为什么不这样做:

    val simpleConfig = x.configration.getObjectList("projects").map{y =>
       Project(y.get("name").toString, y.get("url").toString)
    }
    

    在这种情况下,map 操作应该采用 ConfigObject 的实例,这就是 y 的含义。这似乎是您获得Project 实例所需的全部内容,所以我不确定您为什么将toListConfigObject(这是Map)放入Tuple2 的列表中,然后进一步再次映射。

    【讨论】:

    • getObjectList 返回一个Option[java.util.List[_ <: ConfigObject]],所以y 是一个java.util.List[_ <: ConfigObject]。另一件事:y.get("name").toString 是 f.ex。 ConfigString("google"),我不知道如何从中获取原始值。读取对象数组好像很复杂,一定有更简单的方法?
    【解决方案3】:

    如果一个普通的 HOCON 配置然后类似于奇怪的功能回答这将工作

    import javax.inject._
    import play.api.Configuration
    
    trait Barfoo {
      def configuration: Configuration     
      def projects = for {
        projectsFound <- configuration.getConfigList("projects").toList
        projectConfig <- projectsFound
        name <- projectConfig.getString("name").toList
        url  <- projectConfig.getString("url").toList
      } yield Project(name,url)
    }
    
    class Foobar @Inject() (val configuration: Configuration) extends Barfoo
    

    (使用 Play 2.4+ 注入)

    【讨论】:

      【解决方案4】:

      鉴于数组的内容是 Json 并且您有一个案例类,您可以尝试使用 Json Play API 并以这种方式处理对象。 Inception 部分应该让它变得微不足道。

      【讨论】:

      • 是的,解析 JSON 文件似乎比解析 Hocon 容易得多。这将是一个解决方案,但随后我失去了 Hocon 优于 Json 的优势。像 Json Play Api 这样的 Hocon-Parser-API 会很酷。
      猜你喜欢
      • 1970-01-01
      • 2021-11-09
      • 1970-01-01
      • 1970-01-01
      • 2016-03-04
      • 2011-09-26
      • 1970-01-01
      相关资源
      最近更新 更多