2012-03-09 74 views
1

我想反序列化一些JSON中获得的布尔值。问题是这些值可能为空,真,假,“真”,假,“Y”或“N”。Jackson反序列化自定义布尔json属性

我已经创建了自己的布尔解串器

public class CustomBooleanDeserializer extends JsonDeserializer<Boolean> { 

    final protected Class<?> _valueClass = Boolean.class; 

    @Override 
    public Boolean deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, 
      JsonProcessingException { 
     return _parseBooleanPrimitive2(jp, ctxt); 
    } 

    protected final boolean _parseBooleanPrimitive2(JsonParser jp, DeserializationContext ctxt) 
      throws IOException, JsonProcessingException { 
     LogUtils.d("PARSE BOOLEAN"); 
     JsonToken t = jp.getCurrentToken(); 
     if (t == JsonToken.VALUE_TRUE) { 
      return true; 
     } 
     if (t == JsonToken.VALUE_FALSE) { 
      return false; 
     } 
     if (t == JsonToken.VALUE_NULL) { 
      return false; 
     } 
     if (t == JsonToken.VALUE_NUMBER_INT) { 
      return (jp.getIntValue() != 0); 
     } 
     if (t == JsonToken.VALUE_STRING) { 
      String text = jp.getText().trim(); 
      if ("true".equals(text)) { 
       return true; 
      } 
      if ("false".equals(text) || text.length() == 0) { 
       return Boolean.FALSE; 
      } 

      if ("N".equalsIgnoreCase(text) || text.length() == 0) { 
       return Boolean.FALSE; 
      } 

      if ("Y".equalsIgnoreCase(text)) { 
       return Boolean.TRUE; 
      } 
      throw ctxt.weirdStringException(_valueClass, "only \"true\" or \"false\" recognized"); 
     } 
     // Otherwise, no can do: 
     throw ctxt.mappingException(_valueClass); 
    } 

但是,如果我把它注册为这本解串器不会被调用:

Version version = new Version(1, 0, 0, "SNAPSHOT"); 
SimpleModule module = new SimpleModule("MyModuleName", version); 
module = module.addDeserializer(new CustomBooleanDeserializer()); 
objectMapper.registerModule(module); 

如果,另一方面,我用@JsonDeserialize(using = CustomBooleanDeserializer.class)对于布尔字段,它确实被调用并且工作得很好。唯一的问题是,如果属性为null,我得到这个异常:

org.codehaus.jackson.map.JsonMappingException:问题解串 财产“show_query_cond”(预计类型:简单类型,类 布尔];实际类型:[NULL]),提出问题:对于场 无效值(通过参考链:com.csf.model.CSTable [ “show_query_cond”])

所以,如果布尔属性为空,我的反序列化器没有机会运行。另外,我尝试使用mapper.configure(DeserializationConfig.Feature.FAIL_ON_NULL_FOR_PRIMITIVES, false);,但如果使用@JsonDeserialize注释,则仍会抛出异常。

有谁知道如何使这项工作?

回答

7

至于注册,这可能是由于Java同时具有原始的boolean和对象封装器Boolean。所以你需要使用java.lang.BooleanBoolean.TYPE来登记 - 后者是原始类型的占位符类。

空处理是不同的问题:反序列化方法不会被他们调用。但是,有方法

JsonDeserializer.getNullValue() 

应该被调用;对于原语,您必须返回'Boolean.FALSE',因为您不能将null分配给原始值(可以返回包装;它可以正确处理)。

2

在您的自定义解串器,您可以覆盖的方法getNullValue到默认值:

之前2.6

@Override 
public Boolean getNullValue() { 
    return Boolean.FALSE; 
} 

2.6+

@Override 
public Boolean getNullValue(DeserializationContext ctxt) { 
    return Boolean.FALSE; 
} 
相关问题