Posts mit dem Label JsonSlurper werden angezeigt. Alle Posts anzeigen
Posts mit dem Label JsonSlurper werden angezeigt. Alle Posts anzeigen

Mittwoch, 8. Februar 2012

Groovy Beans To Json

Groovy bietet mit dem groovy.json.JsonBuilder und dem groovy.json.JsonBuilder sehr gute und einfache Möglichkeiten zur Json-Verarbeitung. Hier sollen einfache Groovy Beans (POGO's - Plain Old Groovy Objects) in Json Objekte und wieder zurück transformiert werden.

Dies ist ja dank Builder und Slurper kein Hexenwerk mehr. Das Beispiel-Bean ist folgendes (beliebig austauschbar):

class Book {
    String title
    String author
}



Bean To Json

String toJsonImpl(def bean) {

    JsonBuilder builder = new JsonBuilder()
    builder {
        // Hier folgen Schlüssel und Wert des Eintrags
        // dabei ist eine Variable als Schlüssel nicht möglich
        // deshalb "${ ... }"
        "${ bean.class.getName() }" bean
    }

    return builder.toString()
}

Nun ist folgender Aufruf möglich:

assert '{"Book":{"title":"Die Entw...","author":"G.S."}}'
    == JsonUtil.toJsonImpl(new Book(title: "Die Entw...", author: "G.S."))

Um die Klassen eindeutig identifizieren zu können, wird hier als Json-Key auf oberster Ebene der Name der Klasse benutzt. Und nun der Weg zurück...



Json To Bean

def toBeanImpl(String json) {

    JsonSlurper slurper = new JsonSlurper()
    def beanData = slurper.parseText(json)

    String beanClassName
    Map beanParameter
    beanData.eachWithIndex { key, value, index ->
        if (index == 0) {
            beanClassName = key
            beanParameter = value
        }
    }

    def beanInstance = Class.forName(beanClassName)
            .newInstance(beanParameter)
    return beanInstance
}

Damit ist der Aufruf möglich:

assert JsonUtil.toBeanImpl(
        '{"Book":{"title":"Die Entw...","author":"G.S."}}').properties
        == new Book(title: "Die Entw...", author: "G.S.").properties



Meta Programming

Jetzt können die beiden Funktionen noch an die Beispielklasse “angehängt“ werden. Dass kann zum Beispiel beim automatischen Anhängen an eine Reihe von Klassen interessant sein:

Book.metaClass.toJson = {
    return JsonUtil.toJsonImpl(delegate)
}

Book.metaClass.'static'.toBean = { String json ->
    return JsonUtil.toBeanImpl(json)
}

Die Methode “toBean“ wurde dabei statisch (an der Klasse) hinzugefügt.
Jetzt ist der Aufruf toJson() direkt an der Instanz und toBean(...) an der Klasse möglich:

Book bookBean = new Book(title: "Groovy in Action", author: "Dierk Konig")
String jsonBook = bookBean.toJson()
Book bookBean2 = Book.toBean(jsonBook)
assert bookBean.properties == bookBean2.properties


Na dann viel Spaß beim “Bauen“ und “Schlürfen“.