0

良い時間!

たとえば、json文字列:{id:'a', type:'b', category:'c'}があり、ビジネスロジックでは、カテゴリオブジェクトを作成するには、カテゴリ名('c')とタイプ('b')を知る必要があります。明らかに、カテゴリ用にカスタムデシリアライザー(@JsonDeserialize(using = CategoryCustomDeserializer.class))を作成する必要があり、カテゴリの名前を取得するのは簡単ですが、型の値を取得する方法がわかりません...これを試しましjsonParser.getCodec().readTree(jsonParser)たが、null

正しい方法を提案してください。

編集:これがデシリアライザーです:

  public class CategoryNameDeserializer extends JsonDeserializer<Category> {

     @Override
     public Category deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
        if (jp.getCurrentToken() != JsonToken.END_OBJECT) {
           String categoryName = jp.getText();
           String type = ?????? <------------------------ How to do it
           return Service.getInstance().getCategory(categoryName, type);
        }

        return null;
  }
}
4

1 に答える 1

0

さて、私は答えを見つけました。これは回避策ですが、機能します。このような方法でパーサーをリセットできます。

private JsonParser getResetParser(JsonParser jp) throws IOException {
    JsonFactory factory = jp.getCodec().getFactory();

    StringReader inputSource = (StringReader) jp.getInputSource();
    inputSource.reset();

    BufferedReader br = new BufferedReader(inputSource);
    String source = br.readLine();

    return factory.createJsonParser(source);
}

その後:

private String findTokenText(JsonParser jp, String fieldName) throws IOException {
    JsonParser parser = getResetParser(jp);
    while (true) {
        parser.nextToken();
        if (parser.hasCurrentToken()) {
            switch (parser.getCurrentToken()) {
                case END_ARRAY:
                case END_OBJECT:
                case NOT_AVAILABLE:
                case START_ARRAY:
                case START_OBJECT:
                case VALUE_EMBEDDED_OBJECT:
                case VALUE_FALSE:
                case VALUE_NUMBER_FLOAT:
                case VALUE_NUMBER_INT:
                case VALUE_TRUE:
                    // do nothing
                    break;
                case FIELD_NAME:
                    String currentName = parser.getCurrentName();
                    if (fieldName.equals(currentName)) {
                        parser.nextToken();
                        return parser.getText();
                    }
                    break;
            }
        } else {
            return null;
        }
    }

私が理解していないのは、メソッド内でinputSource.reset();コードを実行したにもかかわらず(デバッグモードで試しただけ)、リーダーがリセットされていないかのように「C」を返す理由です。誰かが説明できますか、なぜこれが起こるのですか?jp.getText()findTokenText

もう1つのバリエーションは、カスタマイズを避け、この投稿からの提案を使用することです。

于 2013-03-27T08:59:46.253 に答える