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

17

我创建了一个使用Hocon格式的配置文件conf/application.conf的Play应用程序(2.1)。

我想在配置中添加一个项目数组。文件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*

这种方法看起来非常复杂,我深陷于大量的选项中,而我的Eclipse IDE不能给我有关类的任何提示。

是否有人有一个示例,可以从Hocon配置文件中读取对象数组? 或者我应该使用JSON文件和JSON解析器代替Hocon?

4个回答

9

以下对我在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检查这个答案。 - Sonson123

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实例所需的全部内容,所以我不确定为什么你要将那个ConfigObject(它是一个Map)转换为Tuple2列表,然后再进行进一步映射。

1
getObjectList 返回一个 Option[java.util.List[_ <: ConfigObject]],所以 y 是一个 java.util.List[_ <: ConfigObject]。另外一件事:y.get("name").toString 是例如 ConfigString("google"),我不知道如何从中获取原始值。读取对象数组似乎很复杂,难道没有更简单的方法吗? - Sonson123

2
如果是普通的HOCON配置,那么类似于strangefeatures所提供的答案,这个方法可以工作。
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+注入)

1

考虑到数组的内容是Json格式,如果您有一个案例类,可以尝试使用Json Play API并以这种方式处理对象。 Inception 部分应该很简单。


是的,解析JSON文件似乎比解析Hocon要容易得多。这可能是一个解决方案,但我会失去Hocon相对于Json所提供的优势。像Json Play Api一样的Hocon-Parser-API会很酷。 - Sonson123

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接