?
前段时间,使用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注解
?
mapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
mapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
兄弟使用的是什么版本?
我用的是1.8.3,没发现有ObjectMapper().setVisibility(JsonMethod.FIELD, Visibility.ANY)这个setVisibility方法
mapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);