2013-04-11 7 views
13

Gerekli alan eksik olduğunda json4'lerin istisna atmamasını sağlamak mümkün mü? Ham json dizesinden Ben "özü" nesne atarGerekli alan eksik olduğunda json4'lerin istisna atmamasını sağlamak mümkün mü?

bu bir

org.json4s.package$MappingException: No usable value for pager 
No usable value for rpp 
Did not find value which can be converted into byte 
    at org.json4s.reflect.package$.fail(package.scala:98) 
    at org.json4s.Extraction$ClassInstanceBuilder.org$json4s$Extraction$ClassInstanceBuilder$$buildCtorArg(Extraction.scala:388) 
    at org.json4s.Extraction$ClassInstanceBuilder$$anonfun$11.apply(Extraction.scala:396) 

gibi istisna sadece boş değerli izin mümkün mü?

cevap

17

Oldukça basit, Option ve potansiyellerini, Some ve None kullanmanız gerekir.

val json = ("name" -> "joe") ~ ("age" -> Some(35)); 
val json = ("name" -> "joe") ~ ("age" -> (None: Option[Int])) 

Yukarıdaki durumda bir match içinde olsa dikkat sizin Option için yapılacaktır. None ise, dizeden tamamen kaldırılacak, bu nedenle geri boş bırakılmaz.

Aynı modelde, tamamlanmamış JSON ayrıştırmak için, ile case class kullanın.

case class someModel(
    age: Option[Int], 
    name: Option[String] 
); 
val json = ("name" -> "joe") ~ ("age" -> None); 
parse(json).extract[someModel]; 

Orada

herhangi istisna olmayacak bir yöntemdir ve bu skala API ile bu kullanmak olacaktır çoğaltmak için bir yol extractOpt

parse(json).extractOpt[someModel]; 

olduğunu scala.util.Try:

Try { parse(json).extract[someModel] }.toOption 
4

Veri geçişleriyle uğraşırken bu sorunla uğraştım ve tanımlanmamış alanları doldurmak için varsayılan değerler istedim.

Çözümüm, sonuçları çıkarmadan önce varsayılan değerleri JValue ile birleştirmekti.

val defaultsJson = Extraction.decompose(defaults) 
    val valueJson = JsonUtil.jValue(v) 
    (defaultsJson merge valueJson).extract[T] 

JsonUtil.scala

import org.json4s._ 

    object JsonUtil { 
    import java.nio.charset.StandardCharsets.UTF_8 
    import java.io.{InputStreamReader, ByteArrayInputStream} 

    def jValue(json: String): JValue = { 
     jValue(json.getBytes(UTF_8)) 
    } 

    def jValue(json: Array[Byte]): JValue = { 
     val reader = new InputStreamReader(new ByteArrayInputStream(json), UTF_8) 
     native.JsonParser.parse(reader) 
    } 
    }