2011-07-12 63 views
2

我使用傑克遜來處理json。如何使用Jackson JSON處理器處理無效值?

現在,我面對一個proplem。

我的POJO:

class Person{ 
    public String name; 
    public int age; 
} 

而且JSON是

{"name":"Jackson","age":""}. 

如果我寫這樣的代碼:

Person person = mapper.readValue("{\"name\":\"Jackson\",\"age\":\"\"}", Person.class); 

一個例外是拋出:

無法從字符串值「」構造int實例:不是有效的int值。

如果JSON是"{\"name\":\"Jackson\",\"age\":null}",那沒問題。

但現在,我不想修改JSON。我該怎麼辦?

+2

那些捲曲雙引號是無效的,但它會導致不同的錯誤和不可編譯的代碼。爲避免紅鯡魚,請修正您問題中的報價爲直引號。 – BalusC

+0

你想處理任何可能的輸入字符串,不是一個數字,或只是一個空字符串? –

回答

3

我建議在http://jira.codehaus.org/browse/JACKSON處記錄一個問題,要求將其視爲錯誤,或者添加允許正確處理的功能。 (DeserializationConfig.Feature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT也可以允許將空的JSON字符串反序列化爲默認的原始值,這是JSON空值在被綁定到Java原語時以其他方式處理的原因。)(更新:我爲此記錄了issue 616。如果你想實現它。)

直到傑克遜如此增強,自定義反序列化處理將有必要將JSON空字符串轉換爲默認原始值(或任何非字符串值需要)。下面是這樣一個例子,這是幸運的簡單,因爲現有的代碼反序列化到int已經處理了一個空字符串,把它變成0。

import java.io.IOException; 

import org.codehaus.jackson.JsonParser; 
import org.codehaus.jackson.JsonProcessingException; 
import org.codehaus.jackson.Version; 
import org.codehaus.jackson.map.DeserializationContext; 
import org.codehaus.jackson.map.ObjectMapper; 
import org.codehaus.jackson.map.deser.StdDeserializer; 
import org.codehaus.jackson.map.module.SimpleModule; 

public class Foo 
{ 
    public static void main(String[] args) throws Exception 
    { 
    // {"name":"Jackson","age":""} 
    String json = "{\"name\":\"Jackson\",\"age\":\"\"}"; 

    SimpleModule module = new SimpleModule("EmptyJsonStringAsInt", Version.unknownVersion()); 
    module.addDeserializer(int.class, new EmptyJsonStringAsIntDeserializer(int.class)); 

    ObjectMapper mapper = new ObjectMapper().withModule(module); 
    Person p = mapper.readValue(json, Person.class); 
    System.out.println(mapper.writeValueAsString(p)); 
    // {"name":"Jackson","age":0} 
    } 
} 

class Person 
{ 
    public String name; 
    public int age; 
} 

class EmptyJsonStringAsIntDeserializer extends StdDeserializer<Integer> 
{ 
    protected EmptyJsonStringAsIntDeserializer(Class<?> vc) 
    { 
    super(vc); 
    } 

    @Override 
    public Integer deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException 
    { 
    return super._parseIntPrimitive(jp, ctxt); 
    } 
} 

(另請注意,如果目標類型爲整數,而不是然後這個字段會被填充一個空值(這不是我想要的),爲此,我登錄issue 617,要求反序列化配置從綁定到一個JSON空值時自動設置原始默認值換句話說,當從JSON空值反序列化爲整數字段時,目標字段將被設置爲Integer.valueOf(0)而不是null。)

+0

謝謝你的回答,布魯斯。也許我沒有明確地發佈我的目的。如果目標類型是Integer而不是int,那麼該字段將填充空值。我認爲這是合理的。這就是我所說的。 – wang

+0

謝謝你的回答,布魯斯。也許我沒有明確地發佈我的目的。如果目標類型是Integer而不是int,那麼該字段將填充空值。我認爲這是合理的。這就是我想說的。例如,一個人有一個「年齡」爲null,僅僅因爲他的名字是未知的,而不是他的年齡是0.我的問題是我無法處理Integer的空字符串。我想這可能是因爲我的傑克遜版本是1.5.5。昨天,我更新到版本1.8.3。它可以處理默認情況下的空字符串。
我的英文很差,我不知道你能否理解我的想法。 – wang

+0

但我不確定我是否理解。升級到傑克遜1.8.3後,你仍然有問題嗎?如果是這樣,*完全*你在做什麼,你想要做什麼,它做的是什麼? –