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

时间:2021-05-25 21:29:29

I have created an Play application (2.1) which uses the configuration in conf/application.conf in the Hocon format.

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

I want to add an array of projects in the configuration. The file conf/application.conf looks like this:

我想在配置中添加一个项目数组。conf /应用程序的文件。设计是这样的:

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

I try to read this configuration in my Scala project:

我尝试在我的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*

This approach seems to be very complicated, I am lost in a lot of Options, and my Eclipse IDE cannot give me any hints about the classes.

这种方法似乎非常复杂,我迷失在许多选项中,我的Eclipse IDE不能提供关于类的任何提示。

Has anybody an example how you can read an array of objects from a Hocon configuration file? Or should I use for this a JSON-file with an JSON-parser instead of Hocon?

有人知道如何从Hocon配置文件中读取对象数组吗?或者,我应该使用带有json解析器的json文件而不是Hocon吗?

4 个解决方案

#1


8  

The following works for me in Play 2.1.2 (I don't have a .maybeApplication on my play.Play object though, and I'm not sure why you do):

以下是我在2.1.2(我没有。may应用在我的剧本上。不过玩对象游戏,我不知道你为什么玩):

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)

Giving output:

给输出:

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

There's not a whole lot different, although I don't get lost in a whole lot of Option instances either (again, different from the API you seem to have).

这并没有很大的不同,尽管我也没有在很多选项实例中迷失(同样,与您看起来拥有的API不同)。

More importantly, getConfigList seems to be a closer match for what you want to do, since it returns List[play.Configuration], which enables you to specify types on retrieval instead of resorting to casts or .toString() calls.

更重要的是,getConfigList似乎更适合您想要做的事情,因为它返回List[play]。[Configuration],使您可以在检索时指定类型,而不必求助于强制类型转换或. tostring()调用。

#2


2  

What are you trying to accomplish with this part y.toList.map{z =>? If you want a collection of Project as the result, why not just do:

你想用这部分来完成什么?地图{ z = > ?如果你想要一个项目的集合,为什么不做:

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

In this case, the map operation should be taking instances of ConfigObject which is what y is. That seems to be all you need to get your Project instances, so I'm not sure why you are toListing that ConfigObject (which is a Map) into a List of Tuple2 and then further mapping that again.

在这种情况下,映射操作应该取ConfigObject的实例,也就是y。这似乎是获取项目实例所需的全部内容,因此我不确定为什么要将这个ConfigObject(一个映射)列出到Tuple2的列表中,然后再进一步映射它。

#3


2  

If a normal HOCON configuration then similar to strangefeatures answer this will work

如果一个正常的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

(Using Play 2.4+ Injection)

(使用玩2.4 +注入)

#4


1  

Given that the contents of the array are Json and you have a case class, you could try to use the Json Play API and work with the objects in that way. The Inception part should make it trivial.

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

#1


8  

The following works for me in Play 2.1.2 (I don't have a .maybeApplication on my play.Play object though, and I'm not sure why you do):

以下是我在2.1.2(我没有。may应用在我的剧本上。不过玩对象游戏,我不知道你为什么玩):

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)

Giving output:

给输出:

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

There's not a whole lot different, although I don't get lost in a whole lot of Option instances either (again, different from the API you seem to have).

这并没有很大的不同,尽管我也没有在很多选项实例中迷失(同样,与您看起来拥有的API不同)。

More importantly, getConfigList seems to be a closer match for what you want to do, since it returns List[play.Configuration], which enables you to specify types on retrieval instead of resorting to casts or .toString() calls.

更重要的是,getConfigList似乎更适合您想要做的事情,因为它返回List[play]。[Configuration],使您可以在检索时指定类型,而不必求助于强制类型转换或. tostring()调用。

#2


2  

What are you trying to accomplish with this part y.toList.map{z =>? If you want a collection of Project as the result, why not just do:

你想用这部分来完成什么?地图{ z = > ?如果你想要一个项目的集合,为什么不做:

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

In this case, the map operation should be taking instances of ConfigObject which is what y is. That seems to be all you need to get your Project instances, so I'm not sure why you are toListing that ConfigObject (which is a Map) into a List of Tuple2 and then further mapping that again.

在这种情况下,映射操作应该取ConfigObject的实例,也就是y。这似乎是获取项目实例所需的全部内容,因此我不确定为什么要将这个ConfigObject(一个映射)列出到Tuple2的列表中,然后再进一步映射它。

#3


2  

If a normal HOCON configuration then similar to strangefeatures answer this will work

如果一个正常的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

(Using Play 2.4+ Injection)

(使用玩2.4 +注入)

#4


1  

Given that the contents of the array are Json and you have a case class, you could try to use the Json Play API and work with the objects in that way. The Inception part should make it trivial.

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