2011-01-27 10 views
13

Używam biblioteki jackson do serializowania/deserializacji do/z JSON. Potrzebuję, aby ten JSON miał najmniejszy rozmiar, więc włączam funkcję ALLOW_UNQUOTED_FIELD_NAMES, aby wyeliminować wszystkie cytaty. Wiem, że usuwanie cytatów nie jest standardowym jsonem, ale zrobienie JSON small jest ciężkim wymogiem projektu. Wygenerowany json działa, ale kiedy ja próbuje odczytać wartość json Dostaję wyjątek:ALLOW_UNQUOTED_FIELD_NAMES w bibliotece JONÓW JONÓW

org.codehaus.jackson.JsonParseException: Nieoczekiwany znak („9” (kod 57)): oczekiwał albo poprawnej nazwy znaków (dla niecytowanej nazwy) lub podwójnego cudzysłowu (dla kwotowanych), aby rozpocząć nazwę pola w [Źródło: [email protected]; Linia 1, kolumna: 3]

Wyjątkiem od powyżej jest generowany, kiedy odczytać ten json:

{90110a2e-febd-470f-afa4-cf7e890d31b9:0,eec652ad-a4d9-4eb1-8d24-7c1a0c29449f:1} 

Sposób ją przeczytać jest:

Map<String, Object> valuesMap = oM.readValue(json, new TypeReference<Map<String, Object>>() {}); 

i przedmiot mapper Używam obu do odczytu i zapisu wartości:

private static final ObjectMapper om = new ObjectMapper(); 
static { 
    om.configure(JsonGenerator.Feature.QUOTE_FIELD_NAMES, false); 
    om.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true); 
    om.configure(SerializationConfig.Feature.WRITE_DATES_AS_TIMESTAMPS, true); 
    om.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false); 
    om.getSerializationConfig().setSerializationInclusion(JsonSerialize.Inclusion.NON_NULL); 
} 

Używam wersji 1.6.3 z Jackson, zarówno w projektach nadawcy, jak i odbiorcy. Potrzebna wersja dla tej funkcji to 1.2+, więc pomyślałem, że może nie korzystam z tej wersji, ale mój odbiornik to aplikacja Spring i sprawdziłem, czy biblioteka zainstalowana w folderze libs to 1.6.3.

Co mogę zrobić źle? Może tej funkcji nie można używać z mapami.

Mam inne pytanie, Do tej pory po prostu wysyłam mapę, gdzie klucz jest po prostu wartością uuid, a wartość jest liczbą. Czy mogę mieć jakieś problemy, jeśli wyślę wartość ze znakami specjalnymi z włączoną funkcją ALLOW_UNQUOTED_FIELD_NAMES? Czy jackson uniknie tych postaci?

Dzięki.

Odpowiedz

5

Wydaje się, że Jackson z numerem QUOTE_FIELD_NAMES produkuje takie dane wyjściowe, że nie jest w stanie odczytać nawet z ALLOW_UNQUOTED_FIELD_NAMES. Prawdopodobnie będziesz musiał zaimplementować niestandardowe JsonParser dla niestandardowego parsowania wejściowego.

Problem polega na tym, że generujesz niestandardowy JSON i nie ma gwarancji, że klient poradzi sobie z nim poprawnie. Jeśli jednak nie ujawnisz go poza aplikacjami i dbasz o rozmiar, możesz sparsować/wygenerować format binarny, taki jak Jackson Smile. Zobacz http://www.cowtowncoder.com/blog/archives/2010/09/entry_418.html (2.4).

+0

Bardzo dobry punkt dotyczący Uśmiechu - może być zwarty, zwł. podczas włączania odnośników wstecznej wartości ciągu znaków (jeśli istnieje wiele powtarzających się wartości ciągów, takich jak wyliczone wartości) – StaxMan

2

Wierzę, że problem jest związany z JavaScript sintax, a nie z Jacksonem ani JSON.

W języku JavaScript nazwa to litera opcjonalnie, po której następuje jedna lub więcej liter, cyfr lub półek, więc 90110a2e-febd-470f-afa4-cf7e890d31b9 nie jest legalną nazwą Javascript.

Cytaty dotyczące nazwy usługi są opcjonalne, jeśli nazwa jest legalną nazwą JavaScript, a nie słowem zastrzeżonym. Więc cytaty są wymagane wokół "imienia", ale są opcjonalne wokół first_name.

BTW, jeśli jesteś tak zaniepokojony rozmiar JSON, dlaczego nie gzip go?

+0

Dzięki, że pomyślałem o tym, ale nie byłem pewien, czy zmienne były legalne, czy nie. Chociaż json nie jest używany w javascript (jest wysyłany z klienta Java do aplikacji JEE), to co mówisz może być słuszne. Jeśli chodzi o gzip, już wysyłam jsona, ale dzięki za pomysł. – Javi

6

OK, odpowiedź Pingw33n jest prawie poprawna, myślę. A więc: tak, możesz użyć tej funkcji; ale jest to raczej heurystyczne - ponieważ nie ma specyfikacji, jak powinny wyglądać nienotowane nazwy (w końcu JSON zezwala na dowolne znaki dla nazw!); lub, co się stanie, jeśli zastosuje się jakiś mechanizm ucieczki, to nikt nie zgadnie, co należy zapisać lub zaakceptować.

W tym konkretnym przypadku jest to prawdopodobnie "-" charakter powodujący problem. Nie jest to prawna część nazwy JavaScript, która jest przybliżeniem używanym przez Jacksona.

Jednym z możliwych rozwiązań będzie to, że Jackson uniknie takich znaków w nazwach właściwości (nie pamiętam, jak to się robi obecnie, jeśli jakieś znaki są cytowane). Jeśli uda Ci się znaleźć prosty przypadek testowy, możesz zgłosić prośbę o dodanie Jira pod numer Jackson Jira, aby uzyskać dodawanie ucieczki (i upewnić się, że analizator składni może odblokować zwykłą wersję odwrotnego ukośnika).

+1

Oh. W rzeczywistości jest to jeszcze prostsze: ponieważ identyfikatory javascript nie mogą rozpoczynać się od liczb, właśnie to powoduje problem. Możliwe, że można to również złagodzić w trybie ALLOW_UNQUOTED_FIELD_NAMES; w tym celu pomocne byłoby zapytanie o funkcję Jira. – StaxMan

Powiązane problemy