[英]Jackson Json Deserialisation: Unrecognized field “…” , not marked as ignorable
[英]Jackson with JSON: Unrecognized field, not marked as ignorable
我需要将某个 JSON 字符串转换为 Java object。 我正在使用 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);
}
我的实体 class 是:
public Class Student {
private String name;
private String id;
//getters & setters for name & id here
}
我的 Wrapper class 基本上是一个容器 object 来获取我的学生名单:
public Class Wrapper {
private List<Student> students;
//getters & setters here
}
我不断收到此错误,“包装器”返回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)
您可以使用 Jackson 的类级注释:
import com.fasterxml.jackson.annotation.JsonIgnoreProperties
@JsonIgnoreProperties
class { ... }
它将忽略您尚未在 POJO 中定义的每个属性。 当您只是在 JSON 中查找几个属性并且不想编写整个映射时非常有用。 杰克逊网站上的更多信息。 如果你想忽略任何未声明的属性,你应该写:
@JsonIgnoreProperties(ignoreUnknown = true)
你可以使用
ObjectMapper objectMapper = getObjectMapper();
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
它将忽略所有未声明的属性。
第一个答案几乎是正确的,但需要的是更改 getter 方法,而不是字段——字段是私有的(并且不会自动检测到); 此外,如果两者都可见,则 getter 优先于字段。(也有一些方法可以使私有字段可见,但如果您想拥有 getter,则没有多大意义)
所以 getter 应该被命名为getWrapper()
,或者注释为:
@JsonProperty("wrapper")
如果您更喜欢 getter 方法名称。
使用 Jackson 2.6.0,这对我有用:
private static final ObjectMapper objectMapper =
new ObjectMapper()
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
并设置:
@JsonIgnoreProperties(ignoreUnknown = true)
它可以通过两种方式实现:
标记 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)
这对我来说非常有效
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(
DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
@JsonIgnoreProperties(ignoreUnknown = true)
注释没有。
添加 setter 和 getter 解决了问题,我觉得实际问题是如何解决它而不是如何抑制/忽略错误。 我收到错误“无法识别的字段.. 未标记为可忽略.. ”
尽管我在类的顶部使用了以下注释,但它无法解析 json 对象并给我输入
@JsonIgnoreProperties(ignoreUnknown = true)
然后我意识到我没有添加 setter 和 getter,在将 setter 和 getter 添加到“Wrapper”和“Student”之后,它就像一个魅力。
这比 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);
如果您使用的是 Jackson 2.0
ObjectMapper mapper = new ObjectMapper();
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
根据文档,您可以忽略所选字段或所有未知字段:
// 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)
它使用以下代码对我有用:
ObjectMapper mapper =new ObjectMapper();
mapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
我已经尝试了以下方法,它适用于使用 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了解更多信息
希望这有帮助
Jackson 抱怨是因为它在您的类 Wrapper 中找不到一个名为“wrapper”的字段。 这样做是因为您的 JSON 对象有一个名为“包装器”的属性。
我认为解决方法是将 Wrapper 类的字段重命名为“wrapper”而不是“students”。
此解决方案在读取 json 流时是通用的,并且只需要获取一些字段,而域类中未正确映射的字段可以忽略:
import org.codehaus.jackson.annotate.JsonIgnoreProperties;
@JsonIgnoreProperties(ignoreUnknown = true)
一个详细的解决方案是使用诸如 jsonschema2pojo 之类的工具从 json 响应的架构中自动生成所需的域类,例如 Student。 您可以通过任何在线 json 到模式转换器来完成后者。
由于 json 属性和 java 属性的名称不匹配,因此将现场学生注释如下
public Class Wrapper {
@JsonProperty("wrapper")
private List<Student> students;
//getters & setters here
}
正如没有人提到的那样,我以为我会......
问题是您在 JSON 中的财产被称为“包装器”,而您在 Wrapper.class 中的财产被称为“学生”。
所以要么...
对我有用的是将财产公之于众。 它为我解决了这个问题。
要么改变
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"}]}
将您的类字段设置为public而非private 。
public Class Student {
public String name;
public String id;
//getters & setters for name & id here
}
就我而言,唯一的线路
@JsonIgnoreProperties(ignoreUnknown = true)
也没有用。
只需添加
@JsonInclude(Include.NON_EMPTY)
杰克逊 2.4.0
您的输入
{"wrapper":[{"id":"13","name":"Fred"}]}
表示它是一个对象,有一个名为“wrapper”的字段,它是一个学生的集合。 所以我的建议是,
Wrapper = mapper.readValue(jsonStr , Wrapper.class);
其中Wrapper
定义为
class Wrapper {
List<Student> wrapper;
}
新的 Firebase Android 引入了一些巨大的变化; 在文档副本下方:
[ https://firebase.google.com/support/guides/firebase-android] :
更新您的 Java 模型对象
与 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
您可以通过在类上添加@IgnoreExtraProperties
注释来消除此警告。 如果您希望 Firebase 数据库像在 2.x SDK 中那样运行并在存在未知属性时抛出异常,您可以在类上添加@ThrowOnExtraProperties
注释。
另一种可能性是 application.properties spring.jackson.deserialization.fail-on-unknown-properties=false
中的此spring.jackson.deserialization.fail-on-unknown-properties=false
,它不需要在您的应用程序中更改任何其他代码。 当您认为合约稳定时,您可以删除此属性或将其标记为真。
如果由于某种原因您无法将 @JsonIgnoreProperties 注释添加到您的类中,并且您位于 Web 服务器/容器(例如 Jetty)中。 您可以在自定义提供程序中创建和自定义 ObjectMapper
import javax.ws.rs.ext.ContextResolver;
import javax.ws.rs.ext.Provider;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
@Provider
public class CustomObjectMapperProvider implements ContextResolver<ObjectMapper> {
private ObjectMapper objectMapper;
@Override
public ObjectMapper getContext(final Class<?> cls) {
return getObjectMapper();
}
private synchronized ObjectMapper getObjectMapper() {
if(objectMapper == null) {
objectMapper = new ObjectMapper();
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
}
return objectMapper;
}
}
这个问题已经有很多答案了。 我正在添加现有答案。
如果您想将@JsonIgnoreProperties
应用于应用@JsonIgnoreProperties
中的所有类,那么最好的方法是覆盖 Spring Boot 默认的 jackson 对象。
在您的应用程序配置文件中定义一个 bean 来创建这样的 jackson 对象映射器。
@Bean
public ObjectMapper getObjectMapper() {
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
return mapper;
}
现在,您不需要标记每个类,它会忽略所有未知属性。
谢谢。
这对我来说非常有效
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
我通过简单地更改我的 POJO 类的 setter 和 getter 方法的签名来解决这个问题。 我所要做的就是更改getObject方法以匹配映射器正在寻找的内容。 在我的情况下,我最初有一个getImageUrl ,但 JSON 数据有image_url ,这会导致映射器关闭。 我将我的 setter 和 getter 都更改为getImage_url 和 setImage_url 。
希望这会有所帮助。
这可能与 OP 遇到的问题不同,但如果有人遇到与我相同的错误,那么这将帮助他们解决问题。 当我使用来自不同依赖项的 ObjectMapper 作为 JsonProperty 注释时,我遇到了与 OP 相同的错误。
这有效:
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.annotation.JsonProperty;
不起作用:
import org.codehaus.jackson.map.ObjectMapper; //org.codehaus.jackson:jackson-mapper-asl:1.8.8
import com.fasterxml.jackson.annotation.JsonProperty; //com.fasterxml.jackson.core:jackson-databind:2.2.3
不知何故,在 45 个帖子和 10 年后,没有人为我的案例发布正确的答案。
@Data //Lombok
public class MyClass {
private int foo;
private int bar;
@JsonIgnore
public int getFoobar() {
return foo + bar;
}
}
就我而言,我们有一个名为getFoobar()
的方法,但没有foobar
属性(因为它是从其他属性计算而来的)。 @JsonIgnoreProperties
上的@JsonIgnoreProperties
不起作用。
解决办法是用@JsonIgnore
注解该方法
POJO 应定义为
响应类
public class Response {
private List<Wrapper> wrappers;
// getter and setter
}
包装类
public class Wrapper {
private String id;
private String name;
// getters and setters
}
和映射器读取值
Response response = mapper.readValue(jsonStr , Response.class);
我需要将某个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
}
我的包装程序类基本上是一个容器对象,用于获取我的学生列表:
public Class Wrapper {
private List<Student> students;
//getters & setters here
}
我不断收到此错误,“包装器”返回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)
我需要将某个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
}
我的包装程序类基本上是一个容器对象,用于获取我的学生列表:
public Class Wrapper {
private List<Student> students;
//getters & setters here
}
我不断收到此错误,“包装器”返回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)
我需要将某个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
}
我的包装程序类基本上是一个容器对象,用于获取我的学生列表:
public Class Wrapper {
private List<Student> students;
//getters & setters here
}
我不断收到此错误,“包装器”返回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)
导入 com.fasterxml.jackson.annotation.JsonIgnoreProperties;
@JsonIgnoreProperties
当我们生成 getter 和 setter 时,特别是以 'is' 关键字开头的,IDE 通常会删除 'is'。 例如
private boolean isActive;
public void setActive(boolean active) {
isActive = active;
}
public isActive(){
return isActive;
}
就我而言,我只是更改了 getter 和 setter。
private boolean isActive;
public void setIsActive(boolean active) {
isActive = active;
}
public getIsActive(){
return isActive;
}
它能够识别该领域。
就我而言,这很简单:REST服务JSON对象已更新(添加了属性),但REST客户端JSON对象未更新。 一旦我更新了JSON客户端对象,“无法识别的字段...”异常就消失了。
在我的情况下,我必须添加公共 getter 和 setter 以将字段设为私有。
ObjectMapper mapper = new ObjectMapper();
Application application = mapper.readValue(input, Application.class);
我使用 jackson-databind 2.10.0.pr3 。
以防万一其他人像我一样使用force-rest-api ,这是我如何使用这个讨论来解决它(Kotlin):
var result = forceApi.getSObject("Account", "idhere")
result.jsonMapper.configure( DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
val account: Account = result.`as`(Account::class.java)
看起来 force-rest-api 正在使用杰克逊的旧版本。
您只需将List的字段从“ students”更改为“ wrapper”即可,只需json文件,然后映射器将对其进行查找。
您的 json 字符串未与映射类内联。 更改输入字符串
String jsonStr = "{\"students\"\:[{\"id\":\"13\",\"name\":\"Fred\"}]}";
或者更改您的映射类
public class Wrapper {
private List<Student> wrapper;
//getters & setters here
}
在我的情况下,错误是由于以下原因造成的
最初它工作正常,然后我重命名了一个变量,在代码中进行了更改,它给了我这个错误。
然后我也应用了杰克逊无知的财产,但它没有用。
最后根据我的变量名称重新定义我的 getter 和 setter 方法后,此错误已解决
所以一定要重新定义 getter 和 setter。
将 Wrapper 类更改为
public Class Wrapper {
@JsonProperty("wrapper") // add this line
private List<Student> students;
}
这样做是将students
字段识别为 json 对象的wrapper
键。
此外,我个人更喜欢使用Lombok Annotations for Getter 和 Setter 作为
@Getter
@Setter
public Class Wrapper {
@JsonProperty("wrapper") // add this line
private List<Student> students;
}
由于我没有使用 Lombok 和@JsonProperty
一起测试上述代码,我建议您将以下代码添加到 Wrapper 类以及覆盖 Lombok 的默认 getter 和 setter。
public List<Student> getWrapper(){
return students;
}
public void setWrapper(List<Student> students){
this.students = students;
}
还要检查这个以使用 Jackson 反序列化列表。
没有 setter/getter 的最短解决方案是将@JsonProperty
添加到类字段:
public class Wrapper {
@JsonProperty
private List<Student> wrapper;
}
public class Student {
@JsonProperty
private String name;
@JsonProperty
private String id;
}
此外,您在 json 中将学生列表称为“wrapper”,因此 Jackson 需要一个带有名为“wrapper”的字段的类。
根据本文档,您可以使用 Jackson2ObjectMapperBuilder 来构建您的 ObjectMapper:
@Autowired
Jackson2ObjectMapperBuilder objectBuilder;
ObjectMapper mapper = objectBuilder.build();
String json = "{\"id\": 1001}";
默认情况下,Jackson2ObjectMapperBuilder 禁用错误 unrecognizedpropertyexception。
json字段:
"blog_host_url": "some.site.com"
Kotlin 领域
var blogHostUrl: String = "https://google.com"
在我的情况下,我只需要在我的数据类中使用@JsonProperty
注释。
例子:
data class DataBlogModel(
@JsonProperty("blog_host_url") var blogHostUrl: String = "https://google.com"
)
这是文章:https://www.baeldung.com/jackson-name-of-property
ObjectMapper objectMapper = new ObjectMapper()
.configure(DeserializationFeature.ACCEPT_EMPTY_ARRAY_AS_NULL_OBJECT, true);
当我的 JSON 有效负载包含 API 无法识别的属性时,我遇到过这种情况。 解决方案是重命名/删除有问题的属性。
我遇到了类似的问题,唯一的区别是我使用的是 YAML 文件而不是 JSON 文件。 所以我在创建 ObjectMapper 时使用了 YamlFactory()。 此外,我的 Java POJO 的属性是私有的。 但是,所有这些答案中提到的解决方案都没有帮助。 我的意思是,它停止抛出错误并开始返回 Java 对象,但java 对象的属性将为空。
我刚刚做了以下事情: -
objectMapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);
并且不需要: -
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
现在,我可以将 Yaml 文件中的数据反序列化为 Java 对象。 现在所有属性都不为空。 该解决方案也适用于 JSON 方法。
下面是我试图抑制不想解析的未知道具。 分享Kotlin代码
val myResponse = jacksonObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.readValue(serverResponse, FooResponse::class.java)
Java 11 和更新版本的简单解决方案:
var mapper = new ObjectMapper()
.registerModule(new JavaTimeModule())
.disable(FAIL_ON_UNKNOWN_PROPERTIES)
.disable(WRITE_DATES_AS_TIMESTAMPS)
.enable(ACCEPT_EMPTY_ARRAY_AS_NULL_OBJECT);
忽略重要的是禁用“FAIL_ON_UNKNOWN_PROPERTIES”
您需要验证您正在解析的类的所有字段,使其与原始JSONObject
的相同。 它帮助了我,就我而言。
@JsonIgnoreProperties(ignoreUnknown = true)
根本没有帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.