首页 文章

带有JSON的Jackson:无法识别的字段,未标记为可忽略

提问于
浏览
499

我需要将某个JSON字符串转换为Java对象 . 我正在使用Jackson进行JSON处理 . 我无法控制输入JSON(我从Web服务中读取) . 这是我的输入JSON:

{"wrapper":[{"id":"13","name":"Fred"}]}

这是一个简化的用例:

private void tryReading() {
    String jsonStr = "{\"wrapper\"\:[{\"id\":\"13\",\"name\":\"Fred\"}]}";
    ObjectMapper mapper = new ObjectMapper();  
    Wrapper wrapper = null;
    try {
        wrapper = mapper.readValue(jsonStr , Wrapper.class);
    } catch (Exception e) {
        e.printStackTrace();
    }
    System.out.println("wrapper = " + wrapper);
}

我的实体类是:

public Class Student { 
    private String name;
    private String id;
    //getters & setters for name & id here
}

My Wrapper类基本上是一个容器对象,用于获取我的学生列表:

public Class Wrapper {
    private List<Student> students;
    //getters & setters here
}

我一直收到此错误,"wrapper"返回 null . 我不确定缺少什么 . 有人可以帮忙吗?

org.codehaus.jackson.map.exc.UnrecognizedPropertyException: 
    Unrecognized field "wrapper" (Class Wrapper), not marked as ignorable
 at [Source: java.io.StringReader@1198891; line: 1, column: 13] 
    (through reference chain: Wrapper["wrapper"])
 at org.codehaus.jackson.map.exc.UnrecognizedPropertyException
    .from(UnrecognizedPropertyException.java:53)

