2013-06-19 29 views
14

Tôi đã tạo một ứng dụng Play (2.1) sử dụng cấu hình trong conf/application.conf trong Hocon format.Hocon: Đọc một mảng các đối tượng từ một tệp cấu hình

Tôi muốn thêm một loạt các dự án vào cấu hình. Các tập tin conf/application.conf trông như thế này:

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

Tôi cố gắng đọc cấu hình này trong dự án Scala của tôi:

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* 

Cách tiếp cận này có vẻ là rất phức tạp, tôi bị mất trong rất nhiều Options, và IDE Eclipse của tôi không thể cho tôi bất kỳ gợi ý nào về các lớp.

Có ai là ví dụ về cách bạn có thể đọc một mảng đối tượng từ tệp cấu hình Hocon không? Hoặc tôi có nên sử dụng cho tệp JSON này với trình phân tích cú pháp JSON thay vì Hocon không?

Trả lời

8

Các công trình sau đây cho tôi trong Chơi 2.1.2 (Tôi không có một .maybeApplication trên đối tượng play.Play của tôi mặc dù, và tôi không chắc chắn lý do tại sao bạn làm):

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) 

đầu ra Giving:

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

Không có nhiều khác biệt, mặc dù tôi không bị mất rất nhiều trường hợp Option hoặc (một lần nữa, khác với API bạn dường như có).

Quan trọng hơn, getConfigList có vẻ là một trận đấu chặt chẽ hơn cho những gì bạn muốn làm, vì nó trả List[play.Configuration], cho phép bạn chỉ định các loại trên hồi thay vì phải dùng đến phôi hoặc .toString() cuộc gọi.

+0

Cảm ơn, trông dễ dàng hơn rất nhiều. Tôi sẽ kiểm tra câu trả lời này trong một vài tuần (... ngày lễ ...) với Play 2.1.2. – Sonson123

1

Cho rằng nội dung của mảng là Json và bạn có một lớp chữ thường, bạn có thể thử sử dụng Json Play API và làm việc với các đối tượng theo cách đó. Phần Inception sẽ làm cho nó tầm thường.

+0

Vâng, phân tích một tệp JSON có vẻ là dễ dàng hơn rất nhiều so với phân tích Hocon. Đây sẽ là một giải pháp, nhưng sau đó tôi mất những lợi thế mà cung cấp Hocon trên Json. Một Hocon-Parser-API như Json Play Api sẽ rất tuyệt. – Sonson123

2

Bạn đang cố gắng làm gì với phần này y.toList.map{z =>? Nếu bạn muốn có một bộ sưu tập các Project như kết quả, tại sao không chỉ làm:

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

Trong trường hợp này, các hoạt động map nên lấy trường hợp của ConfigObject đó là y là gì. Điều đó có vẻ là tất cả những gì bạn cần để có được các trường hợp Project của mình, vì vậy tôi không chắc chắn tại sao bạn là toList ing rằng ConfigObject (là Map) vào Danh sách Tuple2 và sau đó lập bản đồ tiếp tục lại.

+1

'getObjectList' trả về một' Tùy chọn [java.util.List [_ <: ConfigObject]] ', vì vậy' y' là một 'java.util.Liệt kê [_ <: ConfigObject] '. Một điều khác: 'y.get (" name "). ToString' là f.ex. 'ConfigString (" google ")', tôi không biết cách lấy giá trị thô từ nó. Nó có vẻ phức tạp để đọc một mảng đối tượng, phải có một cách dễ dàng hơn? – Sonson123

2

Nếu một cấu hình HOCON bình thường sau đó tương tự như strangefeatures trả lời này sẽ làm việc

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 

(Sử dụng Play 2.4+ Injection)