Hocon:从配置文件中读取一组对象

时间:2013-06-19 16:12:11

标签: json scala configuration playframework playframework-2.1

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

我想在配置中添加一系列项目。文件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文件吗?

4 个答案:

答案 0 :(得分:8)

以下内容适用于Play 2.1.2(我的.maybeApplication对象上没有play.Play,但我不知道你为什么这样做:

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],这使您能够在检索时指定类型而不是诉诸强制转换或{{1调用。

答案 1 :(得分: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个实例所需的全部内容,因此我不确定您为什么toList ConfigObjectMap} Tuple2列表,然后再次进一步映射。

答案 2 :(得分:2)

如果正常的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+注射)

答案 3 :(得分:1)

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