2011-01-27 1 views
13

JSONとのシリアル化/逆シリアル化にjacksonライブラリを使用しています。 JSONのサイズができるだけ小さいので、ALLOW_UNQUOTED_FIELD_NAMES機能を有効にしてすべての引用符を削除する必要があります。引用符を削除することは標準のjsonではないことがわかりますが、jsonを小さくすることはプロジェクトの難しい要件です。 JSONの作品を生成したが、私は、私は例外を取得していたJSON値を読み取ろうとしたら:JackonのALLOW_UNQUOTED_FIELD_NAMES JSONライブラリ

org.codehaus.jackson.JsonParseException: 予期しない文字(「9」(コード57)): は、いずれかの有効な名前に (引用符で囲まれていない名前のための)文字や 二重引用符(引用されたため)[ソースで フィールド名を開始するには期待していた: [email protected]を。行:1、 カラム:私はこのJSONを読んだとき3]

は、上記例外がスローされます。私はそれを読む

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

方法がある:

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

とオブジェクト私が値の読み書きに使用するマッパーは次のとおりです。

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); 
} 

私は送信者プロジェクトと受信者プロジェクトの両方でJacksonのバージョン1.6.3を使用しています。この機能のために必要なバージョンは1.2+ですので、私はこのバージョンを使用していないかもしれないと思ったのですが、受信機はSpringアプリケーションで、libsフォルダにインストールされているライブラリが1.6.3であることを確認しました。

何が間違っている可能性がありますか?たぶん、この機能をマップで使用することはできません。

私は別の質問があります。これまでのところ、キーは単なるuuid値で、値は数値です。 ALLOW_UNQUOTED_FIELD_NAMES機能のある特殊文字を使用して値を送信すると問題はありますか?ジャックソンはこの文字をエスケープするのだろうか?

ありがとうございました。

答えて

5

QUOTE_FIELD_NAMESのようなジャクソンのようなものは、ALLOW_UNQUOTED_FIELD_NAMESをオンにしてもそれ自体を読み取ることができない出力を生成することがあります。非標準の入力解析には、おそらくカスタムJsonParserを実装する必要があります。

問題は、標準以外のJSONを生成しており、クライアントが正しく処理することが保証されていないことです。しかし、あなたのアプリケーションの外にそれを公開せず、大きさを気にかけなければ、JacksonのSmileのようにバイナリ形式を解析/生成することができます。 http://www.cowtowncoder.com/blog/archives/2010/09/entry_418.html(2.4)を参照してください。

+0

スマイルについての非常に良い点 - コンパクトにすることができます。文字列値の後ろ参照を有効にするとき(列挙された値のような多くの繰り返し文字列値がある場合) – StaxMan

2

私はこの問題がJavascriptのsintaxに関連していると思うし、JacksonやJSONには関係しないと思う。

名前では、1つ以上の文字、数字、またはアンダーバーが続いてもかまいません.90110a2e-febd-470f-afa4-cf7e890d31b9は合法的なJavascript名ではありません。

名前が正当なJavaScript名であり予約語でない場合、プロパティ名の引用符はオプションです。したがって、 "first-name"の周りに引用符が必要ですが、first_nameの周りにはオプションです。

ところで、JSONサイズについて心配しているのであれば、なぜそれをgzipしないのですか?

+0

ありがとう、私はそれについて考えていたが、変数が合法であるかどうか確かではなかった。 jsonはjavascriptで使用されていませんが(JavaクライアントからJEEアプリケーションに送信されます)、あなたの言うことは正しいかもしれません。 gzipに関して、私はすでにjsonを圧縮して送信していますが、とにかくそのアイデアに感謝します。 – Javi

6

[OK]をPingw33nの答えはかなり正確だと思います。そう:はい、あなたはその機能を使うことができます。引用符で囲まれていない名前をどのように動作させるべきかについての仕様がないので(JSONは名前のすべての文字を許可しています)、ヒューリスティックです。エスケープ・メカニズムが使用される場合、何が書かれているか、受け入れられるべきかについての誰かの推測です。

この場合、問題を引き起こすのはおそらく ' - '文字です。これはJavascriptの名前の合法的な部分ではありません。これはJacksonが使用する近似です。

可能な解決策の1つは、ジャクソンがそのような文字をプロパティ名でエスケープすることです(現在どのように行われているか、名前文字が引用されているかは覚えていません)。簡単なテストケースを見つけ出すことができる場合は、Jackson JiraにJiraのエンハンスメントリクエストを提出して、エスケープを追加します(パーサーは通常のバックスラッシュバージョンをエスケープできます)。

+1

ああ実際には、それより簡単です:javascriptの識別子は数字で始めることができないので、それが問題の原因です。 ALLOW_UNQUOTED_FIELD_NAMESモードの場合は、これも緩和することができます。このためにJiraの機能要求が役に立ちます。 – StaxMan

関連する問題