30 回答

  • 113

    在我的例子中,它很简单:REST服务JSON对象已更新(已添加属性),但REST客户端JSON对象未更新 . 一旦我更新了JSON客户端对象,“无法识别的字段......”异常就消失了 .

  • 4

    设置 public 你的 class 字段不是 private .

    public Class Student { 
        public String name;
        public String id;
        //getters & setters for name & id here
    }
    
  • 2

    对我有用的是将 property 公之于众 . 它解决了我的问题 .

  • 1

    这对我来说非常合适

    objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    
  • 4

    这对我来说非常合适

    ObjectMapper objectMapper = new ObjectMapper();
    objectMapper.configure(
        DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    

    @JsonIgnoreProperties(ignoreUnknown = true) 注释没有 .

  • 0

    这比All更好,请参考这家酒店 .

    import com.fasterxml.jackson.databind.DeserializationFeature;
    import com.fasterxml.jackson.databind.ObjectMapper;
    
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        projectVO = objectMapper.readValue(yourjsonstring, Test.class);
    
  • 36

    由于json属性和java属性的名称不匹配,因此将字段学生注释如下

    public Class Wrapper {
        @JsonProperty("wrapper")
        private List<Student> students;
        //getters & setters here
    }
    
  • 38

    第一个答案几乎是正确的,但是需要的是更改getter方法,NOT字段 - 字段是私有的(而不是自动检测);此外,如果两者都是可见的,则getters优先于字段 . (有一些方法可以使私有字段可见,但如果你想获得getter,则没有太多意义)

    因此,getter应该被命名为 getWrapper() ,或者注释为:

    @JsonProperty("wrapper")
    

    如果您更喜欢getter方法名称 .

  • 4

    您只需将List的字段从“学生”更改为“包装器”只是json文件,映射器就会查找它 .

  • 10

    就我而言,唯一的一条线

    @JsonIgnoreProperties(ignoreUnknown = true)

    也没用 .

    只需添加

    @JsonInclude(Include.NON_EMPTY)
    

    Jackson 2.4.0

  • 1

    它对我有用,代码如下:

    ObjectMapper mapper =new ObjectMapper();    
    mapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    
  • 3

    没有人提到过,以为我会......

    问题是你的JSON中的属性被称为“包装器”,你在Wrapper.class中的属性被称为“学生” .

    所以......

    • 更正类或JSON中属性的名称 .

    • 根据StaxMan的评论注释您的属性变量 .

    • 注释setter(如果有的话)

  • 8

    如果您使用的是Jackson 2.0

    ObjectMapper mapper = new ObjectMapper();
    mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
    
  • 61

    你的意见

    {"wrapper":[{"id":"13","name":"Fred"}]}
    

    表示它是一个Object,带有一个名为“wrapper”的字段,它是一个学生集合 . 所以我的推荐是,

    Wrapper = mapper.readValue(jsonStr , Wrapper.class);
    

    其中 Wrapper 定义为

    class Wrapper {
        List<Student> wrapper;
    }
    
  • 4

    谷歌把我带到了这里,我很惊讶地看到了答案......所有建议都绕过了错误(在开发后期总是回复4倍)而不是解决它,直到this gentleman因信仰而恢复!

    objectMapper.readValue(responseBody, TargetClass.class)
    

    用于将json String转换为类对象,缺少的是 TargetClass 应该有公共 get ter / set ters . 在OP的问题片段中也缺少相同的内容! :)

    通过lombok你的 class 如下工作!!

    @Data
    @Builder
    public class TargetClass {
        private String a;
    }
    
  • 33

    您的json字符串不与映射的类内联 . 更改输入字符串

    String jsonStr = "{\"students\"\:[{\"id\":\"13\",\"name\":\"Fred\"}]}";
    

    或者更改映射的类

    public class Wrapper {
        private List<Student> wrapper;
        //getters & setters here
    }
    
  • 350

    The new Firebase Android introduced some huge changes ; below the copy of the doc :

    [https://firebase.google.com/support/guides/firebase-android] :

    Update your Java model objects

    与2.x SDK一样,Firebase数据库会自动将传递给 DatabaseReference.setValue() 的Java对象转换为JSON,并可以使用 DataSnapshot.getValue() 将JSON读入Java对象 .

    在新的SDK中,当使用 DataSnapshot.getValue() 将JSON读入Java对象时,JSON中的未知属性现在默认被忽略,因此您不再需要 @JsonIgnoreExtraProperties(ignoreUnknown=true) .

    要在将Java对象写入JSON时排除字段/ getter,注释现在称为 @Exclude 而不是 @JsonIgnore .

    BEFORE
    
    @JsonIgnoreExtraProperties(ignoreUnknown=true)
    public class ChatMessage {
       public String name;
       public String message;
       @JsonIgnore
       public String ignoreThisField;
    }
    
    dataSnapshot.getValue(ChatMessage.class)
    

    AFTER
    
    public class ChatMessage {
       public String name;
       public String message;
       @Exclude
       public String ignoreThisField;
    }
    
    dataSnapshot.getValue(ChatMessage.class)
    

    如果您的JSON中有一个不在Java类中的额外属性,您将在日志文件中看到此警告:

    W/ClassMapper: No setter/field for ignoreThisProperty found on class com.firebase.migrationguide.ChatMessage
    

    您可以通过在 class 上添加 @IgnoreExtraProperties 注释来消除此警告 . 如果您希望Firebase数据库的行为与2.x SDK中的行为相同,并且如果存在未知属性则抛出异常,您可以在类上放置 @ThrowOnExtraProperties 注释 .

  • 4

    使用Jackson 2.6.0,这对我有用:

    private static final ObjectMapper objectMapper = 
        new ObjectMapper()
            .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    

    并设置:

    @JsonIgnoreProperties(ignoreUnknown = true)
    
  • 9

    我通过简单地更改我的POJO类的setter和getter方法的签名来解决这个问题 . 我所要做的就是更改 getObject 方法以匹配映射器正在寻找的方法 . 在我的情况下,我最初有一个 getImageUrl ,但JSON数据有 image_url ,它正在抛出映射器 . 我把我的二传手和吸气者改为 getImage_url and setImage_url .

    希望这可以帮助 .

  • 16

    您可以使用Jackson的类级别注释:

    import com.fasterxml.jackson.annotation.JsonIgnoreProperties
    
    @JsonIgnoreProperties
    class { ... }
    

    它将忽略您想要编写整个映射的每个属性 . 更多信息,请致电Jackson's website . 如果要忽略任何未声明的属性,则应编写:

    @JsonIgnoreProperties(ignoreUnknown = true)
    
  • 3

    改变

    public Class Wrapper {
        private List<Student> students;
        //getters & setters here
    }
    

    public Class Wrapper {
        private List<Student> wrapper;
        //getters & setters here
    }
    
      • 要么 - -

    将您的JSON字符串更改为

    {"students":[{"id":"13","name":"Fred"}]}
    
  • 771

    POJO应定义为

    响应类

    public class Response {
        private List<Wrapper> wrappers;
        // getter and setter
    }
    

    包装类

    public class Wrapper {
        private String id;
        private String name;
        // getters and setters
    }
    

    和mapper读取值

    Response response = mapper.readValue(jsonStr , Response.class);
    
  • 26

    根据doc,您可以忽略所选字段或所有未知字段:

    // to prevent specified fields from being serialized or deserialized
     // (i.e. not include in JSON output; or being set even if they were included)
     @JsonIgnoreProperties({ "internalId", "secretKey" })
    
     // To ignore any unknown properties in JSON input without exception:
     @JsonIgnoreProperties(ignoreUnknown=true)
    
  • 12

    它可以通过2种方式实现:

    • 标记POJO以忽略未知属性
    @JsonIgnoreProperties(ignoreUnknown = true)
    
    • 配置序列化/反序列化POJO / json的ObjectMapper,如下所示:
    ObjectMapper mapper =new ObjectMapper();            
    // for Jackson version 1.X        
    mapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    // for Jackson version 2.X
    mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
    
  • 14

    这可能是一个非常晚的响应,但只是将POJO更改为此应解决问题中提供的json字符串(因为,输入字符串不在您的控件中),如下所示:

    public class Wrapper {
        private List<Student> wrapper;
        //getters & setters here
    }
    
  • 0

    您可以使用

    ObjectMapper objectMapper = getObjectMapper();
    objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    

    它将忽略所有未声明的属性 .

  • 5

    Jackson 抱怨是因为它无法在你的 class Wrapper中找到一个被称为“包装器”的字段 . 这样做是因为你的JSON对象有一个叫做“wrapper”的属性 .

    我认为修复是将您的Wrapper类的字段重命名为“wrapper”而不是“students” .

  • 8

    此解决方案在读取json流时是通用的,并且只需要获取某些字段,而在域类中未正确映射的字段可以忽略:

    import org.codehaus.jackson.annotate.JsonIgnoreProperties;
    @JsonIgnoreProperties(ignoreUnknown = true)
    

    一个详细的解决方案是使用诸如jsonschema2pojo之类的工具从json Response的Schema中自动生成所需的域类,例如Student . 您可以通过任何在线json到架构转换器来执行后者 .

  • 1

    我尝试了下面的方法,它适用于与 Jackson 这样的JSON格式阅读 . 使用已建议的解决方案:使用 @JsonProperty("wrapper") 注释getter

    你的包装类

    public Class Wrapper{ 
      private List<Student> students;
      //getters & setters here 
    }
    

    我对包装类的建议

    public Class Wrapper{ 
    
      private StudentHelper students; 
    
      //getters & setters here 
      // Annotate getter
      @JsonProperty("wrapper")
      StudentHelper getStudents() {
        return students;
      }  
    } 
    
    
    public class StudentHelper {
    
      @JsonProperty("Student")
      public List<Student> students; 
    
      //CTOR, getters and setters
      //NOTE: If students is private annotate getter with the annotation @JsonProperty("Student")
    }
    

    但是,这将为您提供格式的输出:

    {"wrapper":{"student":[{"id":13,"name":Fred}]}}
    

    有关更多信息,请参阅https://github.com/FasterXML/jackson-annotations

    希望这可以帮助

  • 0

    在我的情况下错误来自以下原因

    • 最初它工作正常,然后我重命名了一个变量,在代码中进行了更改,它给了我这个错误 .

    • 然后我也申请了 Jackson 无知 property ,但它没有用 .

    • 最后根据我变量的名称重新定义了我的getter和setter方法后,这个错误得到了解决

    所以一定要重新定义getter和setter .

相关问题