2015-04-28 25 views
6

Mam zagnieżdżone json, którego struktura nie jest zdefiniowana. Może być inny za każdym razem, gdy uruchamiam, ponieważ czytam ze zdalnego pliku. Muszę przekonwertować ten json na mapę typu Map[String, Any]. Próbowałem zajrzeć do parserów json4s i jackson, ale wydaje się, że nie rozwiązują tego problemu. Czy ktoś wie, jak mogę to osiągnąć?Jak mogę przekonwertować ciąg json na mapę scala?

Przykład wyrażenie:

{"body":{ 
    "method":"string", 
    "events":"string", 
    "clients":"string", 
    "parameter":"string", 
    "channel":"string", 
    "metadata":{ 
     "meta1":"string", 
     "meta2":"string", 
     "meta3":"string" 
    } 
}, 
"timestamp":"string"} 

poziom zagnieżdżenia może być dowolne i nie predefiniowany.
Aby pomóc w przypadku użycia:
Mam Map [String, Any], które muszę przechowywać w pliku jako kopię zapasową. Więc konwertuję go na ciąg json i zapisuję go w pliku. Teraz za każdym razem, gdy otrzymuję nowe dane, muszę pobrać json z pliku, przekonwertować go na mapę i wykonać pewne obliczenia. Nie mogę zapisać mapy w pamięci, ponieważ straciłbym ją, gdyby moja praca się nie udała.
Potrzebuję rozwiązania, które konwertuje ciąg json z powrotem na oryginalną mapę, którą miałem przed przekonwertowaniem.

+0

dlaczego nie używasz JSON.parseRaw? – turutosiya

+0

Czy możesz wysłać przykład JSON i innych pomocnych kodów? lub informacje? –

+0

Jak można serializować "Any"? –

Odpowiedz

6

Próbowałem następującą metodę z json4s 3.2.11 i działa:

import org.json4s._ 
import org.json4s.jackson.JsonMethods._ 

//... 
def jsonStrToMap(jsonStr: String): Map[String, Any] = { 
    implicit val formats = org.json4s.DefaultFormats 

    parse(jsonStr).extract[Map[String, Any]] 
} 

Może nie definiują implicit val typu Formats? Zauważ także, że nie musisz mieć implicit val w obrębie każdej metody, dopóki jest ona w zasięgu możliwa do znalezienia.

+0

Hey @lambdista, Kod wygląda idealnie. i chcę to zaimplementować jako funkcję niestandardową w iskrze, ale ramki danych iskry nie obsługują "jakiegokolwiek" ref i próbowałem tego samego z String, String, ale wydaje się, że nie działa. Czy masz jakiś pomysł, w jaki sposób możemy zrobić typ? Dzięki – GSR

1

Można użyć następującego kodu do analizowania ciąg JSON do Map[String, Any]

val jsonMap = parse(jsonString).values.asInstanceOf[Map[String, Any]] 

Jest to jednak nie typesafe i stąd powinny być stosowane z dużą ostrożnością podczas wydobywania wartości z mapy.