2012-08-05 64 views
0

我試圖使用org.codehaus.jackson.map.deser.std.StdDeserializer來執行自定義反序列化。無法反序列化在Jackson中使用JsonParser

我的主要目標是能夠鉤入Jetty的JSON處理結構,並使用Jackson代替默認的JettyJSON。

所以現在,我正在測試,看看這是否有效。

我有一個測試,試圖讀取一個簡單的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\":\"[email protected]\", 
     \"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。

我堅信我非常接近解決方案,並且在解串器中只缺少一件事情。我只是需要一些指導來達到最終目標。

任何幫助表示讚賞!

+0

很高興你設法搞清楚了!然而,有一個問題 - 類看起來像POJO,'ObjectMapper.readValue(...)'應該能夠立即讀取它。所以我很好奇爲什麼需要自定義解串器?還是隻是爲了學習如何去做,如果需要的話? (我肯定存在) – StaxMan 2012-08-06 23:03:34

+0

@StaxMan是的,你說得對,'readValue()'方法應該馬上工作。我需要做的是能夠根據JSON字符串中某些字段的存在/不存在來返回不同的父類對象的不同類對象。這是我試圖覆蓋Jetty中默認的JSON閱讀行爲。我現在意識到這不是正確的做法。但至少我還需要更多地瞭解傑克遜! :) – cheeze 2012-08-08 10:54:39

回答

6

好吧,經過幾天的探索和發佈我的問題後的幾個小時,我已經得到了我自己的問題的答案。

這是一個正確推進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更清晰的閱讀和傑克遜的Javadoc,以確定這樣做的正確方法。

相關問題