• jackson 的UnrecognizedPropertyException错误


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

    Java代码  收藏代码
    1. public static <T> T renderJson2Object(String json, Class clazz){  
    2.        if(!StringUtil.checkObj(json)){  
    3.             return null;  
    4.         }  
    5.         try {  
    6.             mapper.configure(SerializationConfig.Feature.WRITE_DATES_AS_TIMESTAMPS, false);  
    7.             DateFormat myDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
    8.             mapper.getSerializationConfig().setDateFormat(myDateFormat);  
    9.             return (T)mapper.readValue(json, clazz);  
    10.         } catch (IOException e) {  
    11.             log.error(e);  
    12.             throw new IllegalArgumentException(e);  
    13.         }  
    14.     }  

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

    Java代码  收藏代码
    1. renderJson2Object("{"name":"china","age":"<span style="white-space: normal;">5000</span>"}",Student.class);  

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

    Java代码  收藏代码
    1. public class Student implements Serializable{  
    2.     private static final long serialVersionUID = 685922460589405829L;  
    3.   
    4.     private String name;  
    5.     private String age;  
    6.   
    7.    /*get set略*/  
    8. }  

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

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

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

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

    Java代码  收藏代码
    1. 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中的

    Java代码  收藏代码
    1. @Override  
    2.     protected void handleUnknownProperty(JsonParser jp, DeserializationContext ctxt, Object beanOrClass, String propName)  
    3.         throws IOException, JsonProcessingException  
    4.     {  
    5.         ... ... ...  
    6.         <span style="color: #ff0000;">// If registered as ignorable, skip</span>  
    7.         <span style="color: #ff0000;">if (_ignoreAllUnknown ||  
    8.             (_ignorableProps != null && _ignorableProps.contains(propName))) {  
    9.             jp.skipChildren();  
    10.             return;  
    11.         }</span>  
    12.          ... ... ...  
    13.     }  

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

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

    Java代码  收藏代码
    1. protected void addBeanProps(DeserializationConfig config,  
    2.             BasicBeanDescription beanDesc, BeanDeserializerBuilder builder)  
    3.         throws JsonMappingException  
    4.     {  
    5.         ... .... ...  
    6.         // Things specified as "ok to ignore"? [JACKSON-77]  
    7.         AnnotationIntrospector intr = config.getAnnotationIntrospector();  
    8.         boolean ignoreAny = false;  
    9.         {  
    10.             Boolean B = intr.findIgnoreUnknownProperties(beanDesc.getClassInfo());   
    11.             if (B != null) {  
    12.                 ignoreAny = B.booleanValue();  
    13.                 builder.setIgnoreUnknownProperties(ignoreAny);  
    14.             }  
    15.         }  
    16.      ... ... ...  
    17. }  

     intr.findIgnoreUnknownProperties(beanDesc.getClassInfo());

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

    到此Student类的正确做法为:

    Java代码  收藏代码
    1. <span style="color: #ff0000;">@JsonIgnoreProperties(ignoreUnknown = true) </span>  
    2. public class Student implements Serializable{  
    3.     private static final long serialVersionUID = 685922460589405829L;  
    4.   
    5.     private String name;  
    6.     private String age;  
    7.   
    8.    /*get set.....*/  
    9. }  

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

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

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

    发表评论
          <p style="text-align:right;margin-right:30px;">(快捷键 Alt+S / Ctrl+Enter) <input class="submit" id="quick_reply_button" name="commit" type="submit" value="提交"></p>
       </form>
        <script type="text/javascript">
          new HotKey("s",function() {$('quick_reply_button').click();},{altKey: true, ctrlKey: false});
          new HotKey(new Number(13),function() {$('quick_reply_button').click();},{altKey: false, ctrlKey: true});
    
          new Validation("comment_form", {immediate: false, onFormValidate: function(result, form){
            if(result) {
              new Ajax.Request('/blog/create_comment/1131059', {
                onFailure:function(response){
                  $('comments').insert({after:response.responseText})
                  form.spinner.hide();
                  Element.scrollTo($('comments'));
                },
                onSuccess:function(response){
                  Element.scrollTo($('comments'));
                  var new_comment = new Element('div', {}).update(response.responseText).firstChild;
                  var comment_id = new_comment.readAttribute('id');
    
                  $('comments').insert({after:response.responseText});
                  $('editor_body').value = "";
    
                  var css_rules = '#' + comment_id + ' pre';
                  highlightNewAddContent(css_rules);
                  processComment();
                  code_favorites_init(css_rules);
                  
                  form.spinner.hide();
                }, parameters:Form.serialize(form)
              });
            }
        }});
        </script>
        </div>
    
  • 相关阅读:
    .NET 用 Unity 依赖注入——概述注册和解析类型(1)
    .NET 服务器定位模式(Service Locator Pattern)——Common Service Locator
    用什么样的语言就有什么样的公司【转载】
    编程语言和工具比较【翻译】
    .NET 基于任务的异步模式(Task-based Asynchronous Pattern,TAP) async await
    RocketMQ【未完成】
    Dapper
    Java 控制反转和依赖注入模式【翻译】【整理】
    Java 面向切面编程(Aspect Oriented Programming,AOP)
    Groovy 与 Python 的差异【翻译】
  • 原文地址:https://www.cnblogs.com/jpfss/p/10938547.html
  • Copyright © 2020-2023  润新知