2015-10-31 8 views
2

У меня есть json, где имя атрибута имеет специальный символ. Попытка заставить его разобраться с распылителем json. Ниже приведен код Как получить имя атрибута в json @xml: lang будет разбираться в классе case.спрей json атрибут со специальным char

import spray.json._ 
import DefaultJsonProtocol._ 

object SpecialCharInName extends App { 

    case class Person(name: String, `@xml:lang`: String) 

    val json = """ {"name":"MyName", "@xml:lang":"US"} """ 

    object PersonProtocol extends DefaultJsonProtocol { 
    implicit val personFormat = jsonFormat2(Person) 
    } 

    import PersonProtocol._ 
    val person = json.parseJson 
    val personClass = person.convertTo[Person] 

    println(personClass) 

} 

Код выше бросает исключение, как показано ниже

[error] (run-main-0) spray.json.DeserializationException: Object is missing required member '@xml$colonlang' 
spray.json.DeserializationException: Object is missing required member '@xml$colonlang' 
at spray.json.package$.deserializationError(package.scala:23) 
at spray.json.ProductFormats$class.fromField(ProductFormats.scala:60) 
at c.c.s.f.v.d.SpecialCharInName$PersonProtocol$.fromField(SpecialCharInName.scala:12) 
at spray.json.ProductFormatsInstances$$anon$2.read(ProductFormatsInstances.scala:56) 
at spray.json.ProductFormatsInstances$$anon$2.read(ProductFormatsInstances.scala:46) 
at spray.json.JsValue.convertTo(JsValue.scala:31) 
at c.c.s.f.v.d.SpecialCharInName$.delayedEndpoint$com$comcast$sv$fabric$vimond$domain$SpecialCharInName$1(SpecialCharInName.scala:20) 
at c.c.s.f.v.d.SpecialCharInName$delayedInit$body.apply(SpecialCharInName.scala:6) 
at scala.Function0$class.apply$mcV$sp(Function0.scala:40) 
at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:12) 
at scala.App$$anonfun$main$1.apply(App.scala:76) 
at scala.App$$anonfun$main$1.apply(App.scala:76) 
at scala.collection.immutable.List.foreach(List.scala:381) 
at scala.collection.generic.TraversableForwarder$class.foreach(TraversableForwarder.scala:35) 
at scala.App$class.main(App.scala:76) 
at c.c.s.f.v.d.SpecialCharInName$.main(SpecialCharInName.scala:6) 
at c.c.s.f.v.d.SpecialCharInName.main(SpecialCharInName.scala) 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
at java.lang.reflect.Method.invoke(Method.java:497) 
Caused by: java.util.NoSuchElementException: key not found: @xml$colonlang 
at scala.collection.MapLike$class.default(MapLike.scala:228) 
at scala.collection.AbstractMap.default(Map.scala:59) 
at scala.collection.MapLike$class.apply(MapLike.scala:141) 
at scala.collection.AbstractMap.apply(Map.scala:59) 
at spray.json.ProductFormats$class.fromField(ProductFormats.scala:57) 
at c.c.s.f.v.d.SpecialCharInName$PersonProtocol$.fromField(SpecialCharInName.scala:12) 
at spray.json.ProductFormatsInstances$$anon$2.read(ProductFormatsInstances.scala:56) 
at spray.json.ProductFormatsInstances$$anon$2.read(ProductFormatsInstances.scala:46) 
at spray.json.JsValue.convertTo(JsValue.scala:31) 
at c.c.s.f.v.d.SpecialCharInName$.delayedEndpoint$com$comcast$sv$fabric$vimond$domain$SpecialCharInName$1(SpecialCharInName.scala:20) 
at c.c.s.f.v.d.SpecialCharInName$delayedInit$body.apply(SpecialCharInName.scala:6) 
at scala.Function0$class.apply$mcV$sp(Function0.scala:40) 
at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:12) 
at scala.App$$anonfun$main$1.apply(App.scala:76) 
at scala.App$$anonfun$main$1.apply(App.scala:76) 
at scala.collection.immutable.List.foreach(List.scala:381) 
at scala.collection.generic.TraversableForwarder$class.foreach(TraversableForwarder.scala:35) 
at scala.App$class.main(App.scala:76) 
at c.c.s.f.v.d.SpecialCharInName$.main(SpecialCharInName.scala:6) 
at c.c.s.f.v.d.SpecialCharInName.main(SpecialCharInName.scala) 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
at java.lang.reflect.Method.invoke(Method.java:497) 

Спасибо за вашу помощь заранее.

Саад

ответ

3
import spray.json._ 
import DefaultJsonProtocol._ 

object SpecialCharInName extends App { 

    case class Person(name: String, `@xml:lang`: String) 

    val json = """ {"name":"MyName", "@xml:lang":"US"} """ 

    object PersonProtocol extends DefaultJsonProtocol { 
    implicit val personFormat = jsonFormat(Person.apply, "name", "@xml:lang") 
    } 

    import PersonProtocol._ 

    val person = json.parseJson 
    val personClass = person.convertTo[Person] 
    println(personClass) 
} 

Наслаждайтесь :)

Проще говоря, использовать специальный jsonFormat метод, который принимает метод строитель (как apply) и список имен свойств, которые должны представить в документе JSON является разобран. По умолчанию это не очень хорошо работает в вашем случае.

+0

Спасибо, это сработало. – saad

+0

Мне было бы интересно узнать, поддерживает ли https://github.com/fommil/spray-json-shapeless это из коробки. Если нет, пожалуйста, поднимите билет на свой пример. – fommil