我需要将某个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)
答案 0 :(得分:838)
您可以使用杰克逊的班级注释:
import com.fasterxml.jackson.annotation.JsonIgnoreProperties
@JsonIgnoreProperties
class { ... }
它会忽略您在POJO中未定义的每个属性。当你只是在JSON中寻找几个属性并且不想编写整个映射时非常有用。有关详情,请访问Jackson's website。如果要忽略任何未声明的属性,则应写入:
@JsonIgnoreProperties(ignoreUnknown = true)
答案 1 :(得分:397)
您可以使用
ObjectMapper objectMapper = getObjectMapper();
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
它将忽略所有未声明的属性。
答案 2 :(得分:117)
第一个答案几乎是正确的,但是需要的是改变getter方法,NOT字段 - 字段是私有的(而不是自动检测的);此外,如果两者都可见,则getters优先于字段。(有一些方法可以使私有字段可见,但是如果你想获得getter则没有多大意义)
因此,getter应该命名为getWrapper()
,或者注释为:
@JsonProperty("wrapper")
如果您更喜欢getter方法名称。
答案 3 :(得分:75)
使用Jackson 2.6.0,这对我有用:
private static final ObjectMapper objectMapper =
new ObjectMapper()
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
并设置:
@JsonIgnoreProperties(ignoreUnknown = true)
答案 4 :(得分:45)
可以通过两种方式实现:
标记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)
答案 5 :(得分:39)
这对我来说非常有用
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(
DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
@JsonIgnoreProperties(ignoreUnknown = true)
注释没有。
答案 6 :(得分:35)
这比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);
答案 7 :(得分:26)
如果您使用的是Jackson 2.0
ObjectMapper mapper = new ObjectMapper();
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
答案 8 :(得分:17)
根据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)
答案 9 :(得分:14)
使用以下代码对我有用:
ObjectMapper mapper =new ObjectMapper();
mapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
答案 10 :(得分:12)
杰克逊正在抱怨,因为它无法在你的班级Wrapper中找到一个名为“包装器”的字段。这样做是因为你的JSON对象有一个叫做“wrapper”的属性。
我认为修复方法是将您的Wrapper类的字段重命名为“wrapper”而不是“student”。
答案 11 :(得分:10)
此解决方案在读取json流时是通用的,并且只需要获取某些字段,而在域类中未正确映射的字段可以忽略:
import org.codehaus.jackson.annotate.JsonIgnoreProperties;
@JsonIgnoreProperties(ignoreUnknown = true)
详细的解决方案是使用诸如jsonschema2pojo之类的工具从json Response的Schema中自动生成所需的域类,例如Student。您可以通过任何在线json到架构转换器来完成后者。
答案 12 :(得分:10)
我已经尝试了以下方法,它适用于与杰克逊这样的JSON格式阅读。
使用已建议的解决方案:使用@JsonProperty("wrapper")
你的包装类
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
希望这有帮助
答案 13 :(得分:9)
将字段学生注释如下,因为json属性和java属性的名称不匹配
public Class Wrapper {
@JsonProperty("wrapper")
private List<Student> students;
//getters & setters here
}
答案 14 :(得分:8)
正如没有其他人提到的那样,我想...... [/ p>
问题是你的JSON中的属性被称为“包装器”,而你在Wrapper.class中的属性被称为“学生”。
所以要么......
答案 15 :(得分:5)
改变
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"}]}
答案 16 :(得分:5)
您的输入
{"wrapper":[{"id":"13","name":"Fred"}]}
表示它是一个Object,其中包含一个名为“wrapper”的字段,它是一个学生集合。所以我的推荐是,
Wrapper = mapper.readValue(jsonStr , Wrapper.class);
其中Wrapper
定义为
class Wrapper {
List<Student> wrapper;
}
答案 17 :(得分:5)
如果由于某种原因您无法将 @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;
}
}
答案 18 :(得分:4)
就我而言,唯一的一行
@JsonIgnoreProperties(ignoreUnknown = true)
也没有工作。
添加
@JsonInclude(Include.NON_EMPTY)
Jackson 2.4.0
答案 19 :(得分:4)
这对我来说很完美
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
答案 20 :(得分:4)
我通过简单地更改我的POJO类的setter和getter方法的签名来解决这个问题。我所要做的就是更改 getObject 方法以匹配映射器正在查找的内容。在我的情况下,我最初有一个 getImageUrl ,但JSON数据有 image_url ,这使得映射器关闭。我将我的setter和getter都更改为 getImage_url和setImage_url 。
希望这有帮助。
答案 21 :(得分:4)
对我有用的是公开财产。它解决了我的问题。
答案 22 :(得分:3)
新的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
注释。
答案 23 :(得分:3)
另一种可能性是application.properties中的此属性
spring.jackson.deserialization.fail-on-unknown-properties=false
,在您的应用程序中不需要任何其他代码更改。当您认为合同稳定时,可以删除此属性或将其标记为true。
答案 24 :(得分:3)
将公开设置为您的课程字段私有。
public Class Student {
public String name;
public String id;
//getters & setters for name & id here
}
答案 25 :(得分:3)
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 :(得分:2)
这个问题已经有很多答案了。我正在添加现有答案。
如果您想将 @JsonIgnoreProperties
应用于应用程序中的所有类,那么最好的方法是覆盖 Spring Boot 默认的 jackson 对象。
在您的应用程序配置文件中定义一个 bean 来创建这样的 jackson 对象映射器。
@Bean
public ObjectMapper getObjectMapper() {
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
return mapper;
}
现在,您不需要标记每个类,它会忽略所有未知属性。
谢谢。
答案 27 :(得分:2)
这可能是一个非常晚的响应,但只是将POJO更改为此应解决问题中提供的json字符串(因为,输入字符串不在你的控件中),如你所说:
if
答案 28 :(得分:1)
就我而言,它很简单:REST服务JSON对象已更新(已添加属性),但REST客户端JSON对象未更新。一旦我更新了JSON客户端对象,“无法识别的字段......”异常就消失了。
答案 29 :(得分:1)
objectMapper.readValue(responseBody, TargetClass.class)
用于将json String转换为类对象,缺少的是TargetClass
应该有公共get
ter / set
ters。 OP的问题片段中也缺少相同的内容! :)
通过lombok您的课程如下所示!
@Data
@Builder
public class TargetClass {
private String a;
}
答案 30 :(得分:1)
不知何故,经过45个帖子和10年的努力,没有人为我的案件发布正确的答案。
@Data //Lombok
public class MyClass {
private int foo;
private int bar;
@JsonIgnore
public int getFoobar() {
return foo + bar;
}
}
在我的情况下,我们有一个名为getFoobar()
的方法,但是没有foobar
属性(因为它是从其他属性计算出来的)。 @JsonIgnoreProperties
在课堂上无效。
解决方案是使用@JsonIgnore
答案 31 :(得分:1)
这可能不是OP所遇到的问题,但是如果有人以我犯的相同错误来到这里,那么这将帮助他们解决问题。当我使用来自JsonProperty批注的不同依赖项的ObjectMapper时,遇到了与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
答案 32 :(得分:0)
没有设置器/获取器的最短解决方案是将@JsonProperty
添加到类字段中:
public class Wrapper {
@JsonProperty
private List<Student> wrapper;
}
public class Student {
@JsonProperty
private String name;
@JsonProperty
private String id;
}
此外,您还称学生在json中列出了“包装器”,因此杰克逊希望有一个带有“包装器”字段的班级。
答案 33 :(得分:0)
以防万一其他人像我一样使用 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 使用的是 jackson 的旧版本。
答案 34 :(得分:0)
添加setter和getter可以解决问题,我认为真正的问题是如何解决而不是抑制/忽略错误。 我收到错误消息“ 无法识别的字段..未标记为可忽略。. ”
尽管我在类的顶部使用了以下注释,但它无法解析json对象并提供输入
@JsonIgnoreProperties(ignoreUnknown = true)
然后我意识到,在将“包装器”和“吸气剂”添加到“包装器”和“学生”中之后,我没有添加设定器和吸气器,这就像一种魅力。
答案 35 :(得分:0)
FAIL_ON_UNKNOWN_PROPERTIES 选项在默认情况下为true:
FAIL_ON_UNKNOWN_PROPERTIES (default: true)
Used to control whether encountering of unknown properties (one for which there is no setter; and there is no fallback "any setter" method defined using @JsonAnySetter annotation) should result in a JsonMappingException (when enabled), or just quietly ignored (when disabled)
答案 36 :(得分:0)
当我们生成getter和setter时,特别是以“ is”关键字开头的IDE通常会删除“ is”。例如
private boolean isActive;
public void setActive(boolean active) {
isActive = active;
}
public isActive(){
return isActive;
}
就我而言,我只是更改了吸气剂和吸气剂。
private boolean isActive;
public void setIsActive(boolean active) {
isActive = active;
}
public getIsActive(){
return isActive;
}
它能够识别该字段。
答案 37 :(得分:0)
在我的情况下,我必须添加公共获取器和设置器以将字段保留为私有。
ObjectMapper mapper = new ObjectMapper();
Application application = mapper.readValue(input, Application.class);
我使用jackson-databind 2.10.0.pr3。
答案 38 :(得分:0)
导入com.fasterxml.jackson.annotation.JsonIgnoreProperties;
@JsonIgnoreProperties
答案 39 :(得分:0)
将Wrapper类更改为
public Class Wrapper {
@JsonProperty("wrapper") // add this line
private List<Student> students;
}
这样做是将students
字段识别为json对象的wrapper
键。
另外,我个人更喜欢将Lombok Annotations用于Getters and Setters
@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;
}
同时检查this以使用Jackson对列表进行反序列化。
答案 40 :(得分:0)
在我的情况下,错误来自于以下原因
最初它工作正常,然后我重命名了一个变量,制作了 代码中的更改,它给了我这个错误。
然后我也申请了杰克逊无知的财产但是没有用。
最后根据我的方法重新定义我的getter和setter方法 我的变量的名称此错误已解决
因此,请确保重新定义吸气剂和制定者。
答案 41 :(得分:0)
您的json字符串不与映射的类内联。 更改输入字符串
String jsonStr = "{\"students\"\:[{\"id\":\"13\",\"name\":\"Fred\"}]}";
或更改您的映射类
public class Wrapper {
private List<Student> wrapper;
//getters & setters here
}
答案 42 :(得分:0)
您只需将List的字段从“学生”更改为“包装器”只是json文件,映射器就会查找它。
答案 43 :(得分:-1)
您需要验证要解析的类的所有字段,使其与原始JSONObject
中的字段相同。它帮助了我和我的情况。
@JsonIgnoreProperties(ignoreUnknown = true)
根本没有帮助。