当前位置: 代码迷 >> Web前端 >> jackson 的UnrecognizedPropertyException异常
  详细解决方案

jackson 的UnrecognizedPropertyException异常

热度:681   发布时间:2012-10-12 10:17:04.0
jackson 的UnrecognizedPropertyException错误

?

前段时间,使用jackson封装了json字符串转换为javabean的方法,代码如下:

public static <T> T renderJson2Object(String json, Class clazz){
       if(!StringUtil.checkObj(json)){
            return null;
        }
        try {
            mapper.configure(SerializationConfig.Feature.WRITE_DATES_AS_TIMESTAMPS, false);
            DateFormat myDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            mapper.getSerializationConfig().setDateFormat(myDateFormat);
            return (T)mapper.readValue(json, clazz);
		} catch (IOException e) {
            log.error(e);
			throw new IllegalArgumentException(e);
		}
    }

?,这个方法可以根据json字符串,转换为clazz指定的类型的对象,如:

renderJson2Object("{\"name\":\"china\",\"age\":\"5000\"}",Student.class);

Student类里有name,age的get,set方法,代码如下:

?

public class Student implements Serializable{
    private static final long serialVersionUID = 685922460589405829L;

    private String name;
    private String age;

   /*get set略*/
}

?

根据上面的json字符串可以正常转换为Student对象,

但是通常情况下,从前端传json字符串到后端,json字符串的值是不可控的或者被框架修改了json字符串,如在里面添加了其他的键值对,

如现在的json字符串为:"{\"address\":\"hunan\",\"name\":\"china\",\"age\":\"5000\"}",

Student类里根本没有address属性,这样的情况下使用renderJson2Object方法时,会抛

java.lang.IllegalArgumentException: org.codehaus.jackson.map.exc.UnrecognizedPropertyException: Unrecognized field "address" (Class util.Student), not marked as ignorable

??意思是说Student类里没有address这个属性,所以无法正常转化,同时还指明了not marked as ignorable,即没有标明可忽略的特性,先看源码这句话的理解这句话的意思

类:org.codehaus.jackson.map.deser.BeanDeserializer中的

?

@Override
    protected void handleUnknownProperty(JsonParser jp, DeserializationContext ctxt, Object beanOrClass, String propName)
        throws IOException, JsonProcessingException
    {
        ... ... ...
        // If registered as ignorable, skip
        if (_ignoreAllUnknown ||
            (_ignorableProps != null && _ignorableProps.contains(propName))) {
            jp.skipChildren();
            return;
        }
         ... ... ...
    }

?? ?源码注释说,如果注册了忽略特性,则会跳过此步骤,那到底需要怎么忽略呢?

请再看类:org.codehaus.jackson.map.deser.BeanDeserializerFactory中的

?

protected void addBeanProps(DeserializationConfig config,
            BasicBeanDescription beanDesc, BeanDeserializerBuilder builder)
        throws JsonMappingException
    {
        ... .... ...
        // Things specified as "ok to ignore"? [JACKSON-77]
        AnnotationIntrospector intr = config.getAnnotationIntrospector();
        boolean ignoreAny = false;
        {
            Boolean B = intr.findIgnoreUnknownProperties(beanDesc.getClassInfo()); 
            if (B != null) {
                ignoreAny = B.booleanValue();
                builder.setIgnoreUnknownProperties(ignoreAny);
            }
        }
     ... ... ...
}

?

?intr.findIgnoreUnknownProperties(beanDesc.getClassInfo());

会查找目标对象中,是否使用了JsonIgnoreProperties 注解,其中把注解的value值赋给了builder.setIgnoreUnknownProperties(ignoreAny);

到此Student类的正确做法为:

?

@JsonIgnoreProperties(ignoreUnknown = true) 
public class Student implements Serializable{
    private static final long serialVersionUID = 685922460589405829L;

    private String name;
    private String age;

   /*get set.....*/
}
?看红色注解,现在暂时找到在类中添加注解(感觉具体的pojo对象和jackson耦合),不知道有没有其他方法,设全局变量来控制,如果有朋友知道,请告诉我谢谢。。。

?

?

谢谢?up2pu? 兄弟的帮助,使用mapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false),

则无需在目标类中添加JsonIgnoreProperties注解

?

1 楼 up2pu 2012-05-10  
ObjectMapper mapper = new ObjectMapper().setVisibility(JsonMethod.FIELD, Visibility.ANY);
mapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
2 楼 olivechinese 2012-05-13  
up2pu 写道
ObjectMapper mapper = new ObjectMapper().setVisibility(JsonMethod.FIELD, Visibility.ANY);
mapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);



兄弟使用的是什么版本?
我用的是1.8.3,没发现有ObjectMapper().setVisibility(JsonMethod.FIELD, Visibility.ANY)这个setVisibility方法
3 楼 up2pu 2012-05-13  
我用的是1.9.4,setVisibility这个不设置也不影响,主要是下面那句
mapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
  相关解决方案