2013-02-22 21 views
5

Chciałbym zmienić sposób, w jaki wyliczenia są kierowane do JSON. Obecnie używam domyślnego grails.converters.JSON (jako JSON), a na przykład w kontroler używam:Wyliczanie Grails do JSON

FilmKind.values ​​() jako JSON

Wyjście to jest:

"kind":[{"enumType":"FilmKind","name":"DRAMA"},{"enumType":"FilmKind","name":"ACTION"}] 

Chciałbym usunąć "enumType" i po prostu wrócić:

"kind":["DRAMA","ACTION"] 

jestem szuka rozwiązania, które pozwoliłyby mi nadal używać

jako JSON

bo nie chcą Marshall każde wyliczenie indywidualnie.

Odpowiedz

10

bo nie chcą Marshall każde wyliczenie indywidualnie.

Cóż, chyba że chcesz napisać własny konwerter JSON, najlepszym rozwiązaniem jest układanie. Powód jest taki, że jedynym prawdziwym sposobem jest robienie tego, co sugeruje Sergio, a ty będziesz musiał wywoływać ten kod wszędzie, gdzie go potrzebujesz. A jeśli FilmKind jest własnością innej klasy, to jego rozwiązanie w ogóle nie zadziała.

Proponuję Marshallerów i oto, jak bym to zrobił. Utworzyć klasę o nazwie FilmKindMarsaller:

class FilmKindMarshaller { 
    void register() { 
    JSON.registerObjectMarshaller(FilmKind) { FilmKind filmKind -> 
     [ 
      name: filmKind.toString() 

     ] 
    } 
    } 
} 

następnie dodaj następującą do bootstrap:

[ new FilmKindMarshaller() ].each { it.register() } 

powyższe jest tak, że można po prostu zachować dodając wystąpień każdego naziemnego trzeba.

Teraz, w każdej chwili FilmKind jest JSON'ified, niezależnie od tego, czy jest to samodzielna klasa, czy część klasy nadrzędnej, otrzymujesz pożądany JSON, sans enumType.

1

Jak o:

def display = [kind:[]] 
FilmKind.values().each { val -> 
    display.kind.add(val.value) 
} 

render display as JSON 
+0

Dzięki za odpowiedź! To dobrze, po prostu musiałem go nieco zmienić, zamiast wartości val.value należy użyć wartości. Ale nadal chciałbym rozwiązania, które robi to na niższym poziomie, więc nie muszę pisać go wszędzie. Problem pojawia się również, gdy robię "jako JSON" na obiekcie domeny, który zawiera właściwość typu wyliczeniowego, przypisana wartość wyliczenia jest nadal wysyłana z "enumType". – MBozic

+0

Aby uzyskać niższy poziom, sprawdź odpowiedź Gregga. –

2

Można zarejestrować niestandardowego obiektu naziemnego dla swojej klasy domeny w celu umożliwienia as JSON. W swojej Bootstrap.groovy, można zrobić coś takiego:

JSON.registerObjectMarshaller(FilmKind) { 
    def result = [:] 
    def props = ['name'] 
    props.each { prop -> 
     result[prop] = it."$prop" 
    } 
    result 
} 
13

na wypadek gdyby ktoś wędruje jak przekonwertować wszystkie wartości enum do prostych wartości Smyczkowych w sposób ogólny:

class EnumTypeHidingJSONMarshaller { 
    void register() { 
     JSON.registerObjectMarshaller(Enum) { Enum someEnum -> 
      someEnum.toString() 
     } 
    } 
} 
+5

Lub krótszy: JSON.registerObjectMarshaller (Enum, {Enum e -> e.name()}) –

+0

Czy to działa dla Grails3? – bitsnaps