2013-01-25 82 views
2

我正在使用JSON4S生成一些JSON。如何使用JSON4S有條件地生成JSON

如果條件滿足,我想產生如下:

{"fld1":"always", "fld2":"sometimes"} 

如果條件不滿足,我想製作:

{"fld1":"always"} 

我已經試了遠是:

val fld1 = "fld1" -> "always" 

val json = if(condition) ("fld2" -> "sometimes") ~ fld1 else fld1 

compact(render(json)) 

然而,這給了我在render「發現類型不匹配:用產品序列化。要求:org.json4s.package.JValue」

有趣這是render(("fld2" -> "sometimes") ~ fld1)作品,也是如此render(fld1)的問題似乎是與推斷json類型

我怎麼能解決這個問題。?

回答

2

不是我能想到的最好的辦法,但在宣佈自己的類型應該工作:

val json: JObject = 
    if(condition) ("fld2" -> "sometimes") ~ fld1 else fld1 

compact(render(json)) 

另外請注意,你可以得到的類型推斷,以幫助自己的:如果你能在一個渲染去:

compact(render(
    if(condition) fld1 ~ ("fld2" -> "sometimes") else fld1 
)) 
+0

謝謝。我一次完成渲染,但看起來太雜亂(我的代碼比例子更復雜)。但是明確聲明json的類型的確有竅門。 – Eduardo

2

另一種方法是將條件值框中的選項。

val json = fld1 ~ ("fld2" -> (if (condition) Some("sometimes") else None)) 

compact(render(json)) 
4

雖然兩個當前的答案都給出了適當的解決方法,但這兩個解釋都沒有。的問題是,如果我們有兩種類型,如下所示:

trait Foo 
trait Bar 

和隱式轉換(或視圖)從一個到另一個:

implicit def foo2bar(foo: Foo): Bar = new Bar {} 

有條件與Foothen子句和Bar對於其else子句仍將鍵入爲FooBar(在這種情況下爲Object,在您的情況下爲Product with Serializable)的最小上限。

這是因爲該類型推理系統是不會介入,並說,好吧,我們可以查看FooBar,所以我就輸入了整個事情的Bar

如果您考慮它,這是有道理的 - 例如,它是否願意處理這樣的條件,如果我們有兩種隱式轉換,它會做什麼?

在你的情況下,then子句鍵入爲JObject,而else子句是(String, String)。我們有一個觀點,從後者到前者,但在這裏不會使用它,除非您希望整個事情最終成爲JObject,無論是通過顯式聲明類型還是通過在上下文中使用表達式它必須是JObject

鑑於所有這一切,最簡單的解決辦法可能只是要確保兩個條款進行適當從一開始打字,通過爲fld1提供類型註釋是這樣的:

val fld1: JObject = "fld1" -> "always" 

現在你的條件將是按照原樣進行適當的輸入,不需要類型註釋。

+0

感謝您的非常明確的解釋。 – Eduardo

+0

+1這是我希望我能給出但不能做到的那種簡單明瞭的解釋。 – Faiz