[解決済み] カスタム json の "Unrecognized token" 例外をジャクソンで処理する
質問内容
Jackson json パーサー(v2.5.2)を使用して、真のjsonではないカスタムjsonドキュメントをパースしようとしていますが、どうすればうまくいくのかがわかりません。 私は以下のようなjsonドキュメントを持っています。
{
"test": {
"one":"oneThing",
"two": nonStandardThing(),
"three": true
}
}
これをObjectMapperでマッピングしたい。
java.util.Map
というように
nonStandardThing()
をキーにしたマップに String 値として追加されます。
two
.
これを実行すると
ObjectMapper.readValue(json, Map.class)
例外が発生します。
com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'nonStandardThing': was expecting 'null', 'true', 'false' or NaN
at [Source: { "test":{"test1":nonStandardThing(),"test2":"two"}}; line: 1, column: 35]
at com.fasterxml.jackson.core.JsonParser._constructError(JsonParser.java:1487)
at com.fasterxml.jackson.core.base.ParserMinimalBase._reportError(ParserMinimalBase.java:518)
at com.fasterxml.jackson.core.json.ReaderBasedJsonParser._reportInvalidToken(ReaderBasedJsonParser.java:2300)
at com.fasterxml.jackson.core.json.ReaderBasedJsonParser._reportInvalidToken(ReaderBasedJsonParser.java:2277)
を登録しようとしたことがあります。
DeserializationProblemHandler
と共に
ObjectMapper
が、この問題が発生したときに呼び出されることはありません。
以下は、私が試したことを示すサンプルアプリケーションです。
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.deser.DeserializationProblemHandler;
import java.io.IOException;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
public class JacksonDeserializerTest {
private Logger log = Logger.getLogger(JacksonDeserializerTest.class.getName());
public JacksonDeserializerTest() {
String validJson = "{ \"test\":{\"test1\":\"one\",\"test2\":\"two\"}}";
String invalidJson = "{ \"test\":{\"test1\":nonStandardThing(),\"test2\":\"two\"}}";
ObjectMapper mapper = new ObjectMapper();
mapper.addHandler(new DeserializationProblemHandler() {
@Override
public boolean handleUnknownProperty(DeserializationContext dc, JsonParser jp, JsonDeserializer<?> jd, Object bean, String property) throws IOException, JsonProcessingException {
System.out.println("Handling unknown property: " + property);
return false;
}
});
try {
log.log(Level.INFO, "Valid json looks like: {0}", mapper.readValue( validJson, Map.class).toString());
log.log(Level.INFO, "Invalid json looks like: {0}", mapper.readValue(invalidJson, Map.class).toString());
} catch (IOException ex) {
log.log(Level.SEVERE, "Error parsing json", ex);
}
}
public static void main(String[] args) {
JacksonDeserializerTest test = new JacksonDeserializerTest();
}
}
出力は次のようになります。
Apr 24, 2015 1:40:27 PM net.acesinc.data.json.generator.jackson.JacksonDeserializerTest <init>
INFO: Valid json looks like: {test={test1=one, test2=two}}
Apr 24, 2015 1:40:27 PM net.acesinc.data.json.generator.jackson.JacksonDeserializerTest <init>
SEVERE: Error parsing json
com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'nonStandardThing': was expecting 'null', 'true', 'false' or NaN
at [Source: { "test":{"test1":nonStandardThing(),"test2":"two"}}; line: 1, column: 35]
at com.fasterxml.jackson.core.JsonParser._constructError(JsonParser.java:1487)
at com.fasterxml.jackson.core.base.ParserMinimalBase._reportError(ParserMinimalBase.java:518)
at com.fasterxml.jackson.core.json.ReaderBasedJsonParser._reportInvalidToken(ReaderBasedJsonParser.java:2300)
at com.fasterxml.jackson.core.json.ReaderBasedJsonParser._reportInvalidToken(ReaderBasedJsonParser.java:2277)
at com.fasterxml.jackson.core.json.ReaderBasedJsonParser._matchToken(ReaderBasedJsonParser.java:2129)
なぜHandlerが呼ばれないのか、どなたかご指摘いただけないでしょうか? あるいは、このカスタムjsonドキュメントをより良くパースする方法(jacksonかどうか...)があれば、教えてください。
解決方法は?
無効な部分がプロパティでないため、ハンドラが呼ばれない(
"two"
) ではなく、値 (
nonStandardThing()
).
これを処理する明白な方法は、次のように渡すことです。
nonStandardThing()
を
String
というJSONドキュメントに書き換えます。
{
"test": {
"one":"oneThing",
"two": "nonStandardThing()",
"three": true
}
}
それが無理なら、あまりやることはない。カスタム
Jackson
Deserializer
はプロパティに対してのみ有効であり、値に対しては有効ではありません。
関連
-
[解決済み】このコンパイルユニットは名前付きモジュールに関連しているため、名前付きパッケージeclipseを宣言する必要があります。
-
[解決済み】HTTPステータス500 サーブレットクラスのインスタンス化エラー [重複]。
-
[解決済み] hibernate のプロパティが見つかりません。
-
[解決済み] StringBuilderをクリアまたは空にするにはどうすればよいですか?重複] [重複] [重複] [重複] [重複] [重複
-
[解決済み] JavaでSSLピアが正しくシャットダウンされない
-
[解決済み] Jacksonでシリアライズ(JSON) - "No serializer found "と表示される?
-
[解決済み] cURLでJSONデータをPOSTするにはどうすればよいですか?
-
[解決済み] UnixツールでJSONをパースする
-
[解決済み] Python RequestsでJSONデータをPOSTする方法とは?
-
[解決済み] Jackson JSONとHibernate JPAによる無限再帰の問題
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] if / for / while 内で "Missing return statement" が発生する。
-
[解決済み】このコンパイルユニットは名前付きモジュールに関連しているため、名前付きパッケージeclipseを宣言する必要があります。
-
[解決済み】代入の左手は必ず変数 CharAt
-
[解決済み】「error: '.class' expected」の意味と修正方法について
-
[解決済み】Mockitoでモックからチェックされた例外を投げる
-
[解決済み】文字列中の � を置換する方法
-
[解決済み] [Solved] java.lang.NoClassDefFoundError: クラスXXXを初期化できませんでした。
-
[解決済み] java.sql.SQLException を取得しました。ResultSet が終了した後の操作は許可されません。
-
[解決済み] エラー - trustAnchors パラメータは空であってはなりません。
-
[解決済み】 executeQuery()でデータ操作文が発行できない。)