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种方式:
-
标记POJO忽略未知属性
@JsonIgnoreProperties(ignoreUnknown = true)
-
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中的属性被称为“学生”。
所以要么
- 在类或JSON中更正属性的名称。
- 根据StaxMan的评论注释你的属性variables。
- 注释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;
}