0

org.codehaus.jackson.map.deser.std.StdDeserializerカスタム逆シリアル化を実行するために使用しようとしています。

私の主な目標は、Jetty の JSON 処理構造にフックして、デフォルトの JettyJSON の代わりに Jackson を使用できるようにすることです。

ということで、これでうまくいくか試してみます。

単純な JSON 文字列を読み取り、Presence オブジェクトに変換しようとするテストがあります。

public void testBasicJson() throws JsonParseException,
        JsonMappingException,
        IOException {
    ObjectMapper mapper = new ObjectMapper();
    JsonObjectDeserializer jod = new JsonObjectDeserializer();
    SimpleModule module = new SimpleModule("JsonObjectDeserializer",
        new Version(1, 0, 0, null));
    module.addDeserializer(JsonObject.class, jod);
    mapper.registerModule(module);

    //formatted for easy reading
    String jsonSimple = "{
        \"userEmail\":\"user1@lab.com\",
        \"type\":\"presence\",
        \"domain\":\"lab.com\"
    }";
    JsonObject pres = mapper.readValue(jsonSimple, JsonObject.class);
    System.out.println(pres.toString());
}

プレゼンス クラスは次のとおりです。

public class Presence extends JsonObject {
    private static final long serialVersionUID    = 1L;
    protected String userEmail;
    protected String domain;
    protected String type;

    public Presence() {
    }

    //necessary GETTERs and SETTERs are created for userEmail, domain and type

    public String toString() {
        StringBuffer sb = new StringBuffer("\tuser: ");
        sb.append(userEmail);
        sb.append(" - ");
        sb.append(domain);
        return sb.toString();
    }
}

親クラスは次のとおりです。

import org.cometd.server.ServerMessageImpl;

public abstract class JsonObject extends ServerMessageImpl {
    private static final long   serialVersionUID    = 1L;
}

カスタム デシリアライザーは次のとおりです。

import org.codehaus.jackson.JsonParser;
import org.codehaus.jackson.JsonProcessingException;
import org.codehaus.jackson.JsonToken;
import org.codehaus.jackson.map.DeserializationContext;
import org.codehaus.jackson.map.deser.std.StdDeserializer;

public class JsonObjectDeserializer extends StdDeserializer<JsonObject> {
    public JsonObjectDeserializer() {
        super(JsonObject.class);
    }

    @Override
    public JsonObject deserialize(JsonParser jp, DeserializationContext ctxt)
            throws IOException, JsonProcessingException {
        //so I'm at a loss at this point
        //if (jp.nextToken() != JsonToken.START_OBJECT) {
        //    throw new IOException("Invalid");
        //}
    }
}

私が直面している問題は、デシリアライザーの部分です。JsonParser を使用してトークンを読み取ろうとしても、常に null が返されるため機能しません。

私は解決策に非常に近づいていると強く信じており、デシリアライザーに欠けているものは1つだけです。最終目標に到達するためのガイダンスが必要です。

どんな助けでも大歓迎です!

4

1 に答える 1

8

わかりましたので、何日も探索し、質問を投稿してからわずか数時間後、私は自分の質問に対する答えを得ました。

JsonParser を正しく進める問題でした。

メソッドの内容は次のとおりです。

public JsonObject deserialize(JsonParser jp, DeserializationContext ctxt)
        throws IOException, JsonProcessingException {
    if (jp.getCurrentToken() != JsonToken.START_OBJECT) {
        throw new IOException("invalid start marker");
    }
    Presence p = new Presence();
    while (jp.nextToken() != JsonToken.END_OBJECT) {
        String fieldname = jp.getCurrentName();
        jp.nextToken();  //move to next token in string
        if ("userEmail".equals(fieldname)) {
            p.setUserEmail(jp.getText());
        } else if ("domain".equals(fieldname)) {
            p.setDomain(jp.getText());
        } else if ("type".equals(fieldname)) {
            p.setType(jp.getText());
        }
    }
    jp.close();
    return p;
}

http://www.cowtowncoder.com/blog/archives/2009/01/entry_132.htmlと Jackson の Javadoc をより明確に読んで、正しい方法を判断する必要がありました。

于 2012-08-06T01:25:54.267 に答える