jackson与JSON:无法识别的领域,没有标记为可忽略的

我需要将某个JSONstring转换为Java对象。 我正在使用Jackson进行JSON处理。 我无法控制input的JSON(我从Web服务读取)。 这是我的inputJSON:

{"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 } 

我的包装类基本上是一个容器对象来获取我的学生列表:

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

我不断收到这个错误,“包装”返回null 。 我不知道什么是缺less的。 有人可以帮忙吗?

 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) 

您可以使用Jackson的课程级注释:

 @JsonIgnoreProperties 

它会忽略你在POJO中没有定义的每个属性。 当你只是在JSON中寻找一些属性,而不想写出整个映射时非常有用。 更多信息在jackson的网站 。 如果你想忽略任何非声明属性,你应该写:

 @JsonIgnoreProperties(ignoreUnknown = true) 

您可以使用

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

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

第一个答案几乎是正确的,但是需要改变getter方法,而不是field – field是私有的(而不是自动检测的)。 而且,如果两者都可见,getters优先于字段。 (也有办法让私人领域可见,但如果你想要有getter没什么意义)

所以getter应该被命名为“getWrapper()”,或者注释为:

 @JsonProperty("wrapper") 

如果你喜欢getter方法的名字。

这完全为我工作

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

@JsonIgnoreProperties(ignoreUnknown = true)注解没有。

使用jackson2.6.0,这工作对我来说:

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

并设置:

 @JsonIgnoreProperties(ignoreUnknown = true) 

这比所有请参阅此属性更好。

 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); 

如果你正在使用jackson2.0

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

它可以实现2种方式:

  1. 标记POJO忽略未知属性

     @JsonIgnoreProperties(ignoreUnknown = true) 
  2. configurationObjectMapper序列化/反序列化POJO / json,如下所示:

     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) 

它为我工作与以下代码:

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

根据文档,您可以忽略选定的字段或所有未知的字段:

  // to prevent specified fields from being serialized or deserialized // (ie 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) 

jackson抱怨,因为它无法在你的类包装器中find一个叫做“包装器”的字段。 这是因为你的JSON对象有一个叫做“wrapper”的属性。

我认为解决的办法是将你的包装类的字段重命名为“包装”,而不是“学生”。

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

你的包装类

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

我对包装类的build议

 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

希望这可以帮助

这个解决scheme在读取jsonstream时是通用的,只需要获取一些字段,而在Domain Classes中没有正确映射的字段可以被忽略:

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

一个详细的解决scheme是使用jsonschema2pojo这样的工具自动生成所需的Domain Classes,例如json Response的Schema中的Student。 你可以通过任何在线json to schema转换器来完成后者。

正如其他人所说的,我想…

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

所以要么

  1. 在类或JSON中更正属性的名称。
  2. 根据StaxMan的评论注释你的属性variables。
  3. 注释setter(如果有的话)

由于json属性和java属性的名称不匹配,因此请注意字段的学生

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

您的input

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

表示它是一个Object,有一个名为“wrapper”的字段,这是一个学生集合。 所以我的build议是,

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

Wrapper被定义为

 class Wrapper { List<Student> wrapper; } 

就我而言,唯一的路线

@JsonIgnoreProperties(ignoreUnknown = true)

也没有工作。

只需添加

 @JsonInclude(Include.NON_EMPTY) 

jackson2.4.0

这对我来说是完美的

 objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); 

什么对我有用,是使财产公开。 它解决了我的问题。

要么改变

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

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

– – 要么 – –

将您的JSONstring更改为

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

我通过简单地改变我的setter和我的POJO类的getter方法的签名来解决这个问题。 我所要做的只是改变getObject方法来匹配映射器正在寻找的东西。 在我的情况下,我最初有一个getImageUrl ,但JSON数据有image_url抛出映射器closures。 我改变了我的setter和getters getImage_url和setImage_url

希望这可以帮助。

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); 

新的Firebase Android引入了一些巨大的变化; 在doc的副本下面:

[ https://firebase.google.com/support/guides/firebase-android%5D

更新你的Java模型对象

与2.x SDK一样,Firebase数据库将自动将通过的Java对象转换为DatabaseReference.setValue()为JSON,并使用DataSnapshot.getValue()将JSON读入Java对象。

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

要在将JSON写入Java对象时排除字段/ 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 

您可以通过在您的类上添加@IgnoreExtraProperties注释来摆脱此警告。 如果您希望Firebase数据库的行为与在2.x SDK中的行为相同,并且在存在未知属性的情况下引发exception,则可以在类中添加@ThrowOnExtraProperties注释。

这可能是一个非常晚的反应,但只是改变这个POJO应该解决问题中提供的JSONstring(因为inputstring不像你所说的那样在你的控制中):

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

你只需要将List的字段从“students”改为“wrapper”,就可以将json文件和mapper查find。

在我的情况很简单:REST服务JSON对象被更新(一个属性被添加),但是REST客户端JSON对象不是。 只要我更新了JSON客户端对象,“无法识别的字段…”exception消失了。

你的jsonstring不是与映射类内联的。 更改inputstring

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

或者改变你的映射类

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

您需要validation正在parsing的类的所有字段,使其与原始JSONObject的相同。 它帮助我和我的情况。

@JsonIgnoreProperties(ignoreUnknown = true)根本没有帮助。

我被创造了公共领域,为我工作。 在你的情况下,如下所示:

 public Class Student { public String name; public String id; 

